cmake add_custom_command问题与多个输出文件 [英] cmake add_custom_command issue with multiple output files

查看:929
本文介绍了cmake add_custom_command问题与多个输出文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到在使用 add_custom_command 和多个输出文件时,cmake中的一些潜在的不正确的行为。我已经能够隔离问题的一个最小的例子(见下文)。看来,当我有两个输出文件在我的 add_custom_command 中指定,第二个输出文件的上游依赖关系在一些情况下没有被正确跟踪。 cmake文档清楚地提到允许使用多个输出文件。这里有趣的是,交换输出文件的顺序会导致不同的行为,建议第一个 OUTPUT 文件被不同地对待。



请参考下面的玩具示例展示此行为。第一次调用make运行就好了。触摸 a.txt 后,复制baz.cpp到baz2.cpp 规则在第一次调用时不执行到 make ,但在第二次调用 make 时运行。这意味着在单击 make 之后,构建仍将失效。请注意,通过将 add_custom_command 中的输出顺序更改为 OUTPUT baz.cpp bar.cpp



示例CMakeLists.txt:

  cmake_minimum_required(VERSION 2.8)

add_library(mybaz baz.cpp)

add_custom_command(
OUTPUT baz2.cpp
COMMAND cp) baz.cpp baz2.cpp
DEPENDS baz.cpp
COMMENT将baz.cpp复制到baz2.cpp)

add_custom_target(mytarget
DEPENDS baz2.cpp
COMMENTRunning mytarget)

add_dependencies(mybaz mytarget)

add_custom_command(
OUTPUT bar.cpp baz.cpp
COMMAND cat a .txt> bar.cpp
COMMAND cat a.txt> baz.cpp
DEPENDS a.txt
COMMENT生成bar.cpp和baz.cpp)

下面是我运行的命令:

 > touch a.txt 
> cmake。
... snip ...(配置运行正常)
> make
扫描目标的依赖关系mytarget
[20%]生成bar.cpp和baz.cpp
[40%]将baz.cpp复制到baz2.cpp
[60%]运行mytarget
[60%]建立目标mytarget
扫描目标mybaz的依赖关系
[80%]构建CXX对象CMakeFiles / mybaz.dir / baz.cpp.o
链接CXX静态库libmybaz.a
[100%]建立目标mybaz
(一切看起来不错)

> touch a.txt
> make
[20%]生成bar.cpp和baz.cpp
[40%]运行mytarget
[60%]建立目标mytarget
扫描目标mybaz的依赖关系
[80%]构建CXX对象CMakeFiles / mybaz.dir / baz.cpp.o
链接CXX静态库libmybaz.a
[100%]构建目标mybaz
(我似乎是缺少复制baz.cpp到baz2.cpp行)

> make
[20%]将baz.cpp复制到baz2.cpp
[40%]运行mytarget
[60%]建立目标mytarget
[100%]建立目标mybaz
(复制baz.cpp到baz2.cpp执行这一次)



感谢您的帮助! >解决方案

这实际上是CMake 2.8.12.1中的一个错误。根据CMake的人,第一个输出是由Makefile生成器(虽然,可能没有一个原因,它被特殊对待)。



请参阅CMake bugreport: http://www.cmake.org/Bug/view.php?id=15116


I'm noticing some potential incorrect behavior in cmake when working with add_custom_command and multiple output files. I've been able to isolate the problem to a minimal example (see below). It seems that when I have two output files specified in my add_custom_command, the second output file's upstream dependencies are not being tracked correctly in some cases. The cmake documentation clearly mentions that multiple output files are allowed. What's interesting here is that swapping the order of the output files causes different behavior, suggesting that the first OUTPUT file is being treated differently.

Please refer to the toy example below that exhibits this behavior. The first call to make runs just fine. After touching a.txt, the Copying baz.cpp to baz2.cpp rule doesn't execute on the first call to make, but runs on the second call to make. This means that the build will still be stale after a single call to make. Note that this issue is fixed by changing the order of the outputs in add_custom_command to OUTPUT baz.cpp bar.cpp

Example CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)

add_library(mybaz baz.cpp)

add_custom_command(
  OUTPUT  baz2.cpp
  COMMAND cp baz.cpp baz2.cpp
  DEPENDS baz.cpp
  COMMENT "Copying baz.cpp to baz2.cpp")

add_custom_target(mytarget
  DEPENDS baz2.cpp
  COMMENT "Running mytarget")

add_dependencies(mybaz mytarget)

add_custom_command(
  OUTPUT  bar.cpp baz.cpp
  COMMAND cat a.txt > bar.cpp
  COMMAND cat a.txt > baz.cpp
  DEPENDS a.txt
  COMMENT "Generating bar.cpp and baz.cpp")

Below are the commands that I run:

> touch a.txt
> cmake .
    ...snip... (configuration runs fine)
> make
Scanning dependencies of target mytarget
[ 20%] Generating bar.cpp and baz.cpp
[ 40%] Copying baz.cpp to baz2.cpp
[ 60%] Running mytarget
[ 60%] Built target mytarget
Scanning dependencies of target mybaz
[ 80%] Building CXX object CMakeFiles/mybaz.dir/baz.cpp.o
Linking CXX static library libmybaz.a
[100%] Built target mybaz
  (everything looks good)

> touch a.txt
> make
[ 20%] Generating bar.cpp and baz.cpp
[ 40%] Running mytarget
[ 60%] Built target mytarget
Scanning dependencies of target mybaz
[ 80%] Building CXX object CMakeFiles/mybaz.dir/baz.cpp.o
Linking CXX static library libmybaz.a
[100%] Built target mybaz
  (I seem to be missing the 'Copying baz.cpp to baz2.cpp' line)

> make
[ 20%] Copying baz.cpp to baz2.cpp
[ 40%] Running mytarget
[ 60%] Built target mytarget
[100%] Built target mybaz
  ( The 'Copying baz.cpp to baz2.cpp' executes this time )

This has been tested using CMake version 2.8.12.2 on a linux machine.

Thanks in advance for your help!

解决方案

This is in fact a bug in CMake 2.8.12.1. According to the CMake folks, the first output is being treated specially by the Makefile generator (though, there probably isn't a reason for it to be treated specially). A fix to CMake has been made, and is targeted for CMake 3.2.

See the CMake bugreport: http://www.cmake.org/Bug/view.php?id=15116

这篇关于cmake add_custom_command问题与多个输出文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆