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

CMake中add_subdirectory无法找到add_custom_command生成文件的问题

CMake结合FlatBuffers生成API的子目录依赖问题

问题描述

在使用CMake结合FlatBuffers生成API时,遇到以下问题:顶层CMake目录生成API后,子目录中无法找到生成的头文件。

项目结构与操作细节:

  • 顶层CMakeLists.txt定义INTERFACE_FBS,调用flatbuffers_generate_headers生成incl接口目标,添加链接库并设置清理属性,随后通过add_subdirectory引入app子目录。
  • app子目录的CMakeLists.txt创建app可执行文件并链接incl目标。

错误现象:

  • 构建时提示找不到testapi_generated.h,但flatbuffers_generate_headers已通过add_custom_command配置生成该文件。
  • 将可执行文件构建代码移至顶层时,头文件能正常生成且构建成功;此时启用子目录也能正常构建,但执行make clean后再次构建会失败。

疑问:操作哪里有误?是否无法在子目录中使用add_custom_command生成的文件?

问题根源

核心问题是接口目标的依赖传递不完整:

  1. 子目录链接incl目标时,CMake未正确识别需要先执行顶层的自定义命令生成头文件,导致构建顺序出错。
  2. make clean后构建失败,是因为第一次顶层构建生成的头文件被缓存,子目录可复用;清理后缓存消失,CMake未触发顶层生成命令就开始编译子目录代码。

修复方案

1. 为接口目标设置公共包含目录

在顶层CMakeLists.txt中,为incl目标添加公共包含目录,确保子目录能找到生成的头文件:

target_include_directories(incl INTERFACE ${CMAKE_CURRENT_BINARY_DIR})

${CMAKE_CURRENT_BINARY_DIR}是顶层构建目录,即testapi_generated.h的生成位置。

2. 将生成的头文件关联到接口目标

使用target_sources把生成的头文件添加为incl目标的接口源文件,让CMake明确该目标依赖这些生成文件:

set(GENERATED_HEADER ${CMAKE_CURRENT_BINARY_DIR}/testapi_generated.h)
target_sources(incl INTERFACE ${GENERATED_HEADER})

这样所有链接incl的目标(比如子目录的app)会自动依赖该生成文件,触发add_custom_command执行。

3. 确认FlatBuffers生成命令的依赖追踪

检查flatbuffers_generate_headers的实现,确保它已将生成的头文件作为add_custom_command的OUTPUT并关联到incl目标。若函数未自动处理依赖传递,补充上述两步配置即可。

验证效果

修改后,子目录的app目标链接incl时,CMake会先执行顶层自定义命令生成testapi_generated.h,再编译子目录代码。执行make clean后重新构建,也能正确触发头文件生成流程,不会再出现找不到头文件的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 22:09:24