cmake:与add_custom_command依赖关系挣扎

Tal*_*lin 13 cmake

我正在尝试将add_custom_command在一个目录中生成的文件作为另一个目录中add_custom_command的依赖项.

在第一个目录(lib/core)中,我有一个如下所示的构建命令:

add_custom_command(
    OUTPUT libcore.bc
    COMMAND tartln -filetype=bc -link-as-library -o libcore.bc ${STDLIB_BC_FILES}
    DEPENDS ${STDLIB_BC_FILES} tartln
    COMMENT "Linking libcore.bc")
Run Code Online (Sandbox Code Playgroud)

在第二个目录中,我有一个使用该命令输出的命令:

add_custom_command(OUTPUT ${OBJ_FILE}
    COMMAND tartln -disable-fp-elim -filetype=obj -o ${OBJ_FILE} ${BC_FILE}
        "${PROJECT_BINARY_DIR}/lib/core/libcore.bc"
    MAIN_DEPENDENCY "${BC_FILE}" 
    DEPENDS "${PROJECT_BINARY_DIR}/lib/core/libcore.bc"
    COMMENT "Linking Tart bitcode file ${BC_FILE}")
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试构建时,我收到以下错误:

make[3]: *** No rule to make target `lib/core/libcore.bc', needed by `test/stdlib/ReflectionTest.o'.  Stop.
Run Code Online (Sandbox Code Playgroud)

我看到的一个奇怪的事情是错误消息中的路径是相对路径,而不是绝对路径,尽管我知道$ {PROJECT_BINARY_DIR}是一个完整,正确的路径.我不知道这是一个问题还是只是一个奇怪的制作.

我还尝试在lib/core目录中为libcore库创建一个顶级目标:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps)
Run Code Online (Sandbox Code Playgroud)

然后在DEPENDS子句中使用它.奇怪的是,它是第一次执行干净构建时工作,但在任何后续构建时都会出错.在任何情况下,我的理解是DEPENDS仅适用于文件依赖,因此这似乎不是正确的解决方案.(你如何拥有一个依赖于顶级目标的自定义命令?)

我也试过把绝对路径放到各处,没有效果.

小智 7

cmake文档说明了以下有关DEPENDS参数的信息:

DEPENDS选项指定命令所依赖的文件.如果任何依赖项是同一目录中另一个自定义命令的OUTPUT (CMakeLists.txt文件),则CMake会自动将另一个自定义命令带入构建此命令的目标中.如果DEPENDS指定任何目标(由ADD_*命令创建),则会创建目标级依赖关系,以确保在使用此自定义命令的任何目标之前构建目标.

因此,我认为您必须使用add_custom_target定义目标并依赖于此.

add_custom_target的文档说:

使用DEPENDS参数列出的依赖关系可以引用在同一目录(CMakeLists.txt文件)中使用add_custom_command()创建的自定义命令的文件和输出.

因此,您必须使用add_custom_command和add_custom_target,如下所示:

  1. 在第一个生成bc文件的目录中

    add_custom_command(OUTPUT libcore.bc ... ) # just as in your question add_custom_target (LibCoreBC DEPENDS libcore.bc)

  2. 在第二个目录中

    add_custom_command (OUT ${OBJ_FILE} DEPENDS LibCoreBC ....)

  • 不幸的是,这个解决方案不起作用.(我意识到在经过近一年的时间后回复可能是无望的.)据我所知,add_custom_command的DEPENDS参数必须是文件级依赖项 - 尽管文档说同一级别的目标级依赖项*目录*将起作用,事实上我在过去11个月中尝试了许多不同的排列,但它们都没有效果.也就是说,如果我在同一目录中定义自定义目标"foo",然后说DEPENDS"foo",它只会报告"没有规则来制作目标'foo'......" (5认同)

bgo*_*odr 5

这不是答案,而是对您上面的答案之一的澄清。

根据 cmake 文档,创建的自定义目标add_custom_target始终被认为是过时的,并且始终会构建。

IMO,cmake 文件应该改为:

由 add_custom_target 创建的自定义目标始终被认为是过时的,并且始终会构建,但仅在请求时才构建。

这意味着,如果您的所有目标都标记为EXCLUDE_FROM_ALL,并且您有add_custom_target创建新目标的命令,并且您make从命令行键入但未指定目标,则不会构建添加add_custom_target目标。但是,如果您在命令行上明确地拼写出它们make,那么它们就会被构建。另外,ALL您可以指定关键字来add_custom_target强制将它们构建为 all 规则的一部分,我相信这意味着何时make不带参数执行。

  • 我同意。“总是被建造”这句话并不完全正确。 (2认同)