Allow using external static libraries with BUILD_SHARED_LIBS=ON

Previously, this failed if one dependency was a static library compiled
without -fPIC. This is is the case for library libsuitesparseconfig on
Debian which has no dynamic alternative. The error messages read e.g.

```
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libsuitesparseconfig.a(SuiteSparse_config.o): relocation R_X86_64_PC32 against undefined symbol `malloc@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
```

With this patch we change the target_link_libraries call when using
BUILD_SHARED_LIBS=ON. We only pass the dynamic libraries as PUBLIC such
that they will get linked to the library. The static ones are passed as
INTERFACE libraries. This means that they will be automatically linked
to executables which link to the main library. Currently this transitive
linking will only work in the same module as we do not correctly export
libraries. But our build system explicitly links the others ones anyway.
This commit is contained in:
Markus Blatt 2017-05-18 20:37:31 +02:00
parent a7402e5720
commit cd4c0f54fb

View File

@ -30,14 +30,28 @@ macro (opm_compile opm)
add_definitions (${${opm}_DEFINITIONS})
set (${opm}_VERSION "${${opm}_VERSION_MAJOR}.${${opm}_VERSION_MINOR}")
if (${opm}_SOURCES)
add_library (${${opm}_TARGET} ${${opm}_LIBRARY_TYPE} ${${opm}_SOURCES})
set_target_properties (${${opm}_TARGET} PROPERTIES
SOVERSION ${${opm}_VERSION_MAJOR}
VERSION ${${opm}_VERSION}
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
add_library (${${opm}_TARGET} ${${opm}_LIBRARY_TYPE} ${${opm}_SOURCES})
set_target_properties (${${opm}_TARGET} PROPERTIES
SOVERSION ${${opm}_VERSION_MAJOR}
VERSION ${${opm}_VERSION}
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
POSITION_INDEPENDENT_CODE TRUE
)
target_link_libraries (${${opm}_TARGET} ${${opm}_LIBRARIES})
if (${${opm}_LIBRARY_TYPE} STREQUAL "SHARED")
# libs that will be linked with the main lib
string(REGEX REPLACE "([;^])[^;]+\\.a[;$]" "\\1" _public_libs
"${${opm}_LIBRARIES}")
# libs that will not actually linked to the library but
# transitively linked to binaries that link to the main library
string(REGEX REPLACE "([^;]+\\.[^a][a-zA-Z0-9]*|-[a-z]*)[;$]" "" _interface_libs
"${${opm}_LIBRARIES}")
else()
# Use all libs for real and transitive linking
set(_public_libs ${${opm}_LIBRARIES})
unset(_interface)
endif()
target_link_libraries (${${opm}_TARGET} PUBLIC ${_public_libs}
INTERFACE ${_interface_libs})
if (STRIP_DEBUGGING_SYMBOLS)
# queue this executable to be stripped