我正在尝试使用add_custom_command在构建期间生成文件。该命令似乎从未运行过,所以我制作了这个测试文件。
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
我尝试运行:
cmake .
make
并且没有生成 hello.txt。我做错了什么?
我正在尝试使用add_custom_command在构建期间生成文件。该命令似乎从未运行过,所以我制作了这个测试文件。
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
我尝试运行:
cmake .
make
并且没有生成 hello.txt。我做错了什么?
add_custom_target(run ALL ...
当您只构建一个目标时,该解决方案将适用于简单的情况,但当您有多个顶级目标(例如应用程序和测试)时会崩溃。
当我试图将一些测试数据文件打包到一个目标文件中时,我遇到了同样的问题,这样我的单元测试就不会依赖于任何外部。我使用add_custom_command
和一些额外的依赖魔法解决了它set_property
。
add_custom_command(
OUTPUT testData.cpp
COMMAND reswrap
ARGS testData.src > testData.cpp
DEPENDS testData.src
)
set_property(SOURCE unit-tests.cpp APPEND PROPERTY OBJECT_DEPENDS testData.cpp)
add_executable(app main.cpp)
add_executable(tests unit-tests.cpp)
所以现在 testData.cpp 将在 unit-tests.cpp 编译之前生成,并且任何时候 testData.src 更改。如果您调用的命令真的很慢,您将获得额外的好处,即当您仅构建应用程序目标时,您不必等待该命令(只有测试可执行文件需要)完成。
它没有在上面显示,但仔细应用${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories()
将使您的源代码树保持清洁生成的文件。
Add the following:
add_custom_target(run ALL
DEPENDS hello.txt)
If you're familiar with makefiles, this means:
all: run
run: hello.txt
add_custom_target(name ALL ...)
两个现有答案的问题是,它们要么使依赖项成为全局依赖项set_property(...)
(相反,我们想要的是一个可以使另一个目标依赖的目标。
这样做的方法是使用add_custom_command
定义规则,然后add_custom_target
根据该规则定义一个新目标。然后,您可以通过添加该目标作为另一个目标的依赖项add_dependencies
。
# 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 ...)
将为所有目标无条件地构建它。)some_target
是整个库的依赖项,所以它将在该库中的所有文件之前构建。这意味着如果库中有很多文件,我们不必set_property
对每个文件都进行处理。DEPENDS
到add_custom_command
then 它只会在其输入发生变化时重建。(将此与使用add_custom_target(name ALL ...)
命令在每次构建时运行的方法进行比较,无论它是否需要。)有关为什么以这种方式工作的更多信息,请参阅此博客文章:https ://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/