I have an executable built from several object files and linked with several static and shared libraries. I want to specify -Wl,-whole-archive linker option to one of linked libraries.
For example, from this command:
/usr/bin/c++ _objectFiles_ -o _myExec_ _someCommonOptions_ _myLibraries_ -Wl,-rpath _path to libs_
I want to get this command:
/usr/bin/c++ _objectFiles_ -o _myExec_ _someCommonOptions_ _allOtherLibs_ \
-Wl,-whole-archive _one particular lib_ -Wl,-no_whole-archive -Wl,-rpath _path to libs_
Is it any way I can achieve this using cmake? As I understand when I add something like
set_target_properties(myExec PROPERTIES LINK_FLAGS "-Wl,-whole-archive")
then -whole-archive
options is set for all linked libraries and this is definitely not what I want.
Thank you.
Yes, the Core and Utils code will be duplicated. Instead of building them as static libs you can build them as dlls and use anywhere.
Static Linking and Static Libraries is the result of the linker making copy of all used library functions to the executable file. Static Linking creates larger binary files, and need more space on disk and main memory.
You can't statically link a shared library (or dynamically link a static one). The flag -static will force the linker to use static libraries (. a) instead of shared (. so) ones.
This thread Linking static libraries into shared libs? has a method for that.
SET (MYLIB -Wl,--whole-archive my_particular_lib -Wl,--no-whole-archive)
....
TARGET_LINK_LIBRARIES(yourtarget ${normalstuff} ${MYLIB} ${othernormalstuff})
The CMake docs state:
If a library name matches that of another target in the project a dependency will automatically be added in the build system to make sure the library being linked is up-to-date before the target links. Item names starting with '-', but not '-l' or '-framework', are treated as linker flags.
So the -Wl
options should not interfere/be touched by CMake.
TARGET_LINK_LIBRARIES(myTarget -Wl,--whole-archive myLib -Wl,--no-whole-archive)
Simply replace myTarget
and myLib
Oryginal post: https://stackoverflow.com/a/37564428/1052261
As @RichvonLehe points out, the proposed solution may not work if you have multiple libraries. CMake treats -Wl,--whole-archive my_particular_lib -Wl,--no-whole-archive
as 3 separate libraries, and makes no guarantees about ordering. In my particular case, I found that I ended up having a bunch of other archives being included between the -Wl,--whole-archive
and -Wl,--no-whole-archive
flags, resulting in duplicate symbol definitions.
Unfortunately, you also may not be able to wrap everything in quotes. If you do -Wl,--whole-archive,$<TARGET_FILE:my_particular_lib>,--no-whole-archive
or similar you'll find that CMAKE stops treating my_particular_lib as a symbolic target and instead just treats the whole string as a link flag. If my_particular_lib happens to have other CMake side-effects, such as target_include_directories() or in my case, PUBLIC HEADERS, they will cease to be included.
Ultimately I had to resort to a layer of indirection. The trick is to use an INTERFACE library as the top level thing. Use one library (my_lib_part_1) to dangle all of the properties that I needed to be transitively inherited by other targets, such as PUBLIC HEADERS, and another library (my_lib_part_2) that emphatically does not have any properties that needed to be inherited and only vends the .a archive.
Even this is lacking. CMake makes it difficult to have empty STATIC libraries and does not allow you to put PUBLIC HEADERS on INTERFACE libraries (yet?).
add_library(my_lib INTERFACE)
add_library(my_lib_part_1 STATIC
foo.cpp
)
add_library(my_lib_part_2 STATIC
bar.cpp
)
target_link_libraries(my_lib
INTERFACE
my_lib_part_1
# It is very important this is in quotes so CMake treats it as a single flag
"-Wl,--whole-archive $<TARGET_FILE:my_lib_part_2> -Wl,--no-whole-archive"
)
set_target_properties(my_lib_part_1 PROPERTIES
PUBLIC_HEADER "my_public_header.hpp"
)
set_target_properties(my_lib_part_2 PROPERTIES
POSITION_INDEPENDENT_CODE ON
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With