Geometry Nodes: Link error when implicit conversion isn't possible
[blender.git] / build_files / cmake / platform / platform_apple_xcode.cmake
1 # ***** BEGIN GPL LICENSE BLOCK *****
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # The Original Code is Copyright (C) 2016, Blender Foundation
18 # All rights reserved.
19 # ***** END GPL LICENSE BLOCK *****
20
21 # Xcode and system configuration for Apple.
22
23 # Detect processor architecture.
24 if(NOT CMAKE_OSX_ARCHITECTURES)
25   execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
26   message(STATUS "Detected native architecture ${ARCHITECTURE}.")
27   set(CMAKE_OSX_ARCHITECTURES ${ARCHITECTURE} CACHE STRING
28     "Choose the architecture you want to build Blender for: arm64 or x86_64"
29     FORCE)
30 endif()
31
32 # Detect developer directory. Depending on configuration this may be either
33 # an Xcode or Command Line Tools installation.
34 execute_process(
35     COMMAND xcode-select --print-path
36     OUTPUT_VARIABLE XCODE_DEVELOPER_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
37
38 # Detect Xcode version. It is provided by the Xcode generator but not
39 # Unix Makefiles or Ninja.
40 if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
41   # Note that `xcodebuild -version` gives output in two lines: first line will include
42   # Xcode version, second one will include build number. We are only interested in the
43   # first line. Here is an example of the output:
44   #   Xcode 11.4
45   #   Build version 11E146
46   # The expected XCODE_VERSION in this case is 11.4.
47   execute_process(
48     COMMAND xcodebuild -version
49     OUTPUT_VARIABLE _xcode_vers_build_nr
50     RESULT_VARIABLE _xcode_vers_result
51     ERROR_QUIET)
52
53   if(_xcode_vers_result EQUAL 0)
54     # Convert output to a single line by replacing newlines with spaces.
55     # This is needed because regex replace can not operate through the newline character
56     # and applies substitutions for each individual lines.
57     string(REPLACE "\n" " " _xcode_vers_build_nr_single_line "${_xcode_vers_build_nr}")
58     string(REGEX REPLACE "(.*)Xcode ([0-9\\.]+).*" "\\2" XCODE_VERSION "${_xcode_vers_build_nr_single_line}")
59     unset(_xcode_vers_build_nr_single_line)
60   endif()
61
62   unset(_xcode_vers_build_nr)
63   unset(_xcode_vers_result)
64 endif()
65
66 if(XCODE_VERSION)
67   # Construct SDKs path ourselves, because xcode-select path could be ambiguous.
68   # Both /Applications/Xcode.app/Contents/Developer or /Applications/Xcode.app would be allowed.
69   set(XCODE_SDK_DIR ${XCODE_DEVELOPER_DIR}/Platforms/MacOSX.platform/Developer/SDKs)
70
71   # Detect SDK version to use
72   if(NOT DEFINED OSX_SYSTEM)
73     execute_process(
74         COMMAND xcodebuild -version -sdk macosx SDKVersion
75         OUTPUT_VARIABLE OSX_SYSTEM
76         OUTPUT_STRIP_TRAILING_WHITESPACE)
77   endif()
78
79   message(STATUS "Detected OS X ${OSX_SYSTEM} and Xcode ${XCODE_VERSION} at ${XCODE_DEVELOPER_DIR}")
80   message(STATUS "SDKs Directory: " ${XCODE_SDK_DIR})
81 else()
82   # If no Xcode version found, try detecting command line tools.
83   execute_process(
84       COMMAND pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
85       OUTPUT_VARIABLE _cltools_pkg_info
86       OUTPUT_STRIP_TRAILING_WHITESPACE
87       RESULT_VARIABLE _cltools_pkg_info_result
88       ERROR_QUIET)
89
90   if(_cltools_pkg_info_result EQUAL 0)
91     # Extract version.
92     string(REGEX REPLACE ".*version: ([0-9]+)\\.([0-9]+).*" "\\1.\\2" XCODE_VERSION "${_cltools_pkg_info}")
93     # SDK directory.
94     set(XCODE_SDK_DIR "${XCODE_DEVELOPER_DIR}/SDKs")
95
96     # Detect SDK version to use.
97     if(NOT DEFINED OSX_SYSTEM)
98       execute_process(
99           COMMAND xcrun --show-sdk-version
100           OUTPUT_VARIABLE OSX_SYSTEM
101           OUTPUT_STRIP_TRAILING_WHITESPACE)
102     endif()
103
104     message(STATUS "Detected OS X ${OSX_SYSTEM} and Command Line Tools ${XCODE_VERSION} at ${XCODE_DEVELOPER_DIR}")
105     message(STATUS "SDKs Directory: " ${XCODE_SDK_DIR})
106   else()
107     message(FATAL_ERROR "No Xcode or Command Line Tools detected")
108   endif()
109
110   unset( _cltools_pkg_info)
111   unset(__cltools_pkg_info_result)
112 endif()
113
114 # Require a relatively recent Xcode version.
115 if(${XCODE_VERSION} VERSION_LESS 10.0)
116   message(FATAL_ERROR "Only Xcode version 10.0 and newer is supported")
117 endif()
118
119 # Collect list of OSX system versions which will be used to detect path to corresponding SDK.
120 # Start with macOS SDK version reported by xcodebuild and include possible extra ones.
121 #
122 # The reason for need of extra ones is because it's possible that xcodebuild will report
123 # SDK version in the full manner (aka major.minor.patch), but the actual path will only
124 # include major.minor.
125 #
126 # This happens, for example, on macOS Catalina 10.15.4 and Xcode 11.4: xcodebuild on this
127 # system outputs "10.15.4", but the actual SDK path is MacOSX10.15.sdk.
128 #
129 # This should be safe from picking wrong SDK version because (a) xcodebuild reports full semantic
130 # SDK version, so such SDK does exist on the system. And if it doesn't exist with full version
131 # in the path, what SDK is in the major.minor folder then.
132 set(OSX_SDK_TEST_VERSIONS ${OSX_SYSTEM})
133 if(OSX_SYSTEM MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
134   string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1.\\2" OSX_SYSTEM_NO_PATCH "${OSX_SYSTEM}")
135   list(APPEND OSX_SDK_TEST_VERSIONS ${OSX_SYSTEM_NO_PATCH})
136   unset(OSX_SYSTEM_NO_PATCH)
137 endif()
138
139 # Loop through all possible versions and pick the first one which resolves to a valid SDK path.
140 set(OSX_SDK_PATH)
141 set(OSX_SDK_FOUND FALSE)
142 set(OSX_SDKROOT)
143 foreach(OSX_SDK_VERSION ${OSX_SDK_TEST_VERSIONS})
144   set(CURRENT_OSX_SDK_PATH "${XCODE_SDK_DIR}/MacOSX${OSX_SDK_VERSION}.sdk")
145   if(EXISTS ${CURRENT_OSX_SDK_PATH})
146     set(OSX_SDK_PATH "${CURRENT_OSX_SDK_PATH}")
147     set(OSX_SDKROOT macosx${OSX_SDK_VERSION})
148     set(OSX_SDK_FOUND TRUE)
149     break()
150   endif()
151 endforeach()
152 unset(OSX_SDK_TEST_VERSIONS)
153
154 if(NOT OSX_SDK_FOUND)
155   message(FATAL_ERROR "Unable to find SDK for macOS version ${OSX_SYSTEM}")
156 endif()
157
158 message(STATUS "Detected OSX_SYSROOT: ${OSX_SDK_PATH}")
159
160 set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH} CACHE PATH "" FORCE)
161 unset(OSX_SDK_PATH)
162 unset(OSX_SDK_FOUND)
163
164 if(${CMAKE_GENERATOR} MATCHES "Xcode")
165   # to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
166   set(CMAKE_XCODE_ATTRIBUTE_SDKROOT ${OSX_SDKROOT})
167 endif()
168 unset(OSX_SDKROOT)
169
170
171 # 10.13 is our min. target, if you use higher sdk, weak linking happens
172 if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
173   set(OSX_MIN_DEPLOYMENT_TARGET 11.00)
174 else()
175   set(OSX_MIN_DEPLOYMENT_TARGET 10.13)
176 endif()
177
178 if(CMAKE_OSX_DEPLOYMENT_TARGET)
179   if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS ${OSX_MIN_DEPLOYMENT_TARGET})
180     message(STATUS "Setting deployment target to ${OSX_MIN_DEPLOYMENT_TARGET}, lower versions are not supported")
181     set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
182   endif()
183 else()
184   set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
185 endif()
186
187 if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
188   # Force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else (CMake bug?)
189   string(APPEND CMAKE_C_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
190   string(APPEND CMAKE_CXX_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
191   add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
192 endif()
193
194 if(WITH_COMPILER_CCACHE)
195   if(CMAKE_GENERATOR STREQUAL "Xcode")
196     find_program(CCACHE_PROGRAM ccache)
197     if(CCACHE_PROGRAM)
198       get_filename_component(ccompiler "${CMAKE_C_COMPILER}" NAME)
199       get_filename_component(cxxcompiler "${CMAKE_CXX_COMPILER}" NAME)
200       # Ccache can figure out which compiler to use if it's invoked from
201       # a symlink with the name of the compiler.
202       # https://ccache.dev/manual/4.1.html#_run_modes
203       set(_fake_compiler_dir "${CMAKE_BINARY_DIR}/ccache")
204       execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_fake_compiler_dir})
205       set(_fake_C_COMPILER "${_fake_compiler_dir}/${ccompiler}")
206       set(_fake_CXX_COMPILER "${_fake_compiler_dir}/${cxxcompiler}")
207       execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_C_COMPILER})
208       execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_CXX_COMPILER})
209       set(CMAKE_XCODE_ATTRIBUTE_CC         ${_fake_C_COMPILER} CACHE STRING "" FORCE)
210       set(CMAKE_XCODE_ATTRIBUTE_CXX        ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
211       set(CMAKE_XCODE_ATTRIBUTE_LD         ${_fake_C_COMPILER} CACHE STRING "" FORCE)
212       set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
213       unset(_fake_compiler_dir)
214       unset(_fake_C_COMPILER)
215       unset(_fake_CXX_COMPILER)
216     else()
217       message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
218       set(WITH_COMPILER_CCACHE OFF)
219     endif()
220   endif()
221 endif()