Kon*_*tin 5 cmake cmake-custom-command
查看上次状态更新
初始条件
已经解决了获取输出文件列表、解析输入代码生成文件以获取代码生成输入的完整列表的任务。即 add_custom_command 第一次提供了正确的依赖项集:
add_custom_command(OUTPUT ${generatedSources}
                   COMMAND ${codegenCommand} ARGS ${codegenArgs}
                   DEPENDS ${codegenInputFiles})
Run Code Online (Sandbox Code Playgroud)问题场景
缺什么
有没有办法在不重建整个项目的情况下解决这个问题?
更新 - 替代(更好?)问题描述
我在 cmake 邮件列表上发现了类似的未回答的问题,为了更清楚起见,将其发布在这里: http: //article.gmane.org/gmane.comp.programming.tools.cmake.user/52279
我正在尝试让代码生成工具在依赖关系方面与 C 源文件“相同”。我的意思是,假设您有一个 C 文件“ac”。因为它可以#include文件,所以每次内容发生a.c变化,它的依赖关系也可能发生变化。使用 -MMD 重新扫描依赖项。我想要某种方法来为我的代码生成器模拟这一点。首先,我尝试了 add_custom_command,它采用固定的 DEPENDS 列表,在定义自定义命令时确定。具体来说,我的意思是这样的:
function(add_generated_library)
   figure_out_dependencies(deps ${ARGN})
   add_custom_command(... DEPENDS ${deps})
endfunction()
Run Code Online (Sandbox Code Playgroud)
但这仅捕获构建系统生成时的依赖关系。每次运行自定义命令时,DEPENDS 列表可能需要更改,因为更改可能意味着新的依赖项。我应该如何执行此操作?
更新 2 - 可能的解决方案
以下是我认为的事实 - 网络上有关于 cmake 支持动态依赖关系的声音,这是平滑集成许多重要的代码生成工具所必需的 - 没有现成的最佳解决方案可用,正如我们所见实际上需要的是钩子来添加对自定义 DSL 的支持到 IMPLICIT_DEPENDS
来自cmake手册:
IMPLICIT_DEPENDS 选项请求扫描输入文件的隐式依赖关系。给定的语言指定应使用其相应依赖关系扫描器的编程语言。目前仅支持 C 和 CXX 语言扫描程序。必须为 IMPLICIT_DEPENDS 列表中的每个文件指定语言。通过扫描发现的依赖关系会在构建时添加到自定义命令的依赖关系中。
下面的解决方案(希望)遵守以下标准:
解决思路
无法注册自定义语言扫描仪,但可以重用现有语言扫描仪。这个想法是自定义模型文件的依赖关系/层次结构反映为“C”头文件的层次结构。每个层次结构节点都在注册模型文件时添加,并且 C 文件包含匹配的模型文件包含。如果模型文件包含更改,则 C 文件包含更改。因此,每个 codegen 调用将仅依赖于一个生成的反映传递模型的 C 标头。每个反映的文件都将依赖于模型文件并涉及模型文件的更改。
总结一下:可能,我的措辞目前还不是那么清楚,但考虑到其他人的需求和社区帮助我调查这个问题,我将发布通用解决方案(+链接到 github 或新的 cmake wiki 页面),而无需我的项目细节一旦准备好(1-3 天内)。
你能展示一下如何初始化变量codegenInputFiles吗?您可以在那里使用file(GLOB ... )orfile(GLOB_RECURSE ... )命令。\n请参阅文档。
但请注意,您必须重新运行 cmake 才能生成命令。你在使用 git 吗?然后你可以有一个钩子,每次拉取时都会强制执行 cmake 调用(这样,如果有人修改了,codegenInputFiles你的自动生成的文件就会更新)。
澄清问题后,您应该能够通过使用IMPLICIT_DEPENDS而不是找到解决方法DEPENDS。限制:
编辑
\n\n经过一些迭代,我终于明白了你的问题是什么。\n我提出以下解决方案:将文件生成分离在单独的 cmake 子项目中。当您构建主项目(通过调用 make)时,您将为子项目触发 cmake 和 make。调用 cmake 对于保持更新依赖项是必要的,同时调用 make 来实际构建自动生成的源代码。
\n\n这里我展示了一个项目和子项目的示例,项目为子项目调用 cmake 和 make。
\n\n结构:
\n\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 a.cpp\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 subProject\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\nRun Code Online (Sandbox Code Playgroud)\n\n文件内容
\n\n./CMakeLists.txt:
\n\ncmake_minimum_required(VERSION 2.8)\n\nadd_custom_target(subProjectTarget ALL)\nadd_custom_command(TARGET subProjectTarget PRE_BUILD COMMAND mkdir -p ${CMAKE_BINARY_DIR}/subProject && cd ${CMAKE_BINARY_DIR}/subProject && ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR}/subProject && make)\n\ninclude_directories(${CMAKE_BINARY_DIR}/subProject)\nadd_executable (dummy a.cpp)\nadd_dependencies (dummy subProjectTarget)\nRun Code Online (Sandbox Code Playgroud)\n\n./a.cpp(注意 bh 还不存在)
\n\n#include "b.h"\n\nint main () {\n}\nRun Code Online (Sandbox Code Playgroud)\n\n./子项目/CMakeLists.txt
\n\ncmake_minimum_required(VERSION 2.8)\nfile(WRITE ${CMAKE_BINARY_DIR}/b.h "//I am a dummy file\\n")\nRun Code Online (Sandbox Code Playgroud)\n\n构建项目(使用默认make)
me@here:~/example/build$ cmake ..\n-- The C compiler identification is GNU 4.8.2\n-- The CXX compiler identification is GNU 4.8.2\n-- Check for working C compiler: /usr/bin/cc\n-- Check for working C compiler: /usr/bin/cc -- works\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Check for working CXX compiler: /usr/bin/c++\n-- Check for working CXX compiler: /usr/bin/c++ -- works\n-- Detecting CXX compiler ABI info\n-- Detecting CXX compiler ABI info - done\n-- Configuring done\n-- Generating done\n-- Build files have been written to: /home/me/example/build\n\nme@here:~/example/build$ make\nScanning dependencies of target subProjectTarget\n-- The C compiler identification is GNU 4.8.2\n-- The CXX compiler identification is GNU 4.8.2\n-- Check for working C compiler: /usr/bin/cc\n-- Check for working C compiler: /usr/bin/cc -- works\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Check for working CXX compiler: /usr/bin/c++\n-- Check for working CXX compiler: /usr/bin/c++ -- works\n-- Detecting CXX compiler ABI info\n-- Detecting CXX compiler ABI info - done\n-- Configuring done\n-- Generating done\n-- Build files have been written to: /home/me/example/build/subProject\n[  0%] Built target subProjectTarget\nScanning dependencies of target dummy\n[100%] Building CXX object CMakeFiles/dummy.dir/a.cpp.o\nLinking CXX executable dummy\n[100%] Built target dummy\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,第二次 cmake 调用是在子项目上。
\n\n在下一次调用时,一切都会变得更快:
\n\nme@here:~/example/build$ make\n-- Configuring done\n-- Generating done\n-- Build files have been written to: /home/me/example/build/subProject\n[  0%] Built target subProjectTarget\nScanning dependencies of target dummy\n[100%] Building CXX object CMakeFiles/dummy.dir/a.cpp.o\nLinking CXX executable dummy\n[100%] Built target dummy\nRun Code Online (Sandbox Code Playgroud)\n\n(虽然这里每次都会写入bh文件导致a.cpp重新编译)
\n\n通过使用 cmake 命令生成输出目录(而不是 mkdir)并级联为主项目选择的生成器(这里我假设一切都使用 make),可以大大改进此存根
\n\n如果您需要任何进一步说明,请告诉我。
\n|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2360 次  |  
        
|   最近记录:  |