CMake报错‘TARGET未在当前目录创建’的原因与解决办法
CMake跨目录添加POST_BUILD自定义命令报错的原因与解决办法
报错原因
CMake 的 add_custom_command(TARGET ... POST_BUILD) 有严格的目录上下文限制:它要求目标必须在当前正在解析的CMakeLists.txt所在目录,或者该目录通过add_subdirectory包含的子目录中定义。这是因为CMake处理构建脚本时是按目录上下文维护目标信息的,跨目录直接引用未在当前上下文创建的目标,会触发一致性检查,从而抛出TARGET 'foo.elf' was not created in this directory的错误。
解决办法
1. 封装通用逻辑为函数,在目标定义处调用
这是最推荐的方式,既保留代码复用性,又符合CMake的上下文规则:
- 在通用CMake目录的文件中,把ELF处理逻辑封装成函数:
function(add_post_build_elf_processing TARGET_NAME) add_custom_command( TARGET ${TARGET_NAME} POST_BUILD COMMAND blah blah blah COMMAND blah blah blah COMMAND blah blah blah WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} VERBATIM ) endfunction()
- 在定义
foo.elf的CMakeLists.txt中,先引入通用文件,再调用函数绑定处理逻辑:
# 引入通用CMake文件,替换成实际路径 include(${CMAKE_SOURCE_DIR}/path/to/common/elf_processing.cmake) # 定义目标 add_executable(foo.elf your_source_files.c) # 绑定POST_BUILD处理命令 add_post_build_elf_processing(foo.elf)
2. 用自定义目标关联依赖
如果不想修改目标定义目录的CMake脚本,可以在通用目录中创建一个自定义目标,让它依赖foo.elf,并在这个自定义目标中执行处理命令:
add_custom_target(process_all_elfs ALL COMMAND blah blah blah COMMAND blah blah blah COMMAND blah blah blah WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} DEPENDS foo.elf VERBATIM )
注意:这种方式需要确保foo.elf目标已经被CMake识别(即定义foo.elf的CMakeLists.txt已经通过add_subdirectory或include被处理过)。
3. 遍历全局目标批量处理(多目标场景)
如果有多个ELF目标都需要相同处理,可以通过CMake的全局属性遍历目标:
# 在所有目标定义完成后调用 get_property(all_targets GLOBAL PROPERTY BUILDSYSTEM_TARGETS) foreach(target IN LISTS all_targets) get_target_property(target_type ${target} TYPE) # 筛选出EXECUTABLE类型的ELF目标(根据实际情况调整判断条件) if(target_type STREQUAL "EXECUTABLE" AND target MATCHES "\\.elf$") add_custom_command( TARGET ${target} POST_BUILD COMMAND blah blah blah COMMAND blah blah blah COMMAND blah blah blah WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} VERBATIM ) endif() endforeach()
这种方式适合批量处理,但需要确保在所有目标定义完成后执行这段代码。
内容的提问来源于stack exchange,提问作者user3696153
相关产品推荐
相关产品推荐

