cmake:努力与add_custom_command依赖关系

问题描述:

我想获得一个add_custom_command在一个目录中生成的文件是add_custom_command在另一个目录中的依赖项。cmake:努力与add_custom_command依赖关系

在第一目录(LIB /芯)我有一个构建命令,看起来像这样:

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") 

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

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}") 

但是,当我尝试建立,我得到以下错误:

make[3]: *** No rule to make target `lib/core/libcore.bc', needed by `test/stdlib/ReflectionTest.o'. Stop. 

一个奇怪的事情我发现错误消息中的路径是相对的,而不是绝对路径,尽管我知道$ {PROJECT_BINARY_DIR}是一个完整的正确路径。我不知道这是一个问题还是一个奇怪的做法。

我也试着做一个顶级目标为libcore库,在lib/core目录:

add_custom_target(libcore DEPENDS libcore.bc libcore.deps) 

,然后使用该的depends子句。关于这一点的奇怪之处在于,它在您第一次执行干净构建时会有效,但会在后续构建中发生错误。无论如何,我的理解是DEPENDS只能用于文件依赖性,所以这看起来不是正确的解决方案。 (你怎么有一个自定义的命令,依赖于顶级目标呢?)

我也试着把绝对路径无处不在,没有效果。

CMake的文件说,下面讲的depends参数:

The DEPENDS option specifies files on which the command depends. If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built. If DEPENDS specifies any target (created by an ADD_* command) a target-level dependency is created to make sure the target is built before any target using this custom command.

因此,我认为你必须定义一个目标使用add_custom_target和依赖于此。

为add_custom_target文档说:

Dependencies listed with the DEPENDS argument may reference files and outputs of custom commands created with add_custom_command() in the same directory (CMakeLists.txt file).

所以你必须按如下方式使用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 ....)

+4

不幸的是,这个解决方案不起作用。 (我意识到在将近一年过去之后可能无望回复。)据我所知,add_custom_command的DEPENDS参数必须是文件级依赖项 - 尽管文档说目标级依赖项*目录*将起作用,事实上,在过去的11个月里,我尝试了许多不同的排列方式,并且它们都不起作用。也就是说,如果我在同一个目录中定义自定义目标“foo”,然后说出DEPENDS“foo”,它会简单地报告“没有规则使目标'foo'...” – Talin 2011-09-20 06:29:47

+0

@Talin因此,这似乎是错误,在[CMake bugtracker](http://www.cmake.org/Bug/my_view_page.php)中是否存在此问题? – lef 2015-09-10 11:58:41

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

问题是我试图从一个add_custom_command获取输出,并将其输入另一个目录中另一个add_custom_command的输入。我只希望在原始源文件过期的情况下发生这种情况 - 如果我使用了add_custom_target,那么即使源文件没有更改,输出也会始终被重建。鉴于有数百个这些源文件,这会使构建非常缓慢。

下面是我想要做的:我有一个程序,它会生成一个给定源文件的.bc文件(LLVM位码)。有很多这些源文件,它们会创建很多.bc文件。

第二个程序将所有.bc文件转换为一个.obj(ELF对象)文件。所以转换步骤是这样的:

source file -> .bc  (via add_custom_command) 
    .bc   -> .obj (via add_custom_command) 
    .obj  -> .exe (via add_executable) 

原来的源代码文件在不同的目录,是因为它们是类的库 - 我不希望有把所有的代码为每一个类库在同目录。

这是一个无法回答的问题,但是需要对您的answers进行说明。

According to the cmake documents, a custom target created by add_custom_target is always considered out of date and is always built.

IMO,CMake的文件应该说不是:

A custom target created by add_custom_target is always considered out of date and is always built, but only when requested.

这意味着,如果所有的目标都被标记为EXCLUDE_FROM_ALL,你必须创造新的目标add_custom_target命令,键入make从没有指定目标的命令行中,添加了add_custom_target的目标是而不是构建的。但是,如果您明确地在make命令行上拼出它们,则会构建它们。此外,还有ALL关键字,您可以指定add_custom_target强制将其构建为所有规则的一部分,我相信这意味着make在没有参数的情况下执行。

+0

我同意。 “总是建立”这个词并不是真的。 – 2014-07-03 23:38:16