CMake 构建实例

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 包等),告诉我,我立刻给出完整可运行的例子!

文章已创建 3511

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部