CMake add_自定义_命令未运行

CMake add_自定义_命令未运行,cmake,Cmake,我试图在构建期间使用生成文件。命令似乎从未运行过,所以我创建了这个测试文件 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 D

我试图在构建期间使用生成文件。命令似乎从未运行过,所以我创建了这个测试文件

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
    DEPENDS hello.txt)
如果您熟悉makefiles,这意味着:

all: run
run: hello.txt

add\u custom\u target(run ALL…
解决方案适用于简单的情况,即当您只有一个正在构建的目标时,但当您有多个顶级目标(例如应用程序和测试)时,该解决方案会出现故障

当我试图将一些测试数据文件打包到一个对象文件中,这样我的单元测试就不会依赖于任何外部内容时,我遇到了同样的问题。我使用
add\u custom\u命令
和一些附加的依赖魔法
set\u属性
解决了这个问题

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\u BINARY\u DIR}、${PROJECT\u SOURCE\u DIR}和include\u directories()
将保持源代码树中没有生成的文件。

现有两个答案的问题是,它们要么使依赖项成为全局的(
添加自定义目标(全称…
),或者他们将其分配给一个特定的单个文件(
set_property(…)
),如果您有许多文件需要它作为依赖项,这会让人讨厌。相反,我们想要的是一个可以对另一个目标进行依赖的目标


方法是使用
add_custom_命令
定义规则,然后
add_custom_目标
根据该规则定义新目标。然后,您可以通过
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\u target
    不是
    ALL
    的依赖项,这意味着您只能在特定目标需要时构建它。(而
    add\u custom\u target(name ALL…
    将无条件地为所有目标构建它。)
  • 因为
    some_target
    是整个库的一个依赖项,它将在该库中的所有文件之前构建。这意味着如果库中有许多文件,我们不必对每个文件都执行
    set_属性
  • 如果我们将
    dependens
    添加到
    add_custom_命令
    中,则只有在其输入发生变化时才会重新生成该命令。(将此与使用
    add_custom_target(name ALL…
    的方法进行比较,在该方法中,无论是否需要,命令都会在每个构建上运行。)

有关为什么会出现这种情况的更多信息,请参阅以下博文:

当最佳答案不是带有绿色复选图标的答案时,这是一个尴尬的时刻:)谢谢!难道
add_dependencies
不能完成
set_属性(…
行)的工作吗?cmake还有很多其他的优点。我真正喜欢的一个主要方面是生成器(makefile、ninja文件、visualstudio、Eclipse等)。CMake的语言没有任何常规高级编程语言进化得那么快,但只要你在几个小时内掌握了它,它就会变得非常简单。Autotools很好,在过去很流行。想想看:为什么有那么多人使用CMake而不是Autotools?它更容易学习,并且提供了更多的好处。@dom0,Y您可以使用
add_dependencies
,但这有点棘手。您不能直接在
add_custom_命令
和其他命令之间添加依赖项,您首先必须创建一个
add_custom_目标
(它是空的,只是用来提供一个您以后可以命名的目标)原因是,
add_dependencies
只能将目标作为参数,而不是文件。更多信息,请参阅本博客:更尴尬的时刻是,从已接受的答案向下的两个答案是最好的答案,而对“应该是”答案的第一个评论听起来是专业的,而不是刺耳的。add_custom_target是alterActive to add_custom_command这对我来说不起作用,CMake 3.6.1,OSX。我在我的CMakeLists.txt
add_custom_命令(OUTPUT hello.txt命令touch ARGS hello.txt dependens hello.txt)
中添加了
add_custom_目标(运行全部取决于hello.txt)
add\u custom\u target
每次运行时,请按照Rian的建议使用
add\u custom\u命令
instead@linello从
add\u custom\u命令()调用中删除依赖项,它将创建循环依赖项。只有
add\u custom\u目标()
这里应该有DEPENDS参数。当您修复该参数时,它在OS X上对我有效(使用CMake 3.8.0测试)。