How to add dependencies to an object library [for ninja generator]?

The full source and cmake files can be found in this issue.
Ninja: Cannot create dependency of an object library (#24411) · Issues · CMake / CMake · GitLab (kitware.com)

add_library(main OBJECT main.cpp)
target_link_libraries(main a)
add_dependencies(main a)

Neither target_link_libraries(main a) nor add_dependencies(main a) can request compilation a when compiling main.

  1. How do I create dependencies for the object library in the ninja generator?
  2. The ninja generator does this and the makefile generator does not, is this expected?

What is the use case for having a’s objects compile when requesting main? Nothing actually requires them to be there (as there is no linking step).

Thanks, I was just about to ask the cmake experts for help with my needs.

My original requirement is that I want to add a lightweight check target to my c++ repository: compile only, not link, or even use -fsyntax-only at compile time, without generating targets. (similar to rust’s cargo check)

Suppose the original final target is main, and main depends on a and b; a depends on c and d.

Consider writing a macro or function create_shadow_target(X)

It does the following:

  1. create a target named X_shadow, type is object library
  2. target_compile_options(X_shadow PRIVATE -fsyntax-only)
  3. The direct source of X_shadow is the same as X.
  4. for each library A linked by X.
    a. Perform this procedure recursively, generating A_shadow;
    b. Force a dependency between X_shadow and A_shadow
    c. Make X_shadow obtain A_shadow’s headers, and public dependencies
    target_include_directories(X_shadow PRIVATE $<TARGET_PROPERTY:A_shadow,INTERFACE_INCLUDE_DIRECTORIES>)

Then just generate the main_shadow target and run it.

now I can’t do 4.b because I can’t add dependencies to the object library.

and do you have any suggestions for other parts?

I think for 4.c, you can use $<TARGET_PROPERTY:X,INCLUDE_DIRECTORIES> and get the transitive closure automatically and not need to do the shallow traversal yourself.

For 4.b, I think, in general, you want to depend on A directly because you may need a generated header that is attached to a custom command there. Which is actually the case for X as well, so you actually want X_shadow to depend on X here. If you know you don’t have such things, can you instead just make a purely shadow graph (with no links to the normal graph) and wrap it up with a shadow custom target that depends on all of them? In that case, I don’t think you need the intra-shadow dependencies either for that matter.

You can add dependencies, but any link requirements cannot be drawn because there is no “link” node to draw them to (there is an overall target node, but I think we didn’t give it link semantics explicitly).