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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#
# - This module provides the function
# itk_target_link_libraries_with_dynamic_lookup which can be used to
# "weakly" link loadable module.
#
# Link a library to a target such that the symbols are resolved at
# run-time not link-time. This should be used when compiling a
# loadable module when the symbols should be resolve from the run-time
# environment where the module is loaded, and not a specific system
# library.
#
# Specifically, for OSX it uses undefined dynamic_lookup. This is
# similar to using "-shared" on Linux where undefined symbols are
# ignored.
#
# Additionally, the linker is checked to see if it supports undefined
# symbols when linking a shared library. If it does then the library
# is not linked when specified with this function.
#
# https://blog.tim-smith.us/2015/09/python-extension-modules-os-x/
#
# Function: _itkCheckUndefinedSymbolsAllowed
#
# Check if the linker allows undefined symbols for shared libraries.
#
# ITK_UNDEFINED_SYMBOLS_ALLOWED - true if the linker will allow
# undefined symbols for shared libraries
#
function(_itkCheckUndefinedSymbolsAllowed)
set(VARIABLE "ITK_UNDEFINED_SYMBOLS_ALLOWED")
set(cache_var "${VARIABLE}_hash")
# hash the CMAKE_FLAGS passed and check cache to know if we need to rerun
string(MD5 cmake_flags_hash "${CMAKE_SHARED_LINKER_FLAGS}")
if(NOT DEFINED "${cache_var}")
unset("${VARIABLE}" CACHE)
elseif(
NOT
"${${cache_var}}"
STREQUAL
"${cmake_flags_hash}")
unset("${VARIABLE}" CACHE)
endif()
if(NOT DEFINED "${VARIABLE}")
set(test_project_dir "${PROJECT_BINARY_DIR}/CMakeTmp/${VARIABLE}")
file(
WRITE "${test_project_dir}/CMakeLists.txt"
"
cmake_minimum_required(VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})
project(undefined C)
add_library(foo SHARED \"foo.c\")
")
file(
WRITE "${test_project_dir}/foo.c"
"
extern int bar(void);
int foo(void) {return bar()+1;}
")
# APPLE: the CMAKE_MACOSX_RPATH flag should be passed.
if(APPLE)
set(_rpath_arg "-DCMAKE_MACOSX_RPATH='${CMAKE_MACOSX_RPATH}'")
else()
set(_rpath_arg)
endif()
try_compile(
${VARIABLE} "${test_project_dir}"
"${test_project_dir}" undefined
CMAKE_FLAGS "-DCMAKE_SHARED_LINKER_FLAGS='${CMAKE_SHARED_LINKER_FLAGS}'" ${_rpath_arg}
OUTPUT_VARIABLE output)
set(${cache_var}
"${cmake_flags_hash}"
CACHE INTERNAL "hashed try_compile flags")
if(${VARIABLE})
message(STATUS "Performing Test ${VARIABLE} - Success")
else()
message(STATUS "Performing Test ${VARIABLE} - Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Test ${VARIABLE} failed with the following output:\n" "${OUTPUT}\n")
endif()
endif()
endfunction()
_itkcheckundefinedsymbolsallowed()
macro(itk_target_link_libraries_with_dynamic_lookup target)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set_target_properties(${target} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
elseif(ITK_UNDEFINED_SYMBOLS_ALLOWED)
# linker allows undefined symbols, let's just not link
else()
target_link_libraries(${target} ${ARGN})
endif()
endmacro()
|