CMake中如何让两个add_custom_command按顺序依次执行并保证生效
问题根源
- 第二个
add_custom_command的依赖路径错误:你声明的依赖是${SRC_FLATBUFFERS_DIR}/${GEN_FBS_FILE},但第一个自定义命令生成的GEN_FBS_FILE实际输出路径是${DST_FLATBUFFERS_DIR}/${GEN_FBS_FILE},CMake找不到对应依赖,无法建立两个命令的依赖链。 - 当你把最终引用的产物换成
DST_FBS_FILE时,CMake无法识别这个文件的有效生成规则(依赖路径错误导致规则不生效),所以连第一个命令都不会触发。
修复方案
修正第二个自定义命令的依赖路径,同时把最终引用的产物替换为重命名后的文件即可:
list(LENGTH SRC_FBS_FILES LEN) math(EXPR FBS_LIST_NUM "${LEN} - 1") foreach (LIST_ITEM RANGE ${FBS_LIST_NUM}) list(GET SRC_FBS_FILES ${LIST_ITEM} SRC_FBS_FILE) list(GET DST_FBS_FILES ${LIST_ITEM} DST_FBS_FILE) list(GET GEN_FBS_FILES ${LIST_ITEM} GEN_FBS_FILE) get_filename_component(DST_FBS_FILE_DIR ${DST_FBS_FILE} DIRECTORY) add_custom_command (OUTPUT "${DST_FLATBUFFERS_DIR}/${GEN_FBS_FILE}" COMMENT "Generating flatbuffers header ${GEN_FBS_FILE} from ${SRC_FBS_FILE}" COMMAND ${_FLATC} --cpp "${SRC_FLATBUFFERS_DIR}/${SRC_FBS_FILE}" WORKING_DIRECTORY "${DST_FLATBUFFERS_DIR}" DEPENDS "${SRC_FLATBUFFERS_DIR}/${SRC_FBS_FILE}" ) add_custom_command( OUTPUT "${DST_FLATBUFFERS_DIR}/${DST_FBS_FILE}" COMMENT "Renaming '${GEN_FBS_FILE}' to '${DST_FBS_FILE}'" COMMAND ${CMAKE_COMMAND} -E copy "${DST_FLATBUFFERS_DIR}/${GEN_FBS_FILE}" "${DST_FLATBUFFERS_DIR}/${DST_FBS_FILE}" # 修正依赖路径,指向第一个命令生成的GEN文件 DEPENDS "${DST_FLATBUFFERS_DIR}/${GEN_FBS_FILE}" ) # 最终引用重命名后的产物 set(FLATBUFFERS_H_FILES ${FLATBUFFERS_H_FILES} "${DST_FLATBUFFERS_DIR}/${DST_FBS_FILE}") endforeach() # 可选:显式定义自定义目标,保证依赖链一定会被触发 add_custom_target(generate_flatbuffers ALL DEPENDS ${FLATBUFFERS_H_FILES})
核心逻辑说明
CMake的add_custom_command会通过OUTPUT和DEPENDS的路径匹配自动建立执行顺序:只要第二个命令的DEPENDS路径和第一个命令的OUTPUT路径完全一致,CMake就会保证先执行生成GEN文件的命令,再执行重命名的命令。你只需要保证最终编译目标引用的是最后一步的OUTPUT产物(也就是DST_FBS_FILE),整个依赖链就会被触发,两个命令都会按顺序执行。
内容的提问来源于stack exchange,提问作者Anton Issaikin
相关产品推荐
相关产品推荐

