CMake add_custom_command没有运行

Jon*_*erg 48 cmake

我正在尝试使用add_custom_command在构建期间生成文件.该命令似乎永远不会运行,所以我制作了这个测试文件.

cmake_minimum_required( VERSION 2.6 )

add_custom_command(
  OUTPUT hello.txt
  COMMAND touch hello.txt
  DEPENDS hello.txt
)
Run Code Online (Sandbox Code Playgroud)

我试过跑:

cmake .  
make
Run Code Online (Sandbox Code Playgroud)

并且没有生成hello.txt.我做错了什么?

Ria*_*son 55

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)
Run Code Online (Sandbox Code Playgroud)

所以现在testData.cpp将在编译unit-tests.cpp之前生成,并且每次testData.src都会更改.如果您正在调用的命令非常慢,那么您将获得额外的好处,即当您构建应用程序目标时,您不必等待该命令(只有测试可执行文件需要)才能完成.

它没有在上面显示,但仔细的应用${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories()将保持您的源树清理生成的文件.

  • 这个尴尬的时刻,最好的答案不是带有绿色检查图标的那个:)谢谢Rian! (6认同)
  • 不应该`add_dependencies`能够完成`set_property(...`行的工作? (2认同)
  • @ dom0,您可以使用`add_dependencies`来实现,但是有点棘手。您不能直接在`add_custom_command`和其他东西之间添加依赖关系,首先必须创建一个`add_custom_target`(为空,它只是提供一个可以稍后命名的目标)。原因是`add_dependencies`只能将目标作为参数,而不能作为文件。有关更多信息,请参见此博客:https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/ (2认同)

dim*_*mba 34

添加以下内容:

add_custom_target(run ALL
    DEPENDS hello.txt)
Run Code Online (Sandbox Code Playgroud)

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

all: run
run: hello.txt
Run Code Online (Sandbox Code Playgroud)

  • `add_custom_target` 每次都会运行,请使用 Rian 提倡的 `add_custom_command` 代替 (2认同)

Ell*_*ter 14

两个现有答案的问题是它们要么使依赖关系成为global(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)
Run Code Online (Sandbox Code Playgroud)

这种方法的优点:

  • some_target不是依赖项ALL,这意味着只有在特定目标需要时才构建它.(而add_custom_target(name ALL ...)无条件地为所有目标构建它.)
  • 因为它some_target是整个库的依赖项,所以它将在该库中的所有文件之前构建.这意味着如果库中有很多文件,我们就不必set_property对它们中的每一个文件进行操作.
  • 如果我们添加DEPENDSadd_custom_command那么它只会在输入改变时重建.(将此与使用add_custom_target(name ALL ...)命令在每个构建上运行的方法进行比较,无论是否需要.)

有关事情以何种方式运作的更多信息,请参阅此博客文章:https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/