CMake add_custom_command没有运行

时间:2010-05-30 00:50:22

标签: cmake

我正在尝试使用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。我做错了什么?

3 个答案:

答案 0 :(得分:51)

add_custom_target(run ALL ...解决方案适用于您只有一个目标正在构建的简单情况,但是当您有多个顶级目标时会崩溃,例如应用和测试。

当我尝试将一些测试数据文件打包到一个目标文件中时,我遇到了同样的问题,所以我的单元测试不依赖于任何外部测试。我使用add_custom_commandset_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()会使源代码树保持生成文件的清晰。

答案 1 :(得分:31)

添加以下内容:

add_custom_target(run ALL
    DEPENDS hello.txt)

如果您熟悉makefile,这意味着:

all: run
run: hello.txt

答案 2 :(得分:8)

两个现有答案的问题是,它们要么使全局依赖关系(<a href='#' *ngIf='authService.isLoggedIn$ | async' (click)='logOut()'>Log Out</a> ),要么将其分配给特定的单个文件(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的方法进行比较,在该方法中,无论是否需要,该命令都会在每个版本上运行。)

有关为什么这种方式起作用的更多信息,请参见此博客文章:https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/