如何在add_custom_command中使用ExternalProject的目标执行自定义命令?
解决ExternalProject引入的可执行目标在add_custom_command中无法自动替换路径的问题
问题核心在于:ExternalProject_Add 创建的是外部构建流程的目标,不属于当前CMake上下文里的常规可执行目标,因此没法像 add_subdirectory 引入的目标那样,直接在 add_custom_command 的 COMMAND 里用目标名自动替换为可执行文件路径。以下是具体解决方法:
方法一:显式获取外部生成器的可执行文件路径
通过 ExternalProject_Get_Property 获取外部项目的构建目录,手动拼接出可执行文件的完整路径,再在 add_custom_command 中使用:
# 引入外部代码生成器项目 ExternalProject_Add( code_generator SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/code_generator BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/code_generator_build # 传递主项目的工具链参数,保证跨工具链编译一致性 CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} BUILD_ALWAYS ON ) # 获取外部项目的构建目录 ExternalProject_Get_Property(code_generator BINARY_DIR) # 拼接可执行文件路径,适配Windows平台的.exe后缀 set(CODE_GENERATOR_EXEC ${BINARY_DIR}/code_generator) if(WIN32) set(CODE_GENERATOR_EXEC ${CODE_GENERATOR_EXEC}.exe) endif() # 使用生成器生成代码 add_custom_command( OUTPUT generated_code.h COMMAND ${CODE_GENERATOR_EXEC} --output generated_code.h # 明确依赖外部项目,确保生成器先被构建完成 DEPENDS code_generator COMMENT "Generating header file with external code generator" ) # 将生成的代码纳入主项目构建 add_library(generated_code STATIC generated_code.h) add_dependencies(generated_code code_generator)
方法二:创建导入式可执行目标(更优雅的复用方式)
把外部生成的可执行文件包装成CMake导入目标,后续使用时更接近常规 add_executable 创建的目标:
ExternalProject_Add( code_generator SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/code_generator BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/code_generator_build CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} BUILD_ALWAYS ON ) # 获取外部可执行文件路径 ExternalProject_Get_Property(code_generator BINARY_DIR) set(CODE_GENERATOR_EXEC ${BINARY_DIR}/code_generator) if(WIN32) set(CODE_GENERATOR_EXEC ${CODE_GENERATOR_EXEC}.exe) endif() # 创建导入式可执行目标 add_executable(code_generator_exe IMPORTED GLOBAL) set_target_properties(code_generator_exe PROPERTIES IMPORTED_LOCATION ${CODE_GENERATOR_EXEC} ) # 关联依赖,确保导入目标可用前外部项目已构建完成 add_dependencies(code_generator_exe code_generator) # 使用导入目标生成代码,用$<TARGET_FILE:>自动解析可执行文件路径 add_custom_command( OUTPUT generated_code.h COMMAND $<TARGET_FILE:code_generator_exe> --output generated_code.h DEPENDS code_generator_exe COMMENT "Generating header file with imported generator target" ) add_library(generated_code STATIC generated_code.h) add_dependencies(generated_code code_generator_exe)
关键注意事项
- 必须给
ExternalProject_Add传递主项目的工具链参数(如CMAKE_CXX_COMPILER),确保外部项目用和主项目一致的工具链编译,满足跨工具链需求。 - 所有使用外部生成器的目标,都必须添加对外部项目目标(
code_generator)或导入目标的依赖,避免构建顺序错误。
内容的提问来源于stack exchange,提问作者mat
相关产品推荐
相关产品推荐

