You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编写CMakeLists.txt构建源码及示例?单根文件实现多示例构建问询

当然可以!完全不用给每个示例目录单独写CMakeLists.txt,只需要在ProjectRepoDir根目录下写一个顶层CMake配置就能搞定所有构建需求。我给你详细拆解怎么写,以及每个部分的作用:

顶层CMakeLists.txt编写方案

1. 基础配置

首先开头要做一些CMake的基础设置,指定最低版本、项目名称和C++标准,确保编译环境兼容:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 设置C++标准,根据你的代码需求调整版本,比如C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

2. 编译核心库

你的src目录里有liba.cppmodule1.cpp,咱们把它们编译成一个静态库(也可以改成动态库,看你需求),这样主程序和所有示例都能直接链接复用,不用重复编译这些代码:

# 收集核心库的源码文件
set(CORE_SOURCES
    src/liba.cpp
    src/module1.cpp
)

# 编译成静态库
add_library(core_lib STATIC ${CORE_SOURCES})

# 指定头文件目录,让编译时能找到include下的头文件
target_include_directories(core_lib PUBLIC ${PROJECT_SOURCE_DIR}/include)

这里用PUBLIC是为了让链接这个库的目标(主程序、示例)自动继承include目录,不用重复设置。

3. 编译主程序

接下来处理src目录下的main.cpp,生成主程序可执行文件,链接咱们刚才编译的核心库:

add_executable(main_program src/main.cpp)
target_link_libraries(main_program PRIVATE core_lib)

4. 批量编译所有示例

这部分是重点,不用每个示例目录写CMake,咱们通过CMake的目录遍历功能自动处理samples下的所有子目录:

# 遍历samples下的所有子目录
file(GLOB SAMPLE_DIRS RELATIVE ${PROJECT_SOURCE_DIR}/samples ${PROJECT_SOURCE_DIR}/samples/*)

foreach(DIR ${SAMPLE_DIRS})
    # 把目录名里的'-'换成'_',避免CMake识别问题
    string(REPLACE "-" "_" EXEC_NAME ${DIR})
    # 收集当前示例目录下的所有源码文件
    aux_source_directory(${PROJECT_SOURCE_DIR}/samples/${DIR} SAMPLE_SOURCES)
    # 生成对应可执行文件
    add_executable(${EXEC_NAME} ${SAMPLE_SOURCES})
    # 链接核心库
    target_link_libraries(${EXEC_NAME} PRIVATE core_lib)
endforeach()

如果你的示例目录里只有main.cpp,也可以直接指定这个文件代替aux_source_directory,效果是一样的。

5. 可选:统一可执行文件输出目录

默认情况下,可执行文件会生成在build目录对应的子目录里(比如build/src、build/samples/example1-dir),如果想把所有可执行文件都放到build/bin目录下,方便查找运行,可以加这几行:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin)
完整的CMakeLists.txt

把上面的部分整合起来,就是完整的顶层配置文件,直接放在ProjectRepoDir根目录下即可:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 统一输出目录(可选)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin)

# 编译核心库
set(CORE_SOURCES
    src/liba.cpp
    src/module1.cpp
)
add_library(core_lib STATIC ${CORE_SOURCES})
target_include_directories(core_lib PUBLIC ${PROJECT_SOURCE_DIR}/include)

# 编译主程序
add_executable(main_program src/main.cpp)
target_link_libraries(main_program PRIVATE core_lib)

# 批量编译示例
file(GLOB SAMPLE_DIRS RELATIVE ${PROJECT_SOURCE_DIR}/samples ${PROJECT_SOURCE_DIR}/samples/*)
foreach(DIR ${SAMPLE_DIRS})
    string(REPLACE "-" "_" EXEC_NAME ${DIR})
    aux_source_directory(${PROJECT_SOURCE_DIR}/samples/${DIR} SAMPLE_SOURCES)
    add_executable(${EXEC_NAME} ${SAMPLE_SOURCES})
    target_link_libraries(${EXEC_NAME} PRIVATE core_lib)
endforeach()
构建验证

直接执行你说的命令就行:

mkdir build && cd build && cmake .. && make

构建完成后,所有可执行文件都会在build/bin目录下(如果加了统一输出目录),你可以直接运行./bin/main_program./bin/example1_dir等测试。

内容的提问来源于stack exchange,提问作者ywiyogo

火山引擎 最新活动