[CMake] Parallel builds do not work correctly when using "cmake -E copy" to copy files

Alan W. Irwin irwin at beluga.phys.uvic.ca
Thu Dec 13 21:45:36 EST 2007


On 2007-12-13 19:15-0500 Brad King wrote:

> Alan W. Irwin wrote:
>> So the rule seems to be that parallel builds do not work if there are two
>> or more separate custom targets that file depend directly or indirectly
>> (via
>> some custom command file dependency chain) on the same output files.
>>
>> Another way of summarizing these results is that file depends must be
>> minimized and/or custom target depends maximized in order for parallel
>> builds to work properly.
>
> This is correct.
>
>> My guess is I should be able to work around this CMake issue by appropriate
>> changes to the PLplot build system although I have a number of these
>> parallel build issues and the copy problem was only the most obvious.
>>
>> I do regard this as a CMake issue.  Normally, the shoe is on the other
>> foot,
>> and the build system developer is desperately trying to make sure that all
>> the CMake file depends are obviously in place locally rather than depending
>> on a long easily-broken chain of dependencies to do it for them in a
>> minimalist way.  So the big question is whether CMake can be modified so
>> that minimalist file depends and/or maximal (and unintuitive) target
>> depends
>> are not required in order for parallel builds to work properly.
>
> I don't see how CMake can automatically fix this.  If two targets think
> they know how to build the same file how is CMake supposed to know which
> one is the correct target to build first?

I am not completely convinced by that reasoning.  Let me create an abstract
case in Makefile terms that we can discuss (at first) strictly from the GNU
make point of view.  Putting my simple test case in Makefile terms we have
the following rules:

all: target1 target2

file1:
 	custom command to create file1

fileN:
 	custom command to create fileN

target1: file1, file2,....fileN

additional_file: file1, file2,....fileN
 	custom command to create additional_file

There are two alternatives for the target2 dependencies

Either

target2: additional_file  (OPTION A)

or

target2: target1 additional_file (OPTION B)

all, target1, and target2 arephony targets that do not correspond
to actual files.

OPTION A is what my simple example (and current PLplot) uses.  OPTION B
is one fixup you discussed where you made target2 depend on target1.

I know OPTION A always works for serial builds. The reason is each target
knows independently how to build what it needs.  target1 file-depends
directly on the files from a variety of file1 through fileN custom rules. So
it knows how to build exactly what it needs.  target2 (with OPTION A)
file-depends on additional_file which file depends on the file1-fileN rules.
So target2 knows how to build exactly what it needs as well. Thus, if you
remove target1, target2 would build without problems and vice versa.

Of course once you introduce parallel builds it gets complicated, and I
would appreciate your input on that.  I have always assumed that if one
processor was busy creating file1 through the target1 chain of dependencies
the make command kept track that a build of file1 was in progress so the
other processor would not attempt to duplicate that build regardless of
whether it needed it via the target1 or target2 dependency chains.  Indeed,
OPTION A works well for parallel builds (see below where I non-recursively
invoke the appropriate Makefile that is generated by CMake).

You claim that OPTION B must be used for parallel builds (at least if I have
understood you correctly and if my mental model of how cmake dependencies
translate to Makefile dependencies is correct).  I just don't see the
necessity of OPTION B for parallel builds for non-recursive Makefiles, but I
am willing to be educated. :-)

If GNU make does parallel builds without problems for non-recursive OPTION A
(which appears to be the case, see below), then my concern is that CMake is
introducing some additional make issues via the make recursion that it
normally employs that screws up parallel builds and OPTION B is simply a
workaround that bypasses that recursion issue.

Brad, I am struggling with understanding the recursive make system that
CMake normally employs so I am having trouble following the complete
Makefile logic that my simple example creates.  However,
CMakeFiles/tclIndex_examples_tcl2.dir/build.make generated by my simple
CMake example seems to follow the above OPTION A scenario.  Indeed, if I execute
that Makefile directly from the commmand line, e.g.,

make -f CMakeFiles/tclIndex_examples_tcl2.dir/build.make \
CMakeFiles/tclIndex_examples_tcl2.dir/clean
make -j 2 -f CMakeFiles/tclIndex_examples_tcl2.dir/build.make \
CMakeFiles/tclIndex_examples_tcl2.dir/build

there are never double copy problems, while if I run

make clean
make -j 2

there are always double copy problems.  (You should try this for yourself to
be sure you can replicate my experience.) So my current working hypothesis
is there is a parallel build issue for OPTION A that CMake artificially
introduces when it recursively invokes make (i.e., the result of the
above "make -j 2" command).

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__________________________

Linux-powered Science
__________________________


More information about the CMake mailing list