[CMake] Help debug crazy Windows MSVC issue

Hendrk Sattler post at hendrik-sattler.de
Mon Feb 17 04:20:03 EST 2014


Am 2014-02-17 07:36, schrieb Paul Smith:
> On Mon, 2014-02-17 at 00:20 -0500, Paul Smith wrote:
>> On Sun, 2014-02-16 at 22:38 -0500, David Cole wrote:
>> > > How can I structure my cmake file to avoid
>> > > this double build?
>> >
>> > Put the custom command in a custom target, and make the libraries using
>> > the generated file depend on the custom target.
>> >
>> > That works, even for parallel builds.
>> >
>> > Google around for examples and similar advice. You'll end up using
>> > add_custom_target and add_dependencies in addition to what you already
>> > have.
>> 
>> I was thinking about that earlier, but I didn't do it because the docs
>> for add_custom_target() say:
>> 
>>   The target has no output file and is ALWAYS CONSIDERED OUT OF DATE
>>   even if the commands try to create a file with the name of the 
>> target.
> 
> Thanks for the reply, but this isn't working.
> 
> First, unlike most of the examples I've found I'm generating C++ source
> code, and if I leave the output of the custom command as the generated
> source then I ALWAYS get the double build.  In fact if I put
> add_custom_target it builds THREE times; I tried this:
> 
>   cmake_minimum_required(VERSION 2.8.12)
> 
>   project(TEST C CXX)
> 
>   add_custom_command(OUTPUT bar.cpp
>       COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/foo.cpp bar.cpp
>       DEPENDS foo.cpp
>       COMMENT "GENERATING bar.cpp")
> 
>   set_source_files_properties(bar.cpp PROPERTIES GENERATED TRUE)
> 
>   add_custom_target(BuildBar DEPENDS bar.cpp)
> 
>   add_library(Bar STATIC base.cpp bar.cpp)
>   add_library(BarDLL SHARED base.cpp bar.cpp)
> 
>   add_dependencies(Bar BuildBar)
>   add_dependencies(BarDLL BuildBar)
> 
> and this caused the "GENERATING bar.cpp" line to be run three times
> during my build (setting or not setting the GENERATED property doesn't
> appear to make any difference here).

The DEPENDS above should be a MAIN_DEPENDENCY (not sure if that actually 
changes anything)

The custom target gains you nothing. The problem here are actually the 
tools:
Visual Studio 10 totally relies on the custom build tool to protect 
itself when run in parallel.
It will run the generator as many times as the bar.cpp is mentioned in 
different targets, even in parallel if that is enabled.
And that's what you see.

Solutions:
a) Add "cmake -E copy_if_different" to bar-static.cpp and bar-shared.cpp 
and use those (means: use generated leaf files only in one target).
or
b) Switch off the parallel (target) building in the Visual Studio 
options (this will still generate the files multiple times)
or
c) Use jom (and NMake Makefiles generator)

Regards,

HS



More information about the CMake mailing list