如何在CMake中使用不同编译选项编译源文件并生成静态库?
用CMake实现多编译标志生成静态库
没问题,我来帮你搞定这个从Make到CMake的迁移需求!针对你给出的Make规则,我会一步步拆解对应的CMake实现方式:
核心思路
CMake中不需要像Make那样手动指定目标文件的生成路径和依赖关系,它会自动处理这些细节。我们只需要:
- 定义源文件集合
- 创建静态库目标
- 给目标(或特定源文件)设置对应的编译标志和包含目录
完整示例代码
假设你已经定义了SRCDIR、FLAGS、CFLAGS等变量,下面是对应的CMake实现:
# 1. 定义你的路径和编译标志(根据实际情况修改) set(SRCDIR "src") set(FLAGS "-O2") set(CFLAGS "-std=c++17") set(DFLAGS "-DDEBUG") set(EFLAGS1 "-march=native -ffast-math") set(INCLUDES "${PROJECT_SOURCE_DIR}/include") # 2. 收集需要编译的源文件 # 方式一:自动递归收集src目录下所有cpp文件(新增文件需重新运行CMake) file(GLOB_RECURSE GEN_SOURCES "${SRCDIR}/*.cpp") # 方式二:手动列出源文件(更可靠,推荐) # set(GEN_SOURCES # "${SRCDIR}/file1.cpp" # "${SRCDIR}/file2.cpp" # "${SRCDIR}/subdir/file3.cpp" # ) # 3. 创建静态库目标 add_library(MyStaticLib STATIC ${GEN_SOURCES}) # 4. 设置通用编译选项和包含目录 # PRIVATE表示这些选项仅用于编译当前库的源文件,不会传递给依赖它的目标 target_compile_options(MyStaticLib PRIVATE ${FLAGS} ${CFLAGS} ${DFLAGS}) target_include_directories(MyStaticLib PRIVATE ${INCLUDES}) # 5. 添加特殊编译标志EFLAGS1 # 情况A:所有源文件都需要EFLAGS1(对应你的Make规则) target_compile_options(MyStaticLib PRIVATE ${EFLAGS1}) # 情况B:仅部分源文件需要EFLAGS1,替换上面的情况A代码 # set_source_files_properties( # "${SRCDIR}/specific_file1.cpp" # "${SRCDIR}/specific_file2.cpp" # PROPERTIES COMPILE_OPTIONS "${EFLAGS1}" # ) # 可选:指定静态库的输出目录(对应你的OBJDIR1) set_target_properties(MyStaticLib PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/objdir1" )
关键细节说明
target_compile_options的PRIVATE关键字:确保这些编译标志只作用于当前静态库的编译过程,不会影响其他依赖这个库的目标,和你原来的Make规则逻辑一致。- 目标文件路径:CMake默认会在build目录的子文件夹中生成目标文件(.o),如果你需要更精细的控制,可以通过
CMAKE_ARCHIVE_OUTPUT_DIRECTORY等全局变量调整,但一般不需要手动指定,CMake会自动管理。 - 源文件收集:手动列出源文件比
file(GLOB_RECURSE)更稳定,因为后者在新增文件后需要重新运行CMake才能识别。
内容的提问来源于stack exchange,提问作者Raza
相关产品推荐
相关产品推荐

