1# This function defines a linker script in place of the symlink traditionally 2# created for shared libraries. 3# 4# More specifically, this function goes through the PUBLIC and INTERFACE 5# library dependencies of <target> and gathers them into a linker script, 6# such that those libraries are linked against when the shared library for 7# <target> is linked against. 8# 9# Arguments: 10# <target>: A target representing a shared library. A linker script will be 11# created in place of that target's TARGET_LINKER_FILE, which is 12# the symlink pointing to the actual shared library (usually 13# libFoo.so pointing to libFoo.so.1, which itself points to 14# libFoo.so.1.0). 15 16function(define_linker_script target) 17 if (NOT TARGET "${target}") 18 message(FATAL_ERROR "The provided target '${target}' is not actually a target.") 19 endif() 20 21 get_target_property(target_type "${target}" TYPE) 22 if (NOT "${target_type}" STREQUAL "SHARED_LIBRARY") 23 message(FATAL_ERROR "The provided target '${target}' is not a shared library (its type is '${target_type}').") 24 endif() 25 26 set(symlink "$<TARGET_LINKER_FILE:${target}>") 27 set(soname "$<TARGET_SONAME_FILE_NAME:${target}>") 28 29 get_target_property(interface_libs "${target}" INTERFACE_LINK_LIBRARIES) 30 31 set(link_libraries) 32 if (interface_libs) 33 foreach(lib IN LISTS interface_libs) 34 if ("${lib}" STREQUAL "cxx-headers") 35 continue() 36 endif() 37 if (TARGET "${lib}" OR 38 (${lib} MATCHES "cxxabi(_static|_shared)?" AND HAVE_LIBCXXABI) OR 39 (${lib} MATCHES "unwind(_static|_shared)?" AND HAVE_LIBUNWIND)) 40 list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:${lib},OUTPUT_NAME>") 41 else() 42 list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${lib}") 43 endif() 44 endforeach() 45 endif() 46 string(REPLACE ";" " " link_libraries "${link_libraries}") 47 48 set(linker_script "INPUT(${soname} ${link_libraries})") 49 add_custom_command(TARGET "${target}" POST_BUILD 50 COMMAND "${CMAKE_COMMAND}" -E remove "${symlink}" 51 COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "${symlink}" 52 COMMENT "Generating linker script: '${linker_script}' as file ${symlink}" 53 VERBATIM 54 ) 55endfunction() 56