gpt4 book ai didi

cmake - add_custom_command —通过重建更新依赖项列表

转载 作者:行者123 更新时间:2023-12-02 03:27:04 27 4
gpt4 key购买 nike

查看最新状态更新

初始条件

  • 代码生成器以一组输入文件作为参数
  • 生成一组c++源代码
  • 输入文件可能包括其他输入文件
  • 已经解决了获取输出文件列表,解析输入codegen文件以获得完整的codegen输入列表的任务。
    即首次为add_custom_command提供了正确的依赖关系集:
    add_custom_command(OUTPUT ${generatedSources}
    COMMAND ${codegenCommand} ARGS ${codegenArgs}
    DEPENDS ${codegenInputFiles})

  • 问题场景
  • 当前系统运行良好,直到有人修改了一个codegen输入文件之一以包括新的输入文件或删除了现有的输入文件。
    在这种情况下,需要更新作为依赖项提供给add_custom_command的代码生成输入文件的列表,但是我不知道
  • 如何

    缺少什么
  • 在项目重建中更新add_custom_command依赖项的能力重建了

  • 有没有解决方案,而无需进行完整的项目重建?

    更新-替代(更好?)问题描述

    我在cmake邮件列表中发现了类似的未回答问题,请在此处将其张贴出来,以提高清晰度:
    http://article.gmane.org/gmane.comp.programming.tools.cmake.user/52279

    我试图获得一种代码生成工具,使其在依赖性方面的行为与C源文件“相同”。我的意思是,假设您有一个C文件“a.c”。因为它可以#include文件,所以每次 a.c的内容更改时,其依存关系也可能更改。使用-MMD重新扫描依赖项。我想以某种方式为我的代码生成器进行仿真。
    首先,我尝试了add_custom_command,它具有固定的DEPENDS列表,该列表在定义定制命令时确定。具体来说,我的意思是这样的:
    function(add_generated_library)
    figure_out_dependencies(deps ${ARGN})
    add_custom_command(... DEPENDS ${deps})
    endfunction()

    但这仅捕获了生成系统生成时的依赖性。每次运行自定义命令时,DEPENDS列表可能都需要更改,因为更改可能意味着新的依赖关系。我该怎么做?

    更新2-可能的解决方案

    以下我认为是事实
    -网络上有关于cmake支持动态的声音
    依赖关系,这是许多产品顺利集成所必需的
    非平凡的代码生成工具
    -目前没有可用的最佳解决方案,因为我们实际需要的是向IMPLICIT_DEPENDS添加自定义DSL支持的挂钩

    从cmake手册:

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

    以下解决方案(希望)遵循以下条件:
  • 避免对重建
  • 进行不必要的依赖项扫描
  • 避免不必要的代码生成器在重建
  • 上运行
  • 允许向客户端提供cmake函数以注册其模型并
  • 生成代码/从该代码创建库,而无需施加任何项目结构要求(即,没有负责代码生成的子项目,使用特定于项目的策略在项目层次结构中分布模型)

    解决思路

    无法注册自定义语言扫描仪,但是可以重用现有的扫描仪。这个想法是自定义模型文件的依赖关系/层次结构反映为“C”头文件的层次结构。模型文件的注册中添加了每个层次结点,而C文件包含匹配模型文件包含。如果模型文件包含更改,则C文件包含更改。因此,每次代码生成调用将仅依赖于一个生成的C头,该头反映了传递的模型。每个反映的文件都将依赖于模型文件,并会涉及模型文件的更改。

    总结起来:也许,我的措辞目前还不清楚,但是考虑到其他人的需求和社区帮助我调查了这个问题,我将发布通用解决方案(+链接到github或新的cmake Wiki页面),我的专案准备就绪后(1-3天内)。

    最佳答案

    您可以显示如何初始化变量codegenInputFiles吗?您可能在那里可以使用file(GLOB ... )file(GLOB_RECURSE ... )命令。
    参见documentation

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

    解决问题之后,您应该可以通过使用 IMPLICIT_DEPENDS 而不是DEPENDS找到解决方法。局限性:

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


  • 编辑

    经过几次迭代,我终于明白了您的问题所在。
    我提出以下解决方案:在单独的cmake子项目中分离文件生成。当您构建主项目(通过调用make)时,将触发cmake和make子项目。调用cmake对于保持更新的依赖关系是必要的,而调用make则实际构建自动生成的源。

    在这里,我展示了一个项目和一个子项目的示例,该项目调用cmake并为该子项目进行make。

    结构体:
    .
    ├── 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 (注意b.h还不存在)
    #include "b.h"

    int main () {
    }

    ./SubProject/CMakeLists.txt
    cmake_minimum_required(VERSION 2.8)
    file(WRITE ${CMAKE_BINARY_DIR}/b.h "//I am a dummy file\n")

    构建项目(使用默认的 make)
    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

    请注意,第二次cmake调用在子项目上。

    在下一次通话中,一切都变得更快:
    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

    (尽管这里每次都会写入文件b.h,导致重新编译a.cpp)

    通过使用cmake命令生成输出目录(而不是mkdir)并级联为主项目选择的生成器(在此我假设一切都在使用make),可以大大改善此存根。

    让我知道是否需要进一步说明。

    关于cmake - add_custom_command —通过重建更新依赖项列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29784506/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com