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).
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.