Welcome to mirror list, hosted at ThFree Co, Russian Federation.

platform_apple_xcode.cmake « platform « cmake « build_files - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 06890f1cee1a946046196f04e32492840d317df6 (plain)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2016 Blender Foundation. All rights reserved.

# Xcode and system configuration for Apple.

# Detect processor architecture.
if(NOT CMAKE_OSX_ARCHITECTURES)
  execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
  message(STATUS "Detected native architecture ${ARCHITECTURE}.")
  set(CMAKE_OSX_ARCHITECTURES ${ARCHITECTURE} CACHE STRING
    "Choose the architecture you want to build Blender for: arm64 or x86_64"
    FORCE)
endif()

# Detect developer directory. Depending on configuration this may be either
# an Xcode or Command Line Tools installation.
execute_process(
    COMMAND xcode-select --print-path
    OUTPUT_VARIABLE XCODE_DEVELOPER_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)

# Detect Xcode version. It is provided by the Xcode generator but not
# Unix Makefiles or Ninja.
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
  # Note that `xcodebuild -version` gives output in two lines: first line will include
  # Xcode version, second one will include build number. We are only interested in the
  # first line. Here is an example of the output:
  #   Xcode 11.4
  #   Build version 11E146
  # The expected XCODE_VERSION in this case is 11.4.
  execute_process(
    COMMAND xcodebuild -version
    OUTPUT_VARIABLE _xcode_vers_build_nr
    RESULT_VARIABLE _xcode_vers_result
    ERROR_QUIET)

  if(_xcode_vers_result EQUAL 0)
    # Convert output to a single line by replacing newlines with spaces.
    # This is needed because regex replace can not operate through the newline character
    # and applies substitutions for each individual lines.
    string(REPLACE "\n" " " _xcode_vers_build_nr_single_line "${_xcode_vers_build_nr}")
    string(REGEX REPLACE "(.*)Xcode ([0-9\\.]+).*" "\\2" XCODE_VERSION "${_xcode_vers_build_nr_single_line}")
    unset(_xcode_vers_build_nr_single_line)
  endif()

  unset(_xcode_vers_build_nr)
  unset(_xcode_vers_result)
endif()

if(XCODE_VERSION)
  # Construct SDKs path ourselves, because xcode-select path could be ambiguous.
  # Both /Applications/Xcode.app/Contents/Developer or /Applications/Xcode.app would be allowed.
  set(XCODE_SDK_DIR ${XCODE_DEVELOPER_DIR}/Platforms/MacOSX.platform/Developer/SDKs)

  # Detect SDK version to use
  if(NOT DEFINED OSX_SYSTEM)
    execute_process(
        COMMAND xcodebuild -version -sdk macosx SDKVersion
        OUTPUT_VARIABLE OSX_SYSTEM
        OUTPUT_STRIP_TRAILING_WHITESPACE)
  endif()

  message(STATUS "Detected OS X ${OSX_SYSTEM} and Xcode ${XCODE_VERSION} at ${XCODE_DEVELOPER_DIR}")
  message(STATUS "SDKs Directory: " ${XCODE_SDK_DIR})
else()
  # If no Xcode version found, try detecting command line tools.
  execute_process(
      COMMAND pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
      OUTPUT_VARIABLE _cltools_pkg_info
      OUTPUT_STRIP_TRAILING_WHITESPACE
      RESULT_VARIABLE _cltools_pkg_info_result
      ERROR_QUIET)

  if(_cltools_pkg_info_result EQUAL 0)
    # Extract version.
    string(REGEX REPLACE ".*version: ([0-9]+)\\.([0-9]+).*" "\\1.\\2" XCODE_VERSION "${_cltools_pkg_info}")
    # SDK directory.
    set(XCODE_SDK_DIR "${XCODE_DEVELOPER_DIR}/SDKs")

    # Detect SDK version to use.
    if(NOT DEFINED OSX_SYSTEM)
      execute_process(
          COMMAND xcrun --sdk macosx --show-sdk-version
          OUTPUT_VARIABLE OSX_SYSTEM
          OUTPUT_STRIP_TRAILING_WHITESPACE)
    endif()

    message(STATUS "Detected OS X ${OSX_SYSTEM} and Command Line Tools ${XCODE_VERSION} at ${XCODE_DEVELOPER_DIR}")
    message(STATUS "SDKs Directory: " ${XCODE_SDK_DIR})
  else()
    message(FATAL_ERROR "No Xcode or Command Line Tools detected")
  endif()

  unset( _cltools_pkg_info)
  unset(__cltools_pkg_info_result)
endif()

# Require a relatively recent Xcode version.
if(${XCODE_VERSION} VERSION_LESS 10.0)
  message(FATAL_ERROR "Only Xcode version 10.0 and newer is supported")
endif()

# Collect list of OSX system versions which will be used to detect path to corresponding SDK.
# Start with macOS SDK version reported by xcodebuild and include possible extra ones.
#
# The reason for need of extra ones is because it's possible that xcodebuild will report
# SDK version in the full manner (aka major.minor.patch), but the actual path will only
# include major.minor.
#
# This happens, for example, on macOS Catalina 10.15.4 and Xcode 11.4: xcodebuild on this
# system outputs "10.15.4", but the actual SDK path is MacOSX10.15.sdk.
#
# This should be safe from picking wrong SDK version because (a) xcodebuild reports full semantic
# SDK version, so such SDK does exist on the system. And if it doesn't exist with full version
# in the path, what SDK is in the major.minor folder then.
set(OSX_SDK_TEST_VERSIONS ${OSX_SYSTEM})
if(OSX_SYSTEM MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1.\\2" OSX_SYSTEM_NO_PATCH "${OSX_SYSTEM}")
  list(APPEND OSX_SDK_TEST_VERSIONS ${OSX_SYSTEM_NO_PATCH})
  unset(OSX_SYSTEM_NO_PATCH)
endif()

# Loop through all possible versions and pick the first one which resolves to a valid SDK path.
set(OSX_SDK_PATH)
set(OSX_SDK_FOUND FALSE)
set(OSX_SDKROOT)
foreach(OSX_SDK_VERSION ${OSX_SDK_TEST_VERSIONS})
  set(CURRENT_OSX_SDK_PATH "${XCODE_SDK_DIR}/MacOSX${OSX_SDK_VERSION}.sdk")
  if(EXISTS ${CURRENT_OSX_SDK_PATH})
    set(OSX_SDK_PATH "${CURRENT_OSX_SDK_PATH}")
    set(OSX_SDKROOT macosx${OSX_SDK_VERSION})
    set(OSX_SDK_FOUND TRUE)
    break()
  endif()
endforeach()
unset(OSX_SDK_TEST_VERSIONS)

if(NOT OSX_SDK_FOUND)
  message(FATAL_ERROR "Unable to find SDK for macOS version ${OSX_SYSTEM}")
endif()

message(STATUS "Detected OSX_SYSROOT: ${OSX_SDK_PATH}")

set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH} CACHE PATH "" FORCE)
unset(OSX_SDK_PATH)
unset(OSX_SDK_FOUND)

if(${CMAKE_GENERATOR} MATCHES "Xcode")
  # to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
  set(CMAKE_XCODE_ATTRIBUTE_SDKROOT ${OSX_SDKROOT})
endif()
unset(OSX_SDKROOT)


if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
  # M1 chips run Big Sur onwards.
  set(OSX_MIN_DEPLOYMENT_TARGET 11.00)
else()
  # 10.13 is our min. target, if you use higher sdk, weak linking happens
  set(OSX_MIN_DEPLOYMENT_TARGET 10.13)
endif()

set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)

if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
  # Force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else (CMake bug?)
  string(APPEND CMAKE_C_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
  string(APPEND CMAKE_CXX_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
  add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()

if(WITH_COMPILER_CCACHE)
  if(CMAKE_GENERATOR STREQUAL "Xcode")
    find_program(CCACHE_PROGRAM ccache)
    if(CCACHE_PROGRAM)
      get_filename_component(ccompiler "${CMAKE_C_COMPILER}" NAME)
      get_filename_component(cxxcompiler "${CMAKE_CXX_COMPILER}" NAME)
      # Ccache can figure out which compiler to use if it's invoked from
      # a symlink with the name of the compiler.
      # https://ccache.dev/manual/4.1.html#_run_modes
      set(_fake_compiler_dir "${CMAKE_BINARY_DIR}/ccache")
      execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_fake_compiler_dir})
      set(_fake_C_COMPILER "${_fake_compiler_dir}/${ccompiler}")
      set(_fake_CXX_COMPILER "${_fake_compiler_dir}/${cxxcompiler}")
      execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_C_COMPILER})
      execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_CXX_COMPILER})
      set(CMAKE_XCODE_ATTRIBUTE_CC         ${_fake_C_COMPILER} CACHE STRING "" FORCE)
      set(CMAKE_XCODE_ATTRIBUTE_CXX        ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
      set(CMAKE_XCODE_ATTRIBUTE_LD         ${_fake_C_COMPILER} CACHE STRING "" FORCE)
      set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
      unset(_fake_compiler_dir)
      unset(_fake_C_COMPILER)
      unset(_fake_CXX_COMPILER)
    else()
      message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
      set(WITH_COMPILER_CCACHE OFF)
    endif()
  endif()
endif()