target_link_libraries, build order and build parallelism

Hi CMake gurus!
Given the example CMakeLists.txt file below I have a few questions.

  1. Why does building libb first build liba? As I understand it liba should just be propagated as a link time dependency to whatever actually links it in (exec), but I realize I’m missing something.
  2. Also I have observed differences in build order between ninja, make and vs2019. Is there an intended behavior in these cases or is it up to differences in the build systems or bugs?
    • When building exec ninja seems to be able to build a.cpp, b.cpp, and c.cpp in parallel whereas vs2019 does liba, libb and exec in sequence.
    • When building libf, ninja only compiles f.cpp, whereas make and vs2019 first builds libd.

Do you have any suggestions to increase the parallelism of builds in general when using CMake?

cmake_minimum_required( VERSION 3.16 )
project( Hmm LANGUAGES CXX )

add_library( liba a.cpp )
add_library( libb b.cpp )
target_link_libraries( libb PRIVATE liba )
add_executable( exec c.cpp )
target_link_libraries( exec libb )

add_library( libd d.cpp )
add_library( libe INTERFACE )
target_link_libraries( libe INTERFACE libd )
add_library( libf OBJECT f.cpp )
target_link_libraries( libf PRIVATE libe )
add_executable( exeg g.cpp $<TARGET_OBJECTS:libf> )
target_link_libraries( exeg PRIVATE libf )

This is a guarantee that CMake provides as part of its model. If liba has any custom commands attached to it, libb can assume they exist because CMake does this. The Ninja generator has logic to relax this dependency if CMake can convince itself that the dependency is unnecessary.

That explains it, thanks! :slight_smile: