chiark / gitweb /
CMake: Set CPACK variables in cache
[nlopt.git] / cmake / TargetLinkLibrariesWithDynamicLookup.cmake
1 #
2 # - This module provides the function
3 # target_link_libraries_with_dynamic_lookup which can be used to
4 # "weakly" link loadable module.
5 #
6 # Link a library to a target such that the symbols are resolved at
7 # run-time not link-time. This should be used when compiling a
8 # loadable module when the symbols should be resolve from the run-time
9 # environment where the module is loaded, and not a specific system
10 # library.
11 #
12 # Specifically, for OSX it uses undefined dynamic_lookup. This is
13 # similar to using "-shared" on Linux where undefined symbols are
14 # ignored.
15 #
16 # Additionally, the linker is checked to see if it supports undefined
17 # symbols when linking a shared library. If it does then the library
18 # is not linked when specified with this function.
19 #
20 # http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/
21 #
22
23 # Function: _CheckUndefinedSymbolsAllowed
24 #
25 # Check if the linker allows undefined symbols for shared libraries.
26 #
27 # UNDEFINED_SYMBOLS_ALLOWED - true if the linker will allow
28 #   undefined symbols for shared libraries
29 #
30
31 function(_CheckUndefinedSymbolsAllowed)
32
33   set(VARIABLE "UNDEFINED_SYMBOLS_ALLOWED")
34   set(cache_var "${VARIABLE}_hash")
35
36
37   # hash the CMAKE_FLAGS passed and check cache to know if we need to rerun
38   string(MD5 cmake_flags_hash "${CMAKE_SHARED_LINKER_FLAGS}")
39
40   if(NOT DEFINED "${cache_var}" )
41     unset("${VARIABLE}" CACHE)
42   elseif(NOT "${${cache_var}}" STREQUAL "${cmake_flags_hash}" )
43     unset("${VARIABLE}" CACHE)
44   endif()
45
46   if(NOT DEFINED "${VARIABLE}")
47     set(test_project_dir "${PROJECT_BINARY_DIR}/CMakeTmp/${VARIABLE}")
48
49     file(WRITE "${test_project_dir}/CMakeLists.txt"
50 "
51 project(undefined C)
52 add_library(foo SHARED \"foo.c\")
53 ")
54
55     file(WRITE "${test_project_dir}/foo.c"
56 "
57 extern int bar(void);
58 int foo(void) {return bar()+1;}
59 ")
60
61     if(APPLE AND ${CMAKE_VERSION} VERSION_GREATER 2.8.11)
62       set( _rpath_arg  "-DCMAKE_MACOSX_RPATH='${CMAKE_MACOSX_RPATH}'" )
63     else()
64       set( _rpath_arg )
65     endif()
66
67     try_compile(${VARIABLE}
68       "${test_project_dir}"
69       "${test_project_dir}"
70       undefined
71       CMAKE_FLAGS
72         "-DCMAKE_SHARED_LINKER_FLAGS='${CMAKE_SHARED_LINKER_FLAGS}'"
73         ${_rpath_arg}
74       OUTPUT_VARIABLE output)
75
76     set(${cache_var} "${cmake_flags_hash}" CACHE INTERNAL  "hashed try_compile flags")
77
78     if(${VARIABLE})
79       message(STATUS "Performing Test ${VARIABLE} - Success")
80     else()
81       message(STATUS "Performing Test ${VARIABLE} - Failed")
82       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
83         "Performing Test ${VARIABLE} failed with the following output:\n"
84         "${OUTPUT}\n")
85     endif()
86   endif()
87 endfunction()
88
89 _CheckUndefinedSymbolsAllowed()
90
91 macro( target_link_libraries_with_dynamic_lookup target )
92   if ( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
93     set_target_properties( ${target} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" )
94   elseif(UNDEFINED_SYMBOLS_ALLOWED)
95     # linker allows undefined symbols, let's just not link
96   else()
97     target_link_libraries ( ${target} ${ARGN}  )
98   endif()
99 endmacro()