# this defines the build rule for some_file
add_custom_command(
OUTPUT some_file
COMMAND ...
)
# create a target that includes some_file, this gives us a name that we can use later
add_custom_target(
some_target
DEPENDS some_file
)
# then let's suppose we're creating a library
add_library(some_library some_other_file.c)
# we can add the target as a dependency, and it will affect only this library
add_dependencies(some_library some_target)
这种方法的优点是:
some_target不是ALL的依赖项,这意味着您只在特定目标需要时构建它。(而add_custom_target(name ALL ...)将无条件地为所有目标构建它。)
添加以下内容:
如果您熟悉makefile,这意味着:
当您只有一个正在构建的目标时,
add_custom_target(run ALL ...
解决方案将适用于简单的情况,但当您有多个顶级目标(如应用程序和测试)时,它将崩溃。当我试图将一些测试数据文件打包成一个对象文件以便我的单元测试不依赖于任何外部文件时,我遇到了同样的问题。我用
add_custom_command
和一些附加的set_property
依赖魔法解决了这个问题。所以现在testData.cpp将在编译unit-tests.cpp之前生成,并且在任何时候testData.src都会更改。如果你调用的命令真的很慢,你会得到额外的好处,当你只构建应用程序目标时,你不必等待命令(只有测试可执行文件需要)完成。
上面没有显示,但是仔细应用
${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories()
将保持源代码树中生成文件的干净。现有两个答案的问题是,它们要么使依赖项成为全局的(
add_custom_target(name ALL ...)
),要么将其分配给一个特定的单个文件(set_property(...)
),如果有许多文件需要它作为依赖项,这会让人讨厌。相反,我们想要的是一个可以依赖于另一个目标的目标。方法是使用
add_custom_command
定义规则,然后使用add_custom_target
基于该规则定义新目标。然后可以通过add_dependencies
将该目标添加为另一个目标的依赖项。这种方法的优点是:
some_target
不是ALL
的依赖项,这意味着您只在特定目标需要时构建它。(而add_custom_target(name ALL ...)
将无条件地为所有目标构建它。)some_target
是整个库的依赖项,所以它将在该库中的所有文件之前生成。这意味着,如果库中有许多文件,我们不必对每个文件都执行set_property
。DEPENDS
添加到add_custom_command
中,则只有在其输入更改时才能重新生成它。(将此方法与使用add_custom_target(name ALL ...)
的方法进行比较,在这种方法中,无论是否需要,命令都会在每个构建上运行。)有关为什么事情会这样工作的更多信息,请参阅这篇博客文章:https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/
相关问题 更多 >
编程相关推荐