Getting All Library Dependencies


I’ll try my best to describe my issue.

I’m in a situation where our current build system uses a script that generates C++ code. I have this process completed in CMake. But the difficult part, is that the code generation script needs to know what libraries are being used in order to generate the proper code.

So, let’s say there are four libraries. A, B, C, D.

Library A exists on its own.
Library B exists on its own.
Library C uses library B.
Library D uses C and A.

If I build an executable that links against library D, then I need the build script to know about A, B, C and D.
However, I want the developer writing this executable to only have to link against D. As far as the executable is concerned, it only needs to link against D.

My goal is to add properties to the targets. So, the executable links against D, but the under the hood we examine D’s dependencies for the code generation.

The confusion for me comes in with order of evaluation.
I need library D to know that C uses library A. But, if D is evaluated before C, will CMake even know that C relies on A?

There is an issue somewhere (that I can’t find right now) about getting the transitive closure of a target’s dependencies. It doesn’t exist yet. However, what are you trying to do; there may be another way.

What other way are you thinking?

I didn’t know the phrase I was looking for is the “transitive closure of a target’s dependencies”. But, it sounds like that’s what I’m looking for. We have a set of special libraries that are distinguished from others. These special library names have to be exported to an in-house python script that generates some other class definitions and stuff.

The long term goal is to fix how this entire setup is accomplished, but we’re migrating build systems first. The script needs to know every one of these special libraries in order to generate the appropriate code.

So in this example, the code generation script needs to know of all the libraries to generate appropriate code. Worst case, I’ll just have to set these in variables. In our current in-house build system, we have to manually list all dependencies, but this is something I’m trying to fix while redoing the build system into CMake.

My specific current approach is to write a wrapper around add_executable and add_library.

The add_executable() wrapper initially took a multi value argument of these special libraries, called add_library internally, and then grabbed all of the special libraries from other library. The external build script is then called.

I’m working on testing this, but I don’t know what the outcome will be if CMake hasn’t evaluated all of the special libraries by this point.

That would depend on the end goal…

But why? What is the generated code accomplishing?

I don’t think I’m allowed to say why.

The script generates some header files and some source files. This becomes a library. And then multiple other executable or libraries will link against this library.

That’s fine…but this information just isn’t generically available in CMake. I suspect there’s something else going on, but it’s hard to suggest a way forward without more details.

So, I actually ended up getting this implemented in CMake. The approach overall wasn’t as complicated as I thought. Essentially, I added a custom property to all internal libraries called specialLinkedLibraries. Then, we have wrapper functions for linking. When linking, I append $<TARGET_PROPERTY:${library}, specialLinkedLibraries> to the target library. Then, this all gets resolved at build time. Then, I’m able to call our python script that generates the new library and link it.