Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake add_custom_command issue with multiple output files

Tags:

c++

cmake

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!

like image 779
vpradeep Avatar asked Jun 25 '14 18:06

vpradeep


1 Answers

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

like image 164
vpradeep Avatar answered Nov 02 '22 16:11

vpradeep