我正在尝试将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")
在第二个目录中,我有一个使用该命令输出的命令:
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}是一个完整,正确的路径。我不知道这是一个问题,还是只是一种陌生的做法。
我还尝试在lib / core目录中为libcore库创建一个顶级目标:
add_custom_target(libcore DEPENDS libcore.bc libcore.deps)
然后在DEPENDS子句中使用它。奇怪的是,它是第一次执行干净构建时工作,但在任何后续构建时都会出错。在任何情况下,我的理解是DEPENDS仅适用于文件依赖,因此这似乎不是正确的解决方案。 (你如何拥有一个依赖于顶级目标的自定义命令?)
我也试过把绝对路径放到各处,没有效果。
答案 0 :(得分:7)
cmake文档说明了以下有关DEPENDS参数的内容:
DEPENDS选项指定命令所依赖的文件。如果 任何依赖项都是另一个自定义命令的OUTPUT 目录(CMakeLists.txt文件)CMake自动带来另一个 自定义命令到构建此命令的目标中。如果 DEPENDS指定任何目标(由ADD_ *命令创建)a 创建目标级依赖项以确保构建目标 在使用此自定义命令的任何目标之前
因此我认为您必须使用add_custom_target定义目标并依赖于此。
add_custom_target的文档说:
使用DEPENDS参数列出的依赖项 可以引用用其创建的自定义命令的文件和输出 add_custom_command()在同一目录(CMakeLists.txt文件)中。
所以你必须使用add_custom_command和add_custom_target,如下所示:
在生成bc文件的第一个目录中,您可以
add_custom_command(OUTPUT libcore.bc ... ) # just as in your question
add_custom_target (LibCoreBC DEPENDS libcore.bc)
在第二个目录中执行
add_custom_command (OUT ${OBJ_FILE} DEPENDS LibCoreBC ....)
答案 1 :(得分:3)
这是一个非答案,但对上述answers之一的澄清。
根据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 :(得分:0)
我认为add_custom_target
不适用于我想要的东西。根据cmake文档,add_custom_target创建的自定义目标始终被视为过时,并且始终构建。
问题在于我尝试从一个add_custom_command
获取输出,并将其输入到另一个目录中的另一个add_custom_command
的输入中。我只希望在原始源文件过期时发生这种情况 - 如果我使用add_custom_target
,那么即使源文件没有改变,也总是会重建输出。鉴于有数百个这样的源文件,这将使构建非常慢。
这就是我要做的事情:我有一个程序,它在给定源文件的情况下生成.bc文件(LLVM bitcode)。有很多这些源文件,它们会创建大量的.bc文件。
第二个程序将所有.bc文件转换为单个.obj(ELF对象)文件。所以转换步骤如下所示:
source file -> .bc (via add_custom_command)
.bc -> .obj (via add_custom_command)
.obj -> .exe (via add_executable)
原始源代码文件位于不同的目录中,因为它们是类库 - 我不想将每个类库的所有代码放在同一目录中。
答案 3 :(得分:0)
尝试将以下命令添加到第二个目录: set_source_files_properties($ {PROJECT_BINARY_DIR} /lib/core/libcore.bc属性已生成TRUE)
我用此命令解决了我的问题。 相关链接:https://cmake.org/cmake/help/latest/prop_sf/GENERATED.html