CMake 构建实例:从简单到复杂实战项目
下面通过4个逐步升级的实际项目实例,展示 CMake 的完整构建流程、目录结构和 CMakeLists.txt 编写。所有实例都遵循现代 CMake 最佳实践(CMake 3.15+,target-centric 写法,源码外构建)。
实例1:单文件 Hello World(最简单入门)
目录结构
hello/
├── CMakeLists.txt
└── main.cpp
main.cpp
#include <iostream>
int main() {
std::cout << "Hello, CMake World!" << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(HelloWorld LANGUAGES CXX)
add_executable(${PROJECT_NAME} main.cpp)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
构建命令
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
./HelloWorld
实例2:多文件 + 头文件目录(典型小型项目)
目录结构
math_app/
├── CMakeLists.txt
├── main.cpp
├── include/
│ └── math_utils.h
└── src/
└── math_utils.cpp
math_utils.h
#pragma once
double add(double a, double b);
double multiply(double a, double b);
math_utils.cpp
#include "math_utils.h"
double add(double a, double b) { return a + b; }
double multiply(double a, double b) { return a * b; }
main.cpp
#include <iostream>
#include "math_utils.h"
int main() {
std::cout << "3 + 5 = " << add(3, 5) << std::endl;
std::cout << "4 * 7 = " << multiply(4, 7) << std::endl;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MathApp LANGUAGES CXX)
add_executable(${PROJECT_NAME}
main.cpp
src/math_utils.cpp
)
target_include_directories(${PROJECT_NAME} PRIVATE include)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
构建同上
实例3:分离库 + 多目录(中型项目推荐结构)
目录结构
calculator/
├── CMakeLists.txt # 根目录
├── app/
│ ├── CMakeLists.txt
│ └── main.cpp
├── lib/
│ ├── CMakeLists.txt
│ ├── include/calculator/
│ │ └── core.h
│ └── src/
│ └── core.cpp
└── tests/ # (可选,后续加测试)
lib/include/calculator/core.h
#pragma once
namespace calc {
double add(double a, double b);
double subtract(double a, double b);
}
lib/src/core.cpp
#include "calculator/core.h"
namespace calc {
double add(double a, double b) { return a + b; }
double subtract(double a, double b) { return a - b; }
}
app/main.cpp
#include <iostream>
#include "calculator/core.h"
int main() {
std::cout << "10 - 4 = " << calc::subtract(10, 4) << std::endl;
return 0;
}
lib/CMakeLists.txt(库)
add_library(calc_core STATIC
src/core.cpp
)
target_include_directories(calc_core PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_compile_features(calc_core PUBLIC cxx_std_17)
app/CMakeLists.txt(可执行)
add_executable(calculator_app main.cpp)
target_link_libraries(calculator_app PRIVATE calc_core)
根 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(Calculator LANGUAGES CXX)
add_subdirectory(lib)
add_subdirectory(app)
构建命令
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
./app/calculator_app
实例4:完整项目(带静态/动态库选项 + 安装规则 + 测试)
扩展实例3,添加:
- 可选生成共享库
- 安装规则(
make install) - 简单单元测试
根 CMakeLists.txt(增强版)
cmake_minimum_required(VERSION 3.15)
project(Calculator LANGUAGES CXX)
# 选项:是否构建共享库(默认静态)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
add_subdirectory(lib)
add_subdirectory(app)
add_subdirectory(tests) # 可选
# 安装规则
install(TARGETS calculator_app
DESTINATION bin
)
install(TARGETS calc_core
DESTINATION lib
)
install(DIRECTORY lib/include/
DESTINATION include
)
tests/CMakeLists.txt(使用 CMake 自带测试)
find_package(GTest QUIET)
if(GTest_FOUND)
add_executable(calc_test test_core.cpp)
target_link_libraries(calc_test PRIVATE calc_core GTest::gtest_main)
add_test(NAME CalcTest COMMAND calc_test)
else()
message(WARNING "Google Test not found, skipping tests")
endif()
构建 + 安装 + 测试
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON
cmake --build .
ctest . # 运行测试(如果有 GTest)
sudo cmake --install . --prefix /usr/local # 安装到系统
总结:推荐项目模板(直接复制使用)
myproject/
├── CMakeLists.txt
├── cmake/ # 可选:自定义模块
├── app/
│ ├── CMakeLists.txt
│ └── main.cpp
├── lib/
│ ├── CMakeLists.txt
│ ├── include/myproject/
│ └── src/
├── tests/
│ └── CMakeLists.txt
└── third_party/ # 第三方库(如 vcpkg/conan 管理)
这些实例覆盖了从单文件到中大型项目的全部常见需求。你可以直接复制修改使用。
如果你想看特定场景的实例(如集成 Boost/Qt/OpenCV、交叉编译 Android/iOS、使用 vcpkg/Conan 包管理、生成 deb/rpm 包等),告诉我,我立刻给出完整可运行的例子!