自定义源文件中的动态依赖关系

时间:2020-07-03 10:05:56

标签: cmake

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

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

例如,假设我有文件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。我可以随时通过预处理 找到这些自定义文件的这些依赖项。然后在source2.lang上生成source1.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 这些是新的依赖项? 基本上,与cmake一样,当您将新的#include添加到C源文件中时,通常也是如此。这样其他发电机也可以使用。

1 个答案:

答案 0 :(得分:2)

我认为以下内容仅适用于Ninja generator。我认为它也可以与makefile生成器一起使用,但是我没有检查。

add_custom_command具有DEPFILE选项。您必须从命令中以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文件。

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

相关问题