Usage requirement to update direct link dependencies
CMake computes the link line of a target as follows:
- Start with items in the
LINK_LIBRARIESproperty of the target itself.
- For each of those items that is a target, follow the transitive closure of its
- Append items found in the link interface closures needed for dependencies not satisfied by the original
LINK_LIBRARIESlist. Add them in an order that respects their dependencies.
The real implementation is a bit more complicated to handle inferred dependencies of non-target items, but the above is the gist of the logic for targets.
Note that the last step only ever appends to the original
LINK_LIBRARIES. It never inserts among them. This gives projects some control over their link order. However, it does not support a case Qt has for static plugin injection:
Qt plugin injection that causes circular dependency
# Core library used by other components. add_library(Core STATIC core.cpp) # Gui is a static library for use by applications. add_library(Gui STATIC gui_plugin_helper.cpp gui_building_block.cpp) target_link_libraries(Gui PRIVATE Core) # Extra parts of Gui for use by its static plugins. add_library(GuiExtras STATIC gui_extras.cpp) target_link_libraries(GuiExtras PRIVATE Core Gui) # The Gui library has associated static plugins that should be linked into the final executable. add_library(gui_plugin STATIC gui_plugin.cpp) # The plugins depend on some functions in Gui and other libraries. target_link_libraries(gui_plugin PRIVATE Core Gui GuiExtras) # Any application that links Gui should automatically get its plugins. target_link_libraries(Gui INTERFACE gui_plugin) # An application only specifies linking to the Gui static library. add_executable(app main.cpp) target_link_libraries(app PRIVATE Gui)
The resulting link line for
-o app libGui.a libgui_plugin.a libGuiExtras.a libGui.a libgui_plugin.a libGuiExtras.a libCore.a
The reason for the repetition is that the link dependency graph contains a cycle between
INTERFACE_LINK_LIBRARIES specifies the other. This results in inefficient linker operation,
and in more complex cases possibly incorrect library ordering.
If we instead modify the example to link
app directly to
-# Any application that links Gui should automatically get its plugins. -target_link_libraries(Gui INTERFACE gui_plugin) - -# An application only specifies linking to the Gui static library. add_executable(app main.cpp) -target_link_libraries(app PRIVATE Gui) +target_link_libraries(app PRIVATE gui_plugin)
Then the resulting link line for
app references every library once in the desired order:
-o app libgui_plugin.a libGuiExtras.a libGui.a libCore.a
However, it is not practical for Qt to ask application authors to manually do this.
We need a way to specify this as a usage requirement of
To solve this, we'll need some way for a usage requirement to modify behavior of the first step: to add/remove the initial list of items taken from
LINK_LIBRARIES. In the above Qt case,
Gui needs to be able to specify usage requirements that say:
applinked directly to
appdid not link directly to
Gui(except to propagate this requirement)"