[cmake-developers] [CMake 0012311]: Parallel builds may fail when using add_custom_command

Mantis Bug Tracker mantis at public.kitware.com
Thu Jun 30 03:52:19 EDT 2011


The following issue has been SUBMITTED. 
====================================================================== 
http://public.kitware.com/Bug/view.php?id=12311 
====================================================================== 
Reported By:                Marcel Loose
Assigned To:                
====================================================================== 
Project:                    CMake
Issue ID:                   12311
Category:                   CMake
Reproducibility:            always
Severity:                   major
Priority:                   normal
Status:                     new
====================================================================== 
Date Submitted:             2011-06-30 03:52 EDT
Last Modified:              2011-06-30 03:52 EDT
====================================================================== 
Summary:                    Parallel builds may fail when using
add_custom_command
Description: 
When two or more targets depend on a source that is generated by a custom
command, then the rule to create this source is executed more than once when
doing a parallel build. This may even result in a corrupt source as can be
demonstrated (see Steps to Reproduce)


Steps to Reproduce: 
1. Create the following files:

::::::::::::::
CMakeLists.txt
::::::::::::::
cmake_minimum_required(VERSION 2.6)
project(Parallel_Generated)        

add_custom_command(OUTPUT hello.cc
  COMMAND ${CMAKE_COMMAND}        
          -DINFILE=${CMAKE_SOURCE_DIR}/hello.txt
          -P ${CMAKE_SOURCE_DIR}/generate.cmake 
  DEPENDS hello.txt                             
)                                               

set_source_files_properties(hello.cc PROPERTIES GENERATED TRUE)
include_directories(${CMAKE_BINARY_DIR})                       

add_executable(one one.cc hello.cc)
add_executable(two two.cc hello.cc)

::::::::::::::
generate.cmake
::::::::::::::
file(WRITE hello.cc "
#include <iostream>  
void hello(const char* prefix)
{                             
")                            
file(STRINGS "${INFILE}" lines)
foreach(line ${lines})         
  file(APPEND hello.cc "       
  std::cout << prefix << \": ${line}\" << std::endl;
  ")                                                
endforeach(line)                                    
file(APPEND hello.cc "                              
}                                                   
")                                                  
::::::::::::::
hello.txt
::::::::::::::
Hello World.
I'm foo bar baz.

::::::::::::::
one.cc
::::::::::::::
extern void hello(const char*);
int main()
{
  hello("one");
  return 0;
}
::::::::::::::
two.cc
::::::::::::::
extern void hello(const char*);
int main()
{
  hello("two");
  return 0;
}

2. Create a build directory and run cmake from there.

3. Run the following bash-command line

   $ while true; do make clean; make -j2 || break; done

You'll notice that for each build there are two lines "Generating ..."
Sooner or later, after a few (re)builds, the build fail. Checking the generated
source will explain why. 

Additional Information: 
References:
http://www.mail-archive.com/cmake@cmake.org/msg37021.html
http://www.mail-archive.com/cmake@cmake.org/msg36403.html
http://www.mail-archive.com/cmake@cmake.org/msg32782.html

====================================================================== 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2011-06-30 03:52 Marcel Loose   New Issue                                    
======================================================================




More information about the cmake-developers mailing list