Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cmake add_custom_命令--通过重建更新依赖项列表_Cmake_Add Custom Command - Fatal编程技术网

Cmake add_custom_命令--通过重建更新依赖项列表

Cmake add_custom_命令--通过重建更新依赖项列表,cmake,add-custom-command,Cmake,Add Custom Command,请参阅上次状态更新 初始条件 生成一个C++源的代码生成器,其中一个输入文件作为参数 输入文件可能包括其他输入文件 已经解决了获取输出文件列表、解析输入codegen文件以获取codegen输入完整列表的任务。 也就是说,首次为add_custom_命令提供了一组正确的依赖项: add_custom_command(OUTPUT ${generatedSources} COMMAND ${codegenCommand} ARGS ${codegenArgs

请参阅上次状态更新

初始条件

  • 生成一个C++源的代码生成器,其中一个输入文件作为参数
  • 输入文件可能包括其他输入文件
  • 已经解决了获取输出文件列表、解析输入codegen文件以获取codegen输入完整列表的任务。 也就是说,首次为add_custom_命令提供了一组正确的依赖项:

    add_custom_command(OUTPUT ${generatedSources}
                       COMMAND ${codegenCommand} ARGS ${codegenArgs}
                       DEPENDS ${codegenInputFiles})
    
问题场景

  • 当前系统运行良好,直到有人修改其中一个codegen输入文件以包含新的输入文件或删除现有文件的包含。 在这种情况下,需要更新提供的codegen输入文件列表,以将_custom_命令添加为依赖项,但我不知道如何更新
缺少什么

  • 能够通过项目重建更新“添加\自定义\命令依赖项”
有没有办法在不进行完整项目重建的情况下解决这个问题

更新-备选方案(更好?)问题描述

我在cmake邮件列表中发现了类似的未回答问题,为了更清晰,请将其张贴在此处:

我试图让一个代码生成工具在依赖项方面与C源文件的行为“相同”。我的意思是,假设你有一个C文件“a.C”。因为它可以包含文件,所以每当
a.c
的内容改变时,它的依赖关系也可能改变。使用-MMD重新扫描依赖项。我想用一些方法来模拟我的代码生成器。 首先,我尝试了add_custom_命令,它接受一个固定的依赖列表,该列表在定义自定义命令时确定。具体来说,我的意思是:

但这仅在生成构建系统时捕获依赖项。每次运行自定义命令时,依赖项列表可能需要更改,因为更改可能意味着新的依赖项。我应该如何执行此操作

更新2-可能的解决方案

我认为是事实 -网络上有关于cmake支持dynamic的声音 依赖关系,这是许多应用程序顺利集成所必需的 非平凡代码生成工具 -目前还并没有现成的最佳解决方案,因为我们实际上需要的是钩子,以便将自定义DSL的支持添加到隐式应用程序中

从cmake手册:

隐式依赖选项请求扫描输入文件的隐式依赖项。给定的语言指定应使用其相应依赖项扫描程序的编程语言。目前只支持C和CXX语言扫描仪。必须为隐式依赖列表中的每个文件指定语言从扫描中发现的依赖项将在生成时添加到自定义命令的依赖项中

以下解决方案(希望)符合以下标准:

  • 避免在重建时进行不必要的依赖项扫描
  • 避免在重新生成时运行不必要的代码生成器
  • 允许向客户提供cmake功能以注册其模型和 从该代码生成代码/创建库,而不强加任何项目结构要求(即,没有负责代码生成的子项目,使用特定于项目的策略跨项目层次结构分布模型)
解决思路

不可能注册自定义语言扫描程序,但可以重用现有的语言扫描程序。其思想是,自定义模型文件的依赖项/层次结构反映为“C”头文件的层次结构。注册模型文件和C文件时添加每个层次结构节点,包括匹配模型文件。若模型文件包括get CHANGE,C文件包括get CHANGE。因此,每个codegen调用将只依赖于一个生成的反映已传递模型的C头。每个反射的文件都将依赖于模型文件,并会涉及到模型文件的更改


总而言之:可能我的措辞在这一点上还不太清楚,但是关于其他人的需求和帮助我调查这个问题的社区,我会在项目准备就绪后(1-3天内)发布通用解决方案(+链接到github或新的cmake wiki页面),而不发布我的项目细节.

您能否演示如何初始化变量
codegenInputFiles
?您可能可以在那里使用
文件(GLOB…
文件(GLOB\u RECURSE…
命令。 看

但是请注意,您必须重新运行cmake才能生成命令。你在和git合作吗?然后,您可以在每次拉取时强制执行cmake调用(这样,如果有人修改了
codegenInputFiles
,您的自动生成的文件将被更新)


澄清问题后,您应该能够通过使用而不是
DEPENDS
找到解决方法。限制:

  • 它只能在输入文件为C/C++时工作(检查语法,因为必须为每个指定的文件指定语言)
  • 您可能需要检查您的cmake版本是否支持该命令,即使它看起来已经存在一段时间了
  • 它只支持Makefile生成器,听起来很糟糕

  • 编辑

    经过一番反复,我终于明白了你的问题所在。 我提出以下解决方案:在单独的cmake子项目中分离文件生成。当您构建主项目时(通过调用make),您将触发子项目的cmake和make。调用cmake对于更新依赖项是必要的,同时调用make来实际构建自动生成的源

    这里我展示了一个项目和子项目的示例,其中项目调用cmake并生成子项目

    结构:

    .
    ├── CMakeLists.txt
    ├── a.cpp
    ├── build
    └── subProject
        └── CMakeLists.txt
    
    文件内容

    /CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    
    add_custom_target(subProjectTarget ALL)
    add_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)
    
    include_directories(${CMAKE_BINARY_DIR}/subProject)
    add_executable (dummy a.cpp)
    add_dependencies (dummy subProjectTarget)
    
    /a.cpp(注意
    cmake_minimum_required(VERSION 2.8)
    
    add_custom_target(subProjectTarget ALL)
    add_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)
    
    include_directories(${CMAKE_BINARY_DIR}/subProject)
    add_executable (dummy a.cpp)
    add_dependencies (dummy subProjectTarget)
    
    #include "b.h"
    
    int main () {
    }
    
    cmake_minimum_required(VERSION 2.8)
    file(WRITE ${CMAKE_BINARY_DIR}/b.h "//I am a dummy file\n")
    
    me@here:~/example/build$ cmake ..
    -- The C compiler identification is GNU 4.8.2
    -- The CXX compiler identification is GNU 4.8.2
    -- Check for working C compiler: /usr/bin/cc
    -- Check for working C compiler: /usr/bin/cc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/me/example/build
    
    me@here:~/example/build$ make
    Scanning dependencies of target subProjectTarget
    -- The C compiler identification is GNU 4.8.2
    -- The CXX compiler identification is GNU 4.8.2
    -- Check for working C compiler: /usr/bin/cc
    -- Check for working C compiler: /usr/bin/cc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/me/example/build/subProject
    [  0%] Built target subProjectTarget
    Scanning dependencies of target dummy
    [100%] Building CXX object CMakeFiles/dummy.dir/a.cpp.o
    Linking CXX executable dummy
    [100%] Built target dummy
    
    me@here:~/example/build$ make
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/me/example/build/subProject
    [  0%] Built target subProjectTarget
    Scanning dependencies of target dummy
    [100%] Building CXX object CMakeFiles/dummy.dir/a.cpp.o
    Linking CXX executable dummy
    [100%] Built target dummy