[cmake-developers] CMake generates Makefiles that don't parallelize as much as they could.

Brad King brad.king at kitware.com
Wed Jul 23 09:14:20 EDT 2014


On 07/23/2014 09:07 AM, Nick Overdijk wrote:
> Oh wait, since a is in the interface of b, b will always be
> accompanied by a, even though it's not a dependency.
> Is that how it works? 

Yes.  If B is a static library then it does not really link so
its dependencies are only ever used transitively when something
else links to B.  If B really links as a shared library though
then see the following.

If target B links to target A then CMake will not compile objects
in B until A is done.  As explained in my previous link this is
because we allow A to contain custom commands that generate
headers used by B.  The VS and Xcode IDE build systems offer only
this granularity since they organize compilation and linking rules
of a single target together.  The Makefile generator was designed
this way too.  Only the Ninja generator has a chance of increasing
parallelism if the extra ordering dependencies were dropped.  We've
thought about how to do extra analysis to determine when there is
no such custom command to drop them but have not implemented anything
yet.

You might be able to use OBJECT libraries to increase parallelism
for all generators and with no changes to CMake:

 set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 add_library(Aobjs OBJECT a1.c a2.c)
 add_library(Bobjs OBJECT b1.c b2.c)
 add_library(Cobjs OBJECT c1.c c2.c)
 set(dummy_c dummy.c) # needed for VS 6 and Xcode
 add_library(A SHARED $<TARGET_OBJECTS:Aobjs> ${dummy_c})
 add_library(B SHARED $<TARGET_OBJECTS:Bobjs> ${dummy_c})
 add_library(C SHARED $<TARGET_OBJECTS:Cobjs> ${dummy_c})
 target_link_libraries(B PUBLIC A)
 target_link_libraries(C PUBLIC B)

This way the object compilations will be completely independent
of one another and of the linking and ordering dependencies.

-Brad




More information about the cmake-developers mailing list