我有一些非C / C ++的自定义源文件。将这些文件编译为C源文件,然后像往常一样通过cmake编译这些C文件。
但是,我的自定义文件可能具有在开发过程中可能会更改的依赖项。
例如,假设我有文件source1.lang
,source2.lang
,source3.lang
...
source1.lang
... some code
source2.lang
import source1;
... some code
我将这些文件编译为
./langc source1.lang
./langc source2.lang
...
我得到source1.c
,source2.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源文件中时,通常也是如此。这样其他发电机也可以使用。
答案 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>
或类似内容。从这些消息中,我提取了文件并生成了依赖文件。