DefineLinkerScript.cmake 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. function(define_linker_script target)
  16. if (NOT TARGET "${target}")
  17. message(FATAL_ERROR "The provided target '${target}' is not actually a target.")
  18. endif()
  19. get_target_property(target_type "${target}" TYPE)
  20. if (NOT "${target_type}" STREQUAL "SHARED_LIBRARY")
  21. message(FATAL_ERROR "The provided target '${target}' is not a shared library (its type is '${target_type}').")
  22. endif()
  23. set(symlink "$<TARGET_LINKER_FILE:${target}>")
  24. set(soname "$<TARGET_SONAME_FILE_NAME:${target}>")
  25. get_target_property(interface_libs "${target}" INTERFACE_LINK_LIBRARIES)
  26. set(link_libraries)
  27. if (interface_libs)
  28. foreach(lib IN LISTS interface_libs)
  29. if (TARGET "${lib}" OR
  30. (${lib} MATCHES "cxxabi(_static|_shared)?" AND HAVE_LIBCXXABI) OR
  31. (${lib} MATCHES "unwind(_static|_shared)?" AND HAVE_LIBUNWIND))
  32. list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:${lib},OUTPUT_NAME>")
  33. else()
  34. list(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}${lib}")
  35. endif()
  36. endforeach()
  37. endif()
  38. string(REPLACE ";" " " link_libraries "${link_libraries}")
  39. set(linker_script "INPUT(${soname} ${link_libraries})")
  40. add_custom_command(TARGET "${target}" POST_BUILD
  41. COMMAND "${CMAKE_COMMAND}" -E remove "${symlink}"
  42. COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "${symlink}"
  43. COMMENT "Generating linker script: '${linker_script}' as file ${symlink}"
  44. VERBATIM
  45. )
  46. endfunction()