How to solve the circular dependency between the static library and object library
Hi in our code we have a situation that is reproduced in the attached test project.
The idea is that we have the following dependency graph:
commonlib <--- objlib <--- staticplugin <--- dummy <--- test_static_linking_order_cmake
^ |____________^ |
|_____________________________|
So the expected linker line for this situation should be either:
# Solution 1
... objlib.o -o test_static_linking_order_cmake libdummy.a libstaticplugin.a libcommonlib.a
or:
# Solution2
... -o test_static_linking_order_cmake libdummy.a objlib.o libstaticplugin.a libcommonlib.a
Both solutions have limitations that we are not able to handle correctly(in a common way). Do you have any suggestions on how we could solve this? test_static_linking_order_cmake.tar.gz
The rationale of the structure is following:
commonlib - contains symbols that are widely used across project (in our case it's libQtCore.a)
staticplugin - is the Qml plugin with pre-compiled Qml files.
objlib - the resource object library, that relies on symbols from the libQtCore.a library and the Qml plugin. The reason for using it as an object library is a global constructor that initializes resources and exposes precompiled Qml classes for the user-space executable. In the resource initializer, we also have direct calls of the functions from the Qml plugin related to the pre-compiled Qml files. This circular dependency is implemented in the test project as well, look at objlibFunc2 and staticpluginFunc2.
dummy - might be either Qt or user-space Qml plugin that uses Qml classes from the staticplugin
test_static_linking_order_cmake - end-point executable. We need to guarantee that objlib.cpp.o is linked to it directly.
Our investigations end up with two solutions that are commented in the test project:
-
Using the target_sources(... INTERFACE ...) call to propagate the resource object library objects. This obligates us and users to use either the PUBLIC linking or a combination of the PRIVATE and INTERFACE linking between static libraries since the pure PRIVATE linking doesn't provide the transitive propagation of resource objects to the end-point executable.
-
Linking of the static library that propagates the resource objects to itself using the $<TARGET_LINKER_FILE:> genex. This solution only works correctly in the test project, but when we apply it to Qt, it causes issues because of higher level circular dependencies and linking against libraries using INTERFACE_LINK_LIBRARIES property. It also may cause issues after installation, but unfortunately we didn't go that deep with this solution.