How to force the order of target builds in CMake

Viewed 2218

I've just inherited a terrible mess of projects built with CMake. I have zero CMake knowledge and I suspect the previous maintainer had just as much.

I need to force the build order between projects. It used to be:

=== BUILD TARGET foo1 OF PROJECT bar ...
=== BUILD TARGET foo2 OF PROJECT bar ...
=== BUILD TARGET foo3 OF PROJECT bar ...

I had to add a project and dependencies (in different targets not the ones above). But the code is riddled with

# don't change the library order, it will break xyz  
target_link_libraries(foo3 other1 foo2 other2 foo1 other3)

As you can guess, after my changes, I now get

=== BUILD TARGET foo1 OF PROJECT bar ...
=== BUILD TARGET foo3 OF PROJECT bar ...

And foo3 doesn't build due to foo2 headers not being copied/installed/whatever. I'm pretty sure that if I could force CMake to trigger foo2 before foo3 the issue would be resolved.

However, I tried:

target_link_libraries(foo3 foo2)

to no avail. I still see foo3 trigger before foo2.

I also tried

add_dependencies(foo3 foo2)

So, my questions:

  • Can I see the dependency graph that CMake must be building internally ?
  • If there happened to be a cycle somewhere, how would I know and find it ?
  • Can I force the order of target builds ?
  • Is there any other gotchas around build order ?
1 Answers

CMake is a declarative build system.

While the cmake program you write in the CMakeLists.txt files is executed pure imperative the build system it builds is declarative.

This means you can't control the build order of targets. You specify what you want get done but not how it will be done. Thats abstracted away.

The only way is to add dependencies in the targets. First all dependency target are build before the depending target is build.

You add dependencies via commands like "target_link_libraries" and "target_sources". You can use the very general "add_dependencies" to add more that are not basic C/C++ programming relevant files.

Related