CMake add_custom_命令未运行

voj3qocg  于 2023-01-02  发布在  其他
关注(0)|答案(4)|浏览(264)

我试图在编译过程中使用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。我做错了什么?

tcbh2hod

tcbh2hod1#

add_custom_target(run ALL ...解决方案适用于只有一个目标正在构建的简单情况,但当您有多个顶级目标(例如应用程序和测试)时,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()会使源代码树中没有生成的文件。

iszxjhcz

iszxjhcz2#

增加以下内容:

add_custom_target(run ALL
    DEPENDS hello.txt)

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

all: run
run: hello.txt
rekjcdws

rekjcdws3#

现有的两个答案的问题在于,它们要么使依赖关系成为全局的(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/

2j4z5cfb

2j4z5cfb4#

这个问题已经很老了,但即使我遵循了建议的建议,它也不适合我(至少不是每次)。
我正在使用Android Studio,需要调用cMake来构建C++库。在添加代码以运行自定义脚本之前,它一直工作正常(事实上,在我尝试运行"touch"时,如上例所示)。
首先

add_custom_command

根本不起作用。
我试过了

execute_process (
        COMMAND touch hello.txt
)

它起作用了,但不是每次都起作用!
我试图清理项目,手动删除创建的文件,同样的事情。
尝试的cMake版本:
3.10.2
3.18.1
3.22.1
当它们工作时,它们会产生不同的结果,这取决于cMake版本、一个文件或几个文件。只要它们工作,这并不重要,但这就是问题所在。
有人能解释一下这个谜吗?

相关问题