Understanding some of the recent cmake build changes

I was a bit confused with what the difference was between the old

target_link_libraries(foo bar)

and the new

target_link_libraries(foo INTERFACE|PRIVATE|PUBLIC bar)

To try to find out, I decided to look at the generated build.ninja.
The difference that shows up is far fewer order only dependencies. For
example

build lib/TableGen/CMakeFiles/LLVMTableGen.dir/Error.cpp.o:
CXX_COMPILER /home/espindola/llvm/llvm/lib/TableGen/Error.cpp ||
lib/libLLVMSupport.a

becomes just

build lib/TableGen/CMakeFiles/LLVMTableGen.dir/Error.cpp.o:
CXX_COMPILER /home/espindola/llvm/llvm/lib/TableGen/Error.cpp

The net result is that in the old system running

ninja ./lib/TableGen/CMakeFiles/LLVMTableGen.dir/Error.cpp.o

on a tree just after running cmake would execute 91 commands to build
lib/libLLVMSupport.a and then Error.cpp.o. On the new system only one
command is executed :slight_smile:

In a more realistic situation, Error.cpp.o will be compiled in
parallel with the files needed to build lib/libLLVMSupport.a.

Cheers,
Rafael

Yep! This is awesome. I remember filing a CMake bug about this long ago, and it looks like this is the answer.

Rafael, thanks to explain with clear examples.

Although target_link_libraries(INTERFACE) can cut deps among
libraries, files in add_executable() will be still serialized.
For example,

build tools/clang/utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.o:
  CXX_COMPILER /home/chapuni/llvm-project/clang/utils/TableGen/TableGen.cpp

lib/libLLVMTableGen.a lib/libLLVMSupport.a

If TableGen.cpp would be made free from *.a, we should introduce
objlib stuff for add_executable().
See also my tddeps patch.

Thanks for the example. I reported
18990 – Unnecessary ordering dependencies in generated build.ninja to track this.

Cheers,
Rafael