blob: 41426bf0671498613b5c06a8df9d2e22497efc19 [file] [log] [blame]
Louis Dionnedb7d4c52019-10-08 21:10:20 +00001# 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)
Louis Dionne2422a9f2020-06-26 16:05:55 -040034 if ("${lib}" STREQUAL "cxx-headers")
35 continue()
36 endif()
Louis Dionne8a51e952019-10-11 14:42:26 -040037 set(libname "$<IF:$<TARGET_EXISTS:${lib}>,$<TARGET_PROPERTY:${lib},OUTPUT_NAME>,${lib}>")
38 list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${libname}")
Louis Dionnedb7d4c52019-10-08 21:10:20 +000039 endforeach()
40 endif()
Louis Dionnee3f002f2019-10-08 21:33:35 +000041 string(REPLACE ";" " " link_libraries "${link_libraries}")
Louis Dionnedb7d4c52019-10-08 21:10:20 +000042
43 set(linker_script "INPUT(${soname} ${link_libraries})")
44 add_custom_command(TARGET "${target}" POST_BUILD
45 COMMAND "${CMAKE_COMMAND}" -E remove "${symlink}"
46 COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "${symlink}"
47 COMMENT "Generating linker script: '${linker_script}' as file ${symlink}"
48 VERBATIM
49 )
50endfunction()