You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CMake创建自定义目标,配置shell脚本并依赖C++可执行文件

解决方案

问题根源

你原来直接调用的configure_file是CMake配置阶段(即执行cmake ..生成构建文件的阶段)就会执行的命令,不会等到构建阶段(执行make的阶段)运行,所以无法依赖构建产物myExe,也无法做到仅执行make foo-target时才触发配置。

调整步骤

1. 调整模板文件(可选,推荐)

将tool/myscript.sh重命名为tool/myscript.sh.in,区分模板文件和生成后的可执行脚本,避免路径冲突。如果不想重命名,后续步骤中指定输入路径为源码目录下的原始文件即可。

2. 修改tool/CMakeLists.txt内容

直接删除原来的配置阶段configure_file调用,改用构建阶段的自定义命令实现按需生成:

set(CONFIG_INI_ABS_PATH "${PROJECT_SOURCE_DIR}/foo/config.ini")

add_custom_command(
  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/myscript.sh"
  # 依赖模板文件和myExe目标:模板修改或者myExe重新编译时,自动重新生成脚本
  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/myscript.sh.in" myExe
  # 用sed替换模板中的占位符,生成最终脚本
  COMMAND sed 
    -e "s|@CONFIG_INI_ABS_PATH@|${CONFIG_INI_ABS_PATH}|g"
    -e "s|@EXE_ABS_PATH@|$<TARGET_FILE:myExe>|g"
    "${CMAKE_CURRENT_SOURCE_DIR}/myscript.sh.in" 
    > "${CMAKE_CURRENT_BINARY_DIR}/myscript.sh"
  # 给生成的脚本加执行权限
  COMMAND chmod +x "${CMAKE_CURRENT_BINARY_DIR}/myscript.sh"
  VERBATIM
)

add_custom_target(foo-target
  DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/myscript.sh"
)

如果需要跨Windows平台兼容,不用sed的话,可以新增一个tool/configure_script.cmake辅助脚本:

configure_file(${INPUT_FILE} ${OUTPUT_FILE} @ONLY USE_SOURCE_PERMISSIONS)

再把add_custom_command替换为以下写法即可:

add_custom_command(
  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/myscript.sh"
  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/myscript.sh.in" myExe "${CMAKE_CURRENT_SOURCE_DIR}/configure_script.cmake"
  COMMAND ${CMAKE_COMMAND}
    -D CONFIG_INI_ABS_PATH=${CONFIG_INI_ABS_PATH}
    -D EXE_ABS_PATH=$<TARGET_FILE:myExe>
    -D INPUT_FILE="${CMAKE_CURRENT_SOURCE_DIR}/myscript.sh.in"
    -D OUTPUT_FILE="${CMAKE_CURRENT_BINARY_DIR}/myscript.sh"
    -P "${CMAKE_CURRENT_SOURCE_DIR}/configure_script.cmake"
  VERBATIM
)

3. 调整子目录加载顺序

确保你项目根目录的CMakeLists.txt中,add_subdirectory(cpp)的顺序在add_subdirectory(tool)之前,否则CMake会找不到myExe目标。

效果说明

  • 直接执行make等默认构建命令时,不会生成myscript.sh,也不会触发相关依赖编译
  • 执行make foo-target时,会先自动编译更新myExe,再生成替换好路径的myscript.sh到构建目录的tool/路径下
  • 后续如果修改了模板文件或者重新编译了myExe,再次执行make foo-target会自动重新生成脚本

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:12:03