调用add_custom_command时获取CMake目标包含属性的最优方案
优化CMake自定义目标调用LLVM TableGen的包含路径传递方案
方案1:基于生成器表达式的自定义函数优化
如果你的CMake版本在3.20及以上,可以利用$<MAP>和$<JOIN>生成器表达式,直接将目标的包含目录转换为-I<dir>格式,完全避免硬编码:
function(add_tablegen_for_target target output_file td_file) # 将每个包含目录前添加-I,再用空格连接 set(INCLUDE_FLAGS "$<JOIN:$<MAP:LIST,$<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>,-I{}>,\" \">") add_custom_command( OUTPUT ${output_file} COMMAND llvm-tblgen ${INCLUDE_FLAGS} -o ${output_file} ${td_file} DEPENDS ${td_file} ${target} COMMENT "Generating code from ${td_file}" ) add_custom_target(${target}_tblgen ALL DEPENDS ${output_file}) endfunction() # 使用方式:传递目标、输出文件、TableGen源文件 add_tablegen_for_target(MyCoreLib ${CMAKE_CURRENT_BINARY_DIR}/GenCode.inc ${CMAKE_CURRENT_SOURCE_DIR}/MyDefs.td)
方案2:复用LLVM官方封装的TableGen工具
LLVM本身提供了开箱即用的LLVMTableGen模块,已经处理了包含路径、依赖管理等细节,直接复用更省心:
# 导入LLVM的TableGen模块 include(LLVMTableGen) # 直接生成TableGen目标,自动处理包含路径 llvm_tablegen(MyTblGenOutput OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/GenCode.inc DEPENDS MyCoreLib INCLUDE_DIRS $<TARGET_PROPERTY:MyCoreLib,INCLUDE_DIRECTORIES> ) # 关联到自定义目标(可选,根据你的构建流程调整) add_custom_target(MyTblGen ALL DEPENDS MyTblGenOutput)
关键注意事项
- 确保自定义命令依赖于目标(
DEPENDS ${target}),这样当目标的包含目录更新时,TableGen会自动重新运行。 - 若使用旧版本CMake(低于3.20),可以用
get_target_property在函数内部先获取包含目录,再循环拼接-I前缀:function(add_tablegen_for_target target output_file td_file) get_target_property(INCLUDE_DIRS ${target} INCLUDE_DIRECTORIES) set(INCLUDE_FLAGS "") foreach(dir IN LISTS INCLUDE_DIRS) list(APPEND INCLUDE_FLAGS "-I${dir}") endforeach() add_custom_command( OUTPUT ${output_file} COMMAND llvm-tblgen ${INCLUDE_FLAGS} -o ${output_file} ${td_file} DEPENDS ${td_file} ${target} COMMENT "Generating code from ${td_file}" ) add_custom_target(${target}_tblgen ALL DEPENDS ${output_file}) endfunction()
内容的提问来源于stack exchange,提问作者Leonardo
相关产品推荐
相关产品推荐

