File: DefineLinkerScript.cmake

package info (click to toggle)
llvm-toolchain-11 1%3A11.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 995,808 kB
  • sloc: cpp: 4,767,656; ansic: 760,916; asm: 477,436; python: 170,940; objc: 69,804; lisp: 29,914; sh: 23,855; f90: 18,173; pascal: 7,551; perl: 7,471; ml: 5,603; awk: 3,489; makefile: 2,573; xml: 915; cs: 573; fortran: 503; javascript: 452
file content (55 lines) | stat: -rw-r--r-- 2,259 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# This function defines a linker script in place of the symlink traditionally
# created for shared libraries.
#
# More specifically, this function goes through the PUBLIC and INTERFACE
# library dependencies of <target> and gathers them into a linker script,
# such that those libraries are linked against when the shared library for
# <target> is linked against.
#
# Arguments:
#   <target>: A target representing a shared library. A linker script will be
#             created in place of that target's TARGET_LINKER_FILE, which is
#             the symlink pointing to the actual shared library (usually
#             libFoo.so pointing to libFoo.so.1, which itself points to
#             libFoo.so.1.0).

function(define_linker_script target)
  if (NOT TARGET "${target}")
    message(FATAL_ERROR "The provided target '${target}' is not actually a target.")
  endif()

  get_target_property(target_type "${target}" TYPE)
  if (NOT "${target_type}" STREQUAL "SHARED_LIBRARY")
    message(FATAL_ERROR "The provided target '${target}' is not a shared library (its type is '${target_type}').")
  endif()

  set(symlink "$<TARGET_LINKER_FILE:${target}>")
  set(soname "$<TARGET_SONAME_FILE_NAME:${target}>")

  get_target_property(interface_libs "${target}" INTERFACE_LINK_LIBRARIES)

  set(link_libraries)
  if (interface_libs)
    foreach(lib IN LISTS interface_libs)
      if ("${lib}" STREQUAL "cxx-headers")
        continue()
      endif()
      if (TARGET "${lib}" OR
          (${lib} MATCHES "cxxabi(_static|_shared)?" AND HAVE_LIBCXXABI) OR
          (${lib} MATCHES "unwind(_static|_shared)?" AND HAVE_LIBUNWIND))
        list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:${lib},OUTPUT_NAME>")
      else()
        list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${lib}")
      endif()
    endforeach()
  endif()
  string(REPLACE ";" " " link_libraries "${link_libraries}")

  set(linker_script "INPUT(${soname} ${link_libraries})")
  add_custom_command(TARGET "${target}" POST_BUILD
    COMMAND "${CMAKE_COMMAND}" -E remove "${symlink}"
    COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "${symlink}"
    COMMENT "Generating linker script: '${linker_script}' as file ${symlink}"
    VERBATIM
  )
endfunction()