如何使用CMake正确构建现有结构的C++项目(适配3.21+新版本)
CMake 3.21+ 项目配置方案
配置文件数量说明
你当前的项目一共需要3个CMakeLists.txt即可,分别存放在:
- 项目根目录(ProjectRootDir)
- libraries 目录
- program_subdir 目录
如果追求精简也可以缩减为2个,但3个的结构更清晰,和Java模块化的管理思路对齐,后续新增库、新增可执行目标的维护成本更低。
各配置文件内容
1. 项目根目录CMakeLists.txt
cmake_minimum_required(VERSION 3.21 FATAL_ERROR) # 替换为实际项目名 project(MyCppProject LANGUAGES CXX) # 全局指定C++标准,也可单独给每个目标配置,全局设置更省心 set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to use") set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "Is the specified C++ standard required") set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Disable non-standard C++ extensions") # 引入子目录,注意libraries要放在program_subdir前面,因为后者依赖前者 add_subdirectory(libraries) add_subdirectory(program_subdir)
2. libraries目录CMakeLists.txt
这里我们使用CMake的OBJECT类型库,这种库不会生成独立的.a/.so/.lib/.dll文件,只会把源码编译为临时目标文件,后续直接嵌入到可执行文件中,完全符合你不需要编译为外部独立库的需求。
# 配置Library1 add_library(Library1 OBJECT Library1/Library1.cpp Library1/Library1.h ) # 给依赖Library1的目标自动添加头文件搜索路径,匹配#include <Library1.h>的引用写法 target_include_directories(Library1 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Library1 ) # 配置Library2,逻辑和Library1完全一致 add_library(Library2 OBJECT Library2/Library2.cpp Library2/Library2.h ) target_include_directories(Library2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/Library2 )
3. program_subdir目录CMakeLists.txt
add_executable(MyProgram program.cpp ) # 直接链接两个OBJECT库即可,CMake会自动继承头文件搜索路径、编译选项,也会把两个库的目标文件嵌入到可执行文件中 target_link_libraries(MyProgram PRIVATE Library1 Library2 )
编译使用方法
进入项目根目录执行以下命令即可完成编译:
# 生成构建配置 cmake -S . -B build # 执行编译 cmake --build build
编译完成后的可执行文件会生成在build/program_subdir目录下。
可选优化建议
如果后续项目规模扩大、新增第三方依赖,当前#include <Library1.h>的写法可能出现头文件重名冲突,更推荐参考Java的包命名逻辑调整目录结构:把Library1的头文件放到libraries/Library1/include/Library1/Library1.h路径下,引用时改为#include <Library1/Library1.h>,只需要同步把Library1的target_include_directories配置改为${CMAKE_CURRENT_SOURCE_DIR}/Library1/include即可,能完全避免头文件命名冲突。
内容的提问来源于stack exchange,提问作者jotadepicas
相关产品推荐
相关产品推荐

