
CMake 是现代 C/C++ 项目中最主流的构建工具之一。它不仅可以帮助开发者组织源代码、管理依赖、构建库文件,还能提升项目的模块化程度和可维护性。
本文将以一个简单模块 color 为例,介绍如何使用 CMake:
我们采用模块化、分离构建思路组织项目结构:
your_project/
├── CMakeLists.txt # 顶层 CMake 构建脚本
├── include/ # 公共头文件目录
│ └── color.h
├── src/ # 源文件目录
│ ├── main.c # 主程序入口
│ └── color/ # color 模块目录
│ ├── color.c
│ └── CMakeLists.txt # color 模块构建配置
└── build/ # 构建输出目录(自动生成)目录/文件 | 说明 |
|---|---|
include/ | 放置对外公开头文件,便于跨模块引用 |
src/color/ | 独立模块,具备独立构建能力 |
build/ | 构建输出与源代码分离,保持干净 |
CMakeLists.txt | 配置统一构建规则与链接流程 |
CMakeLists.txtcmake_minimum_required(VERSION 3.10)
project(ColorApp C)
set(CMAKE_C_STANDARD 99)
# 设置库和可执行文件的输出路径
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# 添加头文件搜索路径
include_directories(include)
# 添加 color 模块
add_subdirectory(src/color)
# 添加主程序
add_executable(${PROJECT_NAME} src/main.c)
# 链接 color 模块库
target_link_libraries(${PROJECT_NAME} color)src/color/CMakeLists.txt ✅【推荐写法】# 可选但推荐:模块自身声明(便于大型项目调试)
project(ColorModule C)
# 构建静态库 color
add_library(color STATIC color.c)
# 添加头文件目录(可供外部 target 使用)
target_include_directories(color PUBLIC ${CMAKE_SOURCE_DIR}/include)project()?cmake_minimum_required(),它只应在顶层写一次。include/color.h#ifndef COLOR_H
#define COLOR_H
void set_color(void);
#endifsrc/color/color.c#include <stdio.h>
#include "color.h"
void set_color(void) {
printf("Set color called!\n");
}src/main.c#include "color.h"
int main() {
set_color();
return 0;
}在项目根目录下执行以下命令进行构建:
mkdir build
cd build
cmake ..
make
./bin/ColorAppSet color called!借助 CMAKE_*_OUTPUT_DIRECTORY 变量,我们可以控制构建产物的输出位置:
变量名 | 描述 | 示例输出路径 |
|---|---|---|
CMAKE_ARCHIVE_OUTPUT_DIRECTORY | 静态库 .a 输出路径 | build/lib/libcolor.a |
CMAKE_LIBRARY_OUTPUT_DIRECTORY | 动态库 .so 输出路径 | build/lib/libcolor.so |
CMAKE_RUNTIME_OUTPUT_DIRECTORY | 可执行文件输出路径 | build/bin/ColorApp |
if(WIN32)
message(STATUS "Compiling on Windows")
add_definitions(-DPLATFORM_WINDOWS)
elseif(APPLE)
message(STATUS "Compiling on macOS")
add_definitions(-DPLATFORM_MACOS)
elseif(UNIX)
message(STATUS "Compiling on Linux")
add_definitions(-DPLATFORM_LINUX)
endif()平台 | 构建命令 |
|---|---|
Linux/macOS | cmake .. && make |
Windows MinGW | cmake -G "MinGW Makefiles" .. && mingw32-make |
Windows Visual Studio | cmake -G "Visual Studio 17 2022" .. (生成 .sln) |
你可以基于此结构轻松扩展为多模块项目:
art, password:
src/art/,放入 art.c, art.h;CMakeLists.txt 和库配置;include/;
CMakeLists.txt 中添加子目录与链接即可;
tests/ 目录引入单元测试框架如 CTest、Google Test。
关键点 | 内容 |
|---|---|
使用 add_library() 构建静态/动态库 | 模块化构建 |
使用 target_link_libraries() 连接模块 | 清晰解耦 |
使用输出变量设置生成目录 | 可控构建产物结构 |
模块 + 主程序分离 | 易于维护与扩展 |
支持跨平台平台适配 | Windows/macOS/Linux 构建 |
your_project/
├── CMakeLists.txt # 顶层构建配置
├── include/
│ └── color.h # 模块头文件
├── src/
│ ├── main.c # 主程序
│ └── color/
│ ├── color.c # 模块实现
│ └── CMakeLists.txt # 模块构建配置
├── build/
│ ├── lib/
│ │ └── libcolor.a # 静态库输出
│ └── bin/
│ └── ColorApp # 主程序输出# src/color/CMakeLists.txt
project(ColorModule C)
add_library(color STATIC color.c)
target_include_directories(color PUBLIC ${CMAKE_SOURCE_DIR}/include)CMake 有了更深入的理解和认识。