Вам необходимо передать параметр --whole-archive
компоновщику. В CMake вы можете сделать это следующим образом.
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
add_library(unit1 STATIC unit1.c)
target_compile_options(unit1 PRIVATE -fPIC)
add_library(unit2 STATIC unit2.c)
target_compile_options(unit2 PRIVATE -fPIC)
add_library(merged SHARED)
set_target_properties(merged PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(merged
"-Wl,--whole-archive libunit1.a libunit2.a -Wl,--no-whole-archive"
unit1 unit2
)
Примечание. Команда target_link_libraries
может использоваться также для указания флагов компоновщика, а не только имен библиотек. Кавычки важны, в противном случае CMake может переставить флаги и удалить дубликаты.
Экспортируемые символы
$ nm libmerged.so | grep " T "
000000000000065d T GoodbyeWorld
000000000000064a T HelloWorld
0000000000000670 T _fini
0000000000000520 T _init
Другой вариант, чтобы избежать проблемы, - создать OBJECT
вместо STATIC
библиотек для unit1
и unit2
.
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
add_library(unit1 OBJECT unit1.c)
target_compile_options(unit1 PRIVATE -fPIC)
add_library(unit2 OBJECT unit2.c)
target_compile_options(unit2 PRIVATE -fPIC)
add_library(merged SHARED $<TARGET_OBJECTS:unit1> $<TARGET_OBJECTS:unit2>)
set_target_properties(merged PROPERTIES LINKER_LANGUAGE C)