【问题标题】:Dynamic dependency within custom source files自定义源文件中的动态依赖关系
【发布时间】:2020-07-03 10:05:56
【问题描述】:

我有非 C/C++ 的自定义源文件。这些文件被编译成 C 源文件,然后这些 C 文件像往常一样被 cmake 编译。

但是,我的自定义文件可能具有在开发过程中会发生变化的依赖项。

例如让我们说我有文件source1.langsource2.langsource3.lang...

source1.lang

... some code

source2.lang

import source1;
... some code

我将这些文件编译为

./langc source1.lang
./langc source2.lang
...

我得到source1.csource2.c ...

现在,如您所见,source2.lang 依赖于source1.lang。我可以通过预处理这些自定义文件随时找到这些依赖项。然后在source1.lang 上生成source2.lang 的显式依赖,以便在修改source1.lang 时重新编译。

现在,我有一个这样的自定义命令

# This is populated automatically.
set(SOURCE2_DEPENDS source2.lang source1.lang) 

add_custom_command(
        DEPENDS ${SOURCE2_DEPENDS }
        COMMAND ./langc source2.lang
        OUTPUT source2.c 
        COMMENT "Compiling source2.c"
     )

问题是依赖关系可能在开发过程中发生变化。即SOURCE1_DEPENDS配置后可以更改。比如我可以修改source2.lang来导入source3.lang

source2.lang

import source1;
import source3;
... some code

我现在可以看到 source2.lang 已修改。所以我预处理它以找到新的依赖项。但是如何让 cmake 知道依赖项发生了变化呢?

到目前为止,我能看到的唯一方法是 Makefile 生成器修改生成的 build.make 文件以手动添加和删除这些依赖项。

但是,我怎样才能以通用的方式告诉 cmake 这些是新的依赖项? 基本上,当您将新的#include 添加到 C 源文件时,cmake 通常会这样做。这样其他生成器也可以使用。

【问题讨论】:

    标签: cmake


    【解决方案1】:

    我认为以下内容目前仅适用于 Ninja 生成器。我认为它也适用于 makefile 生成器,但我没有检查。

    add_custom_commandDEPFILE 选项。你必须从你的命令生成一个 makefile-ish 风格的 depfile。例如:

    add_custom_command(
            DEPENDS ${SOURCE2_DEPENDS}
            DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/source2.d
            COMMAND ./langc 
                   --depfile ${CMAKE_CURRENT_BINARY_DIR}/source2.d
                   --depfile-relative ${CMAKE_BINARY_DIR}
                    source2.lang
            OUTPUT source2.c 
            COMMENT "Compiling source2.c"
         )
    

    生成的 depfile 应该看起来像由 gcc 使用标准 -MT/-MD 选项生成的 makefile 依赖文件。请注意,目标路径必须相对于${CMAKE_BINARY_DIR}。所以langc程序应该在${CMAKE_CURRENT_BINARY_DIR}/source2.d中生成如下文件:

    buildir/subdir/source2.c: /absolute/path/to/be/safe/source2.lang /absolute/path/to/be/safe/source1.lang /etc..
    # ^^ must be relative to CMAKE_BINARY_DIR
    

    Cmake 将depfile 命令插入到生成的忍者构建系统中,它们被忍者选中,然后生成器知道依赖关系。但是,您可以考虑将您自己的语言添加到 cmake,以便 cmake 自动选择 *.lang 文件。

    我在使用m4 预处理源文件的项目中生成了DEPFILE。使用--debug=p m4 选项,预处理器会在预处理文件时打印m4debug: including file <the file> 或类似的东西。从这些消息中,我提取了文件并生成了依赖文件。

    【讨论】:

    • 这基本上就是我想为 Makefile 生成器做的事情。基本上是手动将那些A:B依赖规则插入到cmake生成的build.make文件的末尾。
    • "但是,您可以考虑将您自己的语言添加到 cmake,以便 cmake 自动选择 *.lang 文件" 我该怎么做?这是我希望的事情。
    • 我没做过,所以没有经验。某处有一个stackoverflow线程解释了如何做到这一点。
    • 我在 cmake 文档和 stackoverflow 上寻找过类似的东西。没有运气。如果可以的话,你能试着记住这个线程吗?这可能会有所帮助。
    • stackoverflow.com/questions/38293535/… 例子有一颗珍珠。我认为检查现有文件,如cmake/Modules 中的CMakeDetermineCCompiler CMakeCCompiler.cmake.in 等也会有所帮助。
    猜你喜欢
    • 2014-07-07
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    相关资源
    最近更新 更多