Imported Upstream version 3.17.1
[platform/upstream/cmake.git] / Modules / Platform / Darwin-Initialize.cmake
1 # Ask xcode-select where to find /Developer or fall back to ancient location.
2 execute_process(COMMAND xcode-select -print-path
3   OUTPUT_VARIABLE _stdout
4   OUTPUT_STRIP_TRAILING_WHITESPACE
5   ERROR_VARIABLE _stderr
6   RESULT_VARIABLE _failed)
7 if(NOT _failed AND IS_DIRECTORY ${_stdout})
8   set(OSX_DEVELOPER_ROOT ${_stdout})
9 elseif(IS_DIRECTORY "/Developer")
10   set(OSX_DEVELOPER_ROOT "/Developer")
11 else()
12   set(OSX_DEVELOPER_ROOT "")
13 endif()
14
15 execute_process(COMMAND sw_vers -productVersion
16   OUTPUT_VARIABLE CURRENT_OSX_VERSION
17   OUTPUT_STRIP_TRAILING_WHITESPACE)
18
19 # Save CMAKE_OSX_ARCHITECTURES from the environment.
20 set(CMAKE_OSX_ARCHITECTURES "$ENV{CMAKE_OSX_ARCHITECTURES}" CACHE STRING
21   "Build architectures for OSX")
22
23 # macOS, iOS, tvOS, and watchOS should lookup compilers from
24 # Platform/Apple-${CMAKE_CXX_COMPILER_ID}-<LANG>
25 set(CMAKE_EFFECTIVE_SYSTEM_NAME "Apple")
26
27 #----------------------------------------------------------------------------
28 # _CURRENT_OSX_VERSION - as a two-component string: 10.5, 10.6, ...
29 #
30 string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*$" "\\1"
31   _CURRENT_OSX_VERSION "${CURRENT_OSX_VERSION}")
32
33 #----------------------------------------------------------------------------
34 # CMAKE_OSX_DEPLOYMENT_TARGET
35
36 # Set cache variable - end user may change this during ccmake or cmake-gui configure.
37 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND _CURRENT_OSX_VERSION VERSION_GREATER 10.3)
38   set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING
39     "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value.")
40 endif()
41
42 #----------------------------------------------------------------------------
43 # CMAKE_OSX_SYSROOT
44
45 if(CMAKE_OSX_SYSROOT)
46   # Use the existing value without further computation to choose a default.
47   set(_CMAKE_OSX_SYSROOT_DEFAULT "${CMAKE_OSX_SYSROOT}")
48 elseif(NOT "x$ENV{SDKROOT}" STREQUAL "x" AND
49         (NOT "x$ENV{SDKROOT}" MATCHES "/" OR IS_DIRECTORY "$ENV{SDKROOT}"))
50   # Use the value of SDKROOT from the environment.
51   set(_CMAKE_OSX_SYSROOT_DEFAULT "$ENV{SDKROOT}")
52 elseif(CMAKE_SYSTEM_NAME STREQUAL iOS)
53   set(_CMAKE_OSX_SYSROOT_DEFAULT "iphoneos")
54 elseif(CMAKE_SYSTEM_NAME STREQUAL tvOS)
55   set(_CMAKE_OSX_SYSROOT_DEFAULT "appletvos")
56 elseif(CMAKE_SYSTEM_NAME STREQUAL watchOS)
57   set(_CMAKE_OSX_SYSROOT_DEFAULT "watchos")
58 elseif("${CMAKE_GENERATOR}" MATCHES Xcode
59        OR CMAKE_OSX_DEPLOYMENT_TARGET
60        OR CMAKE_OSX_ARCHITECTURES MATCHES "[^;]"
61        OR NOT EXISTS "/usr/include/sys/types.h")
62   # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory.
63   set(_CMAKE_OSX_SDKS_DIR "")
64   if(OSX_DEVELOPER_ROOT)
65     foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs)
66       file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${d}/*)
67       if(_CMAKE_OSX_SDKS)
68         set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${d})
69         break()
70       endif()
71     endforeach()
72   endif()
73
74   if(_CMAKE_OSX_SDKS_DIR)
75     # Select SDK for current OSX version accounting for the known
76     # specially named SDKs.
77     set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u")
78     set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9")
79
80     # find the latest SDK
81     set(_CMAKE_OSX_LATEST_SDK_VERSION "0.0")
82     file(GLOB _CMAKE_OSX_SDKS RELATIVE "${_CMAKE_OSX_SDKS_DIR}" "${_CMAKE_OSX_SDKS_DIR}/MacOSX*.sdk")
83     foreach(_SDK ${_CMAKE_OSX_SDKS})
84       if(_SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk" AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
85         set(_CMAKE_OSX_LATEST_SDK_VERSION "${CMAKE_MATCH_1}")
86       endif()
87     endforeach()
88
89     # pick an SDK that works
90     set(_CMAKE_OSX_SYSROOT_DEFAULT)
91     foreach(ver ${CMAKE_OSX_DEPLOYMENT_TARGET}
92                 ${_CURRENT_OSX_VERSION}
93                 ${_CMAKE_OSX_LATEST_SDK_VERSION})
94       set(_CMAKE_OSX_DEPLOYMENT_TARGET ${ver})
95       set(_CMAKE_OSX_SDKS_VER ${_CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CMAKE_OSX_DEPLOYMENT_TARGET}})
96       set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
97       if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_CHECK}")
98         set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SYSROOT_CHECK}")
99         break()
100       endif()
101     endforeach()
102
103     if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET AND _CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_DEPLOYMENT_TARGET)
104       set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING
105         "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE)
106     endif()
107   else()
108     # Assume developer files are in root (such as Xcode 4.5 command-line tools).
109     set(_CMAKE_OSX_SYSROOT_DEFAULT "")
110   endif()
111 endif()
112
113 # Set cache variable - end user may change this during ccmake or cmake-gui configure.
114 # Choose the type based on the current value.
115 set(_CMAKE_OSX_SYSROOT_TYPE STRING)
116 foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
117   if("x${${v}}" MATCHES "/")
118     set(_CMAKE_OSX_SYSROOT_TYPE PATH)
119     break()
120   endif()
121 endforeach()
122 set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_DEFAULT}" CACHE ${_CMAKE_OSX_SYSROOT_TYPE}
123   "The product will be built against the headers and libraries located inside the indicated SDK.")
124
125 # Resolves the SDK name into a path
126 function(_apple_resolve_sdk_path sdk_name ret)
127   execute_process(
128     COMMAND xcrun -sdk ${sdk_name} --show-sdk-path
129     OUTPUT_VARIABLE _stdout
130     OUTPUT_STRIP_TRAILING_WHITESPACE
131     ERROR_VARIABLE _stderr
132     RESULT_VARIABLE _failed
133   )
134   set(${ret} "${_stdout}" PARENT_SCOPE)
135 endfunction()
136 # Handle multi-arch sysroots. Do this before CMAKE_OSX_SYSROOT is
137 # transformed into a path, so that we know the sysroot name.
138 function(_apple_resolve_multi_arch_sysroots)
139   if(DEFINED CMAKE_APPLE_ARCH_SYSROOTS)
140     return() # Already cached
141   endif()
142
143   list(LENGTH CMAKE_OSX_ARCHITECTURES _num_archs)
144   if(NOT (_num_archs GREATER 1))
145     return() # Only apply to multi-arch
146   endif()
147
148   if(CMAKE_OSX_SYSROOT STREQUAL "macosx")
149     # macOS doesn't have a simulator sdk / sysroot, so there is no need to handle per-sdk arches.
150     return()
151   endif()
152
153   if(IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
154     if(NOT CMAKE_OSX_SYSROOT STREQUAL _CMAKE_OSX_SYSROOT_DEFAULT)
155       message(WARNING "Can not resolve multi-arch sysroots with CMAKE_OSX_SYSROOT set to path (${CMAKE_OSX_SYSROOT})")
156     endif()
157     return()
158   endif()
159
160   string(REPLACE "os" "simulator" _simulator_sdk ${CMAKE_OSX_SYSROOT})
161   set(_sdks "${CMAKE_OSX_SYSROOT};${_simulator_sdk}")
162   foreach(sdk ${_sdks})
163     _apple_resolve_sdk_path(${sdk} _sdk_path)
164     if(NOT IS_DIRECTORY "${_sdk_path}")
165       message(WARNING "Failed to resolve SDK path for '${sdk}'")
166       continue()
167     endif()
168
169     execute_process(
170       COMMAND plutil -extract SupportedTargets.${sdk}.Archs json ${_sdk_path}/SDKSettings.plist -o -
171       OUTPUT_VARIABLE _sdk_archs_json
172       OUTPUT_STRIP_TRAILING_WHITESPACE
173       ERROR_VARIABLE _stderr
174       RESULT_VARIABLE _failed
175       )
176     if(_failed)
177       # Failure to extract supported architectures for an SDK means that the installed SDK is old
178       # and does not provide such information (SDKs that come with Xcode >= 10.x started providing
179       # the information). In such a case, return early, and handle multi-arch builds the old way
180       # (no per-sdk arches).
181       return()
182     endif()
183
184     # Poor man's JSON decoding
185     string(REGEX REPLACE "[]\\[\"]" "" _sdk_archs ${_sdk_archs_json})
186     string(REPLACE "," ";" _sdk_archs ${_sdk_archs})
187
188     set(_sdk_archs_${sdk} ${_sdk_archs})
189     set(_sdk_path_${sdk} ${_sdk_path})
190   endforeach()
191
192   foreach(arch ${CMAKE_OSX_ARCHITECTURES})
193     set(_arch_sysroot "")
194     foreach(sdk ${_sdks})
195       list(FIND _sdk_archs_${sdk} ${arch} arch_index)
196       if(NOT arch_index EQUAL -1)
197         set(_arch_sysroot ${_sdk_path_${sdk}})
198         break()
199       endif()
200     endforeach()
201     if(_arch_sysroot)
202       list(APPEND _arch_sysroots ${_arch_sysroot})
203     else()
204       message(WARNING "No SDK found for architecture '${arch}'")
205       list(APPEND _arch_sysroots "${arch}-SDK-NOTFOUND")
206     endif()
207   endforeach()
208
209   set(CMAKE_APPLE_ARCH_SYSROOTS "${_arch_sysroots}" CACHE INTERNAL
210     "Architecture dependent sysroots, one per CMAKE_OSX_ARCHITECTURES")
211 endfunction()
212
213 _apple_resolve_multi_arch_sysroots()
214
215 # Transform CMAKE_OSX_SYSROOT to absolute path
216 set(_CMAKE_OSX_SYSROOT_PATH "")
217 if(CMAKE_OSX_SYSROOT)
218   if("x${CMAKE_OSX_SYSROOT}" MATCHES "/")
219     # This is a path to the SDK.  Make sure it exists.
220     if(NOT IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
221       message(WARNING "Ignoring CMAKE_OSX_SYSROOT value:\n ${CMAKE_OSX_SYSROOT}\n"
222         "because the directory does not exist.")
223       set(CMAKE_OSX_SYSROOT "")
224     endif()
225     set(_CMAKE_OSX_SYSROOT_PATH "${CMAKE_OSX_SYSROOT}")
226   else()
227     _apple_resolve_sdk_path(${CMAKE_OSX_SYSROOT} _sdk_path)
228     if(IS_DIRECTORY "${_sdk_path}")
229       set(_CMAKE_OSX_SYSROOT_PATH "${_sdk_path}")
230       # For non-Xcode generators use the path.
231       if(NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
232         set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
233       endif()
234     endif()
235   endif()
236 endif()