如何在CMake中以目标编译时的方式预处理公开头文件?
让CMake自定义命令与目标编译参数一致预处理头文件
要实现和目标编译时完全一致的预处理方式,核心是复用目标的编译配置参数,CMake的生成器表达式(Generator Expressions)可以直接获取目标的编译定义、包含目录、编译选项,再配合编译器的预处理专用参数即可实现。
具体实现步骤
- 定义公开头文件列表
先把需要预处理的公开头文件整理成列表:
set(PUBLIC_HEADERS include/my_lib.h include/my_utils.h )
- 为每个头文件生成匹配目标参数的自定义预处理命令
通过遍历头文件,复用目标的编译配置,同时根据编译器类型添加对应的预处理参数(MSVC用/P,GCC/Clang用-E):
# 存储所有预处理输出文件 set(PREPROCESSED_OUTPUTS "") foreach(HEADER ${PUBLIC_HEADERS}) get_filename_component(HEADER_BASENAME ${HEADER} NAME) # 定义输出文件路径,放在构建目录下避免污染源码 set(OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/preprocessed_${HEADER_BASENAME}.i") list(APPEND PREPROCESSED_OUTPUTS ${OUTPUT_FILE}) # 根据编译器生成包含目录参数 set(INCLUDE_FLAGS "") if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(INCLUDE_FLAGS "$<JOIN:$<TARGET_PROPERTY:my_target,INCLUDE_DIRECTORIES>,\" /I\">") string(PREPEND INCLUDE_FLAGS "/I") else() set(INCLUDE_FLAGS "$<JOIN:$<TARGET_PROPERTY:my_target,INCLUDE_DIRECTORIES>,\" -I\">") string(PREPEND INCLUDE_FLAGS "-I") endif() add_custom_command( OUTPUT ${OUTPUT_FILE} COMMAND $<CXX_COMPILER> # 复用目标的编译宏定义 $<TARGET_PROPERTY:my_target,COMPILE_DEFINITIONS> # 复用目标的包含目录 ${INCLUDE_FLAGS} # 复用目标的编译选项 $<TARGET_PROPERTY:my_target,COMPILE_OPTIONS> # 编译器专属预处理参数 $<$<CXX_COMPILER_ID:MSVC>:/P> $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-E> # 输入输出文件指定(MSVC用/Fo指定输出路径,GCC/Clang用-o) $<$<CXX_COMPILER_ID:MSVC>:/Fo${OUTPUT_FILE} ${HEADER}> $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-o ${OUTPUT_FILE} ${HEADER}> MAIN_DEPENDENCY ${HEADER} COMMENT "Preprocessing ${HEADER_BASENAME}..." ) endforeach()
注意:把代码中的
my_target替换为你实际的目标名称(比如库或可执行文件目标)。
- 创建自定义目标触发预处理
把所有预处理输出文件绑定到一个自定义目标,方便通过make preprocess_public_headers或cmake --build . --target preprocess_public_headers触发:
add_custom_target(preprocess_public_headers DEPENDS ${PREPROCESSED_OUTPUTS} COMMENT "Preprocessing all public headers..." )
关键说明
- 生成器表达式
$<TARGET_PROPERTY:...>会自动适配目标的配置(比如Debug/Release的不同宏定义、编译选项),保证预处理和目标编译的环境完全一致 - 针对MSVC的
/P参数,默认会在源文件同目录生成.i文件,这里用/Fo参数指定输出到构建目录,避免污染源码 - 如果目标包含平台或配置特定的编译参数,生成器表达式会自动处理,无需手动区分
内容的提问来源于stack exchange,提问作者Nurullah Cirit
相关产品推荐
相关产品推荐

