CMake add_custom_命令未运行

2024-04-19 00:40:58 发布

您现在位置:Python中文网/ 问答频道 /正文

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


Tags: 文件命令txtcmakeaddhellooutputversion
3条回答

添加以下内容:

add_custom_target(run ALL
    DEPENDS hello.txt)

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

all: run
run: 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_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中,则只有在其输入更改时才能重新生成它。(将此方法与使用add_custom_target(name ALL ...)的方法进行比较,在这种方法中,无论是否需要,命令都会在每个构建上运行。)

有关为什么事情会这样工作的更多信息,请参阅这篇博客文章:https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/

相关问题 更多 >