Hey CMake community,
I’m trying to figure out how to encapsulate linker flags in one of the subdirectories of my cmake project. Is there a way for be to set link flags on a target so that when it is linked against, those flags are added to the link command? Specifically by wrapping the target library with -Wl
flags?
I have a rather large, overly complicated build that I’m trying to clean up a little bit by encapsulating some of the build components into their own cmake. At first I was defining object libraries, but I found the use of target_include_directories
and target_link_libraries
very convenient for defining those things on static libraries.
I have one component that defines symbols that need to be kept in the final binary (dynamic library) because they’re JNI symbols and even though they aren’t referenced in c++ code, they will be used by java code. Those symbols are defined in one component that is now being linked as a static library. Without additional flags, all those JNI symbols get stripped out when doing the final link. Furthermore that library has other dependencies that don’t need to be forced to be in the final binary.
The solution I’ve found with my current structure is the following
add_subdirectory(jni_component_dir)
add_library(final_lib SHARED ${final_lib_src})
target_link_libraries(final_lib
-Wl,-whole-archive
jni_component
-Wl,-no-whole-archive
... other libs too ... )
With this structure the linker command looks like ld ... -whole-archive jni_component -no-whole-archive dep1 dep2 ...
. Hopefully you get the idea.
This actually works, but now I wonder if I can move this awareness to the jni directory itself. Afterall, that component is responsible for knowing if it has “unused” symbols that need to be kept.
If I try to move the linker flags to the subdirectory then I get something more akin to this:
add_library(jni_component_helper STATIC ${jni_src})
target_link_libraries(jni_component_helper dep1 dep2)
add_library(jni_component STATIC "")
target_link_libraries(jni_component
-Wl,-whole-archive
jni_component_helper
-Wl,-no-whole-archive)
which produces ld ... -whole-archive jni_component jni_compent_depa dep1 dep2 dep1_dep -no-whole-archive ...
and ultimately gives me link errors with duplicate symbols.
What I want is something similar to this but without all the dependent libraries getting pulled into that link commands. It seems like subdirectories imposes some sort of boundary where the link flags are treated differently. Is there any way to impose this kind of boundary on a target without requiring another subdirectory? Furthermore, is there any way to componentize this without cluttering the top-level cmake?