Page MenuHome

CMake: proposal to conditionally link using generator expressions
Closed, ResolvedPublicDESIGN

Description

Motivation

Currently we have a quite kludgy solution for linking libraries, where we manually order library linking when building blender or blenderplayer.

This was originally done because library linking needed to conditionally use a stub, or the real library (for blenderplayer).

This task proposes to do things the *correct* way and use the target_link_libraries command (target-scoped conditions).

See: https://developer.blender.org/diffusion/B/browse/master/build_files/cmake/macros.cmake;56933373e29e1ed076bfb8ab4b50c447e66f00ff$497

The problem with this is we are having to guess the right linking order - for more complex cases, sometimes including the library multiple times... until it works,
Its quite haphazard and kludgey.
Its also not clear when looking at cmake files what links to what (though the includes give a reasonable explanation).

Solution

Modern CMake versions contain more APIs for target-scoped conditions and features. For example, we can link conditionally to one library or another depending on a property of the target being linked.

With C++ files with trivial implementations:

cmake_minimum_required(VERSION 3.1)
project(LinkConditions)

add_library(stubs stubs.cpp)
add_library(bf_editors bf_editors.cpp)

add_library(bikeshed_this_name INTERFACE)
target_link_libraries(bikeshed_this_name INTERFACE
  $<$<NOT:$<BOOL:$<TARGET_PROPERTY:USE_STUBS>>>:bf_editors>
  $<$<BOOL:$<TARGET_PROPERTY:USE_STUBS>>:stubs>
)

add_executable(blender blender.cpp)
target_link_libraries(blender bikeshed_this_name)

add_executable(blenderplayer blenderplayer.cpp)
target_link_libraries(blenderplayer bikeshed_this_name)
set_target_properties(blenderplayer PROPERTIES USE_STUBS ON)

When running ninja we see:

$ ninja -v
[1/8] /usr/lib/ccache/c++      -MMD -MT CMakeFiles/stubs.dir/stubs.cpp.o -MF CMakeFiles/stubs.dir/stubs.cpp.o.d -o CMakeFiles/stubs.dir/stubs.cpp.o -c ../stubs.cpp
[2/8] /usr/lib/ccache/c++      -MMD -MT CMakeFiles/bf_editors.dir/bf_editors.cpp.o -MF CMakeFiles/bf_editors.dir/bf_editors.cpp.o.d -o CMakeFiles/bf_editors.dir/bf_editors.cpp.o -c ../bf_editors.cpp
[3/8] : && /home/stephen/dev/prefix/qt/kde/bin/cmake -E remove libstubs.a && /usr/bin/ar qc libstubs.a  CMakeFiles/stubs.dir/stubs.cpp.o && /usr/bin/ranlib libstubs.a && :
[4/8] : && /home/stephen/dev/prefix/qt/kde/bin/cmake -E remove libbf_editors.a && /usr/bin/ar qc libbf_editors.a  CMakeFiles/bf_editors.dir/bf_editors.cpp.o && /usr/bin/ranlib libbf_editors.a && :
[5/8] /usr/lib/ccache/c++      -MMD -MT CMakeFiles/blender.dir/blender.cpp.o -MF CMakeFiles/blender.dir/blender.cpp.o.d -o CMakeFiles/blender.dir/blender.cpp.o -c ../blender.cpp
[6/8] /usr/lib/ccache/c++      -MMD -MT CMakeFiles/blenderplayer.dir/blenderplayer.cpp.o -MF CMakeFiles/blenderplayer.dir/blenderplayer.cpp.o.d -o CMakeFiles/blenderplayer.dir/blenderplayer.cpp.o -c ../blenderplayer.cpp
[7/8] : && /usr/lib/ccache/c++      CMakeFiles/blender.dir/blender.cpp.o  -o blender  -rdynamic libbf_editors.a && :
[8/8] : && /usr/lib/ccache/c++      CMakeFiles/blenderplayer.dir/blenderplayer.cpp.o  -o blenderplayer  -rdynamic libstubs.a && :

and as the last two lines show, we have linked to the libbf_editors or the libstubs as desired.

This could be used to simplify the cmake buildsystem somewhat.

So we could use a command for eg:

target_link_libraries(
    bf_rna INTERFACE
    $<$<NOT:$<BOOL:$<TARGET_PROPERTY:USE_STUBS>>>:bf_editors>
    $<$<BOOL:$<TARGET_PROPERTY:USE_STUBS>>:stub>
)

Note that while quite verbose, this would only be needed for the few libraries which the Game engine stubs out.

Steps to implement

These are the proposed steps:

  • Add a library argument to blender_add_lib (which will be passed to target_link_libraries within the function), eg: blender_add_lib(bf_python_bmesh "${SRC}" "${INC}" "${INC_SYS}" $"{LIB}")
  • Remove BLENDER_SORTED_LIBS from macros.cmake
  • Use target-scoped conditions for the cases they're needed.

Revisions and Commits

Event Timeline

Stephen Kelly (steveire) raised the priority of this task from to 90.
Stephen Kelly (steveire) updated the task description. (Show Details)
Stephen Kelly (steveire) edited a custom field.
Campbell Barton (campbellbarton) renamed this task from Link conditionally with cmake generator expressions to CMake: proposal to conditionally link using generator expressions.Nov 8 2015, 5:04 PM
Campbell Barton (campbellbarton) lowered the priority of this task from 90 to Low.

Note, I had a patch for listing libs in each CMake file (along with source and includes), committed to a temp branch.
https://developer.blender.org/rBS71a1c7ab1d316bea90f19b9061af0d50543e50e0

hewi added a subscriber: hewi.Nov 9 2015, 3:29 PM
Campbell Barton (campbellbarton) changed the task status from Unknown Status to Resolved.Apr 16 2019, 4:59 PM
hewi removed a subscriber: hewi.May 2 2019, 8:45 AM