6fd9982358
Adds a new OS::get_system_ca_certs method which can be implemented by platforms to retrieve the list of trusted CA certificates using OS specific APIs. The function should return the certificates in PEM format, and is currently implemented for Windows/macOS/LinuxBSD(*)/Android. mbedTLS will fall back to bundled certificates when the OS returns no certificates. (*) LinuxBSD does not have a standardized certificates store location. The current implementation will test for common locations and may return an empty string on some distributions (falling back to the bundled certificates).
278 lines
9.4 KiB
Python
278 lines
9.4 KiB
Python
import os
|
|
import sys
|
|
from methods import detect_darwin_sdk_path
|
|
from platform_methods import detect_arch
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from SCons import Environment
|
|
|
|
|
|
def is_active():
|
|
return True
|
|
|
|
|
|
def get_name():
|
|
return "macOS"
|
|
|
|
|
|
def can_build():
|
|
if sys.platform == "darwin" or ("OSXCROSS_ROOT" in os.environ):
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def get_opts():
|
|
from SCons.Variables import BoolVariable, EnumVariable
|
|
|
|
return [
|
|
("osxcross_sdk", "OSXCross SDK version", "darwin16"),
|
|
("MACOS_SDK_PATH", "Path to the macOS SDK", ""),
|
|
("vulkan_sdk_path", "Path to the Vulkan SDK", ""),
|
|
EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")),
|
|
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
|
|
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN)", False),
|
|
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
|
|
BoolVariable("use_coverage", "Use instrumentation codes in the binary (e.g. for code coverage)", False),
|
|
]
|
|
|
|
|
|
def get_doc_classes():
|
|
return [
|
|
"EditorExportPlatformMacOS",
|
|
]
|
|
|
|
|
|
def get_doc_path():
|
|
return "doc_classes"
|
|
|
|
|
|
def get_flags():
|
|
return [
|
|
("arch", detect_arch()),
|
|
("use_volk", False),
|
|
]
|
|
|
|
|
|
def get_mvk_sdk_path():
|
|
def int_or_zero(i):
|
|
try:
|
|
return int(i)
|
|
except:
|
|
return 0
|
|
|
|
def ver_parse(a):
|
|
return [int_or_zero(i) for i in a.split(".")]
|
|
|
|
dirname = os.path.expanduser("~/VulkanSDK")
|
|
if not os.path.exists(dirname):
|
|
return ""
|
|
|
|
ver_file = "0.0.0.0"
|
|
ver_num = ver_parse(ver_file)
|
|
|
|
files = os.listdir(dirname)
|
|
for file in files:
|
|
if os.path.isdir(os.path.join(dirname, file)):
|
|
ver_comp = ver_parse(file)
|
|
lib_name = os.path.join(
|
|
os.path.join(dirname, file), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/libMoltenVK.a"
|
|
)
|
|
if os.path.isfile(lib_name) and ver_comp > ver_num:
|
|
ver_num = ver_comp
|
|
ver_file = file
|
|
|
|
return os.path.join(os.path.join(dirname, ver_file), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/")
|
|
|
|
|
|
def configure(env: "Environment"):
|
|
# Validate arch.
|
|
supported_arches = ["x86_64", "arm64"]
|
|
if env["arch"] not in supported_arches:
|
|
print(
|
|
'Unsupported CPU architecture "%s" for macOS. Supported architectures are: %s.'
|
|
% (env["arch"], ", ".join(supported_arches))
|
|
)
|
|
sys.exit()
|
|
|
|
## Build type
|
|
|
|
if env["target"] == "template_release":
|
|
if env["arch"] != "arm64":
|
|
env.Prepend(CCFLAGS=["-msse2"])
|
|
elif env.dev_build:
|
|
env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"])
|
|
|
|
## Compiler configuration
|
|
|
|
# Save this in environment for use by other modules
|
|
if "OSXCROSS_ROOT" in os.environ:
|
|
env["osxcross"] = True
|
|
|
|
# CPU architecture.
|
|
if env["arch"] == "arm64":
|
|
print("Building for macOS 11.0+.")
|
|
env.Append(ASFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
|
|
env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
|
|
env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
|
|
elif env["arch"] == "x86_64":
|
|
print("Building for macOS 10.13+.")
|
|
env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"])
|
|
env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"])
|
|
env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"])
|
|
|
|
env.Append(CCFLAGS=["-fobjc-arc"])
|
|
|
|
if not "osxcross" in env: # regular native build
|
|
if env["macports_clang"] != "no":
|
|
mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
|
|
mpclangver = env["macports_clang"]
|
|
env["CC"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang"
|
|
env["CXX"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++"
|
|
env["AR"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar"
|
|
env["RANLIB"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib"
|
|
env["AS"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as"
|
|
else:
|
|
env["CC"] = "clang"
|
|
env["CXX"] = "clang++"
|
|
|
|
detect_darwin_sdk_path("macos", env)
|
|
env.Append(CCFLAGS=["-isysroot", "$MACOS_SDK_PATH"])
|
|
env.Append(LINKFLAGS=["-isysroot", "$MACOS_SDK_PATH"])
|
|
|
|
else: # osxcross build
|
|
root = os.environ.get("OSXCROSS_ROOT", "")
|
|
if env["arch"] == "arm64":
|
|
basecmd = root + "/target/bin/arm64-apple-" + env["osxcross_sdk"] + "-"
|
|
else:
|
|
basecmd = root + "/target/bin/x86_64-apple-" + env["osxcross_sdk"] + "-"
|
|
|
|
ccache_path = os.environ.get("CCACHE")
|
|
if ccache_path is None:
|
|
env["CC"] = basecmd + "cc"
|
|
env["CXX"] = basecmd + "c++"
|
|
else:
|
|
# there aren't any ccache wrappers available for macOS cross-compile,
|
|
# to enable caching we need to prepend the path to the ccache binary
|
|
env["CC"] = ccache_path + " " + basecmd + "cc"
|
|
env["CXX"] = ccache_path + " " + basecmd + "c++"
|
|
env["AR"] = basecmd + "ar"
|
|
env["RANLIB"] = basecmd + "ranlib"
|
|
env["AS"] = basecmd + "as"
|
|
|
|
# LTO
|
|
|
|
if env["lto"] == "auto": # LTO benefits for macOS (size, performance) haven't been clearly established yet.
|
|
env["lto"] = "none"
|
|
|
|
if env["lto"] != "none":
|
|
if env["lto"] == "thin":
|
|
env.Append(CCFLAGS=["-flto=thin"])
|
|
env.Append(LINKFLAGS=["-flto=thin"])
|
|
else:
|
|
env.Append(CCFLAGS=["-flto"])
|
|
env.Append(LINKFLAGS=["-flto"])
|
|
|
|
# Sanitizers
|
|
|
|
if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]:
|
|
env.extra_suffix += ".san"
|
|
env.Append(CCFLAGS=["-DSANITIZERS_ENABLED"])
|
|
|
|
if env["use_ubsan"]:
|
|
env.Append(
|
|
CCFLAGS=[
|
|
"-fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin"
|
|
]
|
|
)
|
|
env.Append(LINKFLAGS=["-fsanitize=undefined"])
|
|
env.Append(CCFLAGS=["-fsanitize=nullability-return,nullability-arg,function,nullability-assign"])
|
|
|
|
if env["use_asan"]:
|
|
env.Append(CCFLAGS=["-fsanitize=address,pointer-subtract,pointer-compare"])
|
|
env.Append(LINKFLAGS=["-fsanitize=address"])
|
|
|
|
if env["use_tsan"]:
|
|
env.Append(CCFLAGS=["-fsanitize=thread"])
|
|
env.Append(LINKFLAGS=["-fsanitize=thread"])
|
|
|
|
if env["use_coverage"]:
|
|
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
|
|
env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"])
|
|
|
|
## Dependencies
|
|
|
|
if env["builtin_libtheora"] and env["arch"] == "x86_64":
|
|
env["x86_libtheora_opt_gcc"] = True
|
|
|
|
## Flags
|
|
|
|
env.Prepend(CPPPATH=["#platform/macos"])
|
|
env.Append(CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"])
|
|
env.Append(
|
|
LINKFLAGS=[
|
|
"-framework",
|
|
"Cocoa",
|
|
"-framework",
|
|
"Carbon",
|
|
"-framework",
|
|
"AudioUnit",
|
|
"-framework",
|
|
"CoreAudio",
|
|
"-framework",
|
|
"CoreMIDI",
|
|
"-framework",
|
|
"IOKit",
|
|
"-framework",
|
|
"ForceFeedback",
|
|
"-framework",
|
|
"CoreVideo",
|
|
"-framework",
|
|
"AVFoundation",
|
|
"-framework",
|
|
"CoreMedia",
|
|
"-framework",
|
|
"QuartzCore",
|
|
"-framework",
|
|
"Security",
|
|
]
|
|
)
|
|
env.Append(LIBS=["pthread", "z"])
|
|
|
|
if env["opengl3"]:
|
|
env.Append(CPPDEFINES=["GLES3_ENABLED"])
|
|
env.Append(LINKFLAGS=["-framework", "OpenGL"])
|
|
|
|
env.Append(LINKFLAGS=["-rpath", "@executable_path/../Frameworks", "-rpath", "@executable_path"])
|
|
|
|
if env["vulkan"]:
|
|
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
|
|
env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "IOSurface"])
|
|
if not env["use_volk"]:
|
|
env.Append(LINKFLAGS=["-lMoltenVK"])
|
|
mvk_found = False
|
|
|
|
mvk_list = [get_mvk_sdk_path(), "/opt/homebrew/lib", "/usr/local/homebrew/lib", "/opt/local/lib"]
|
|
if env["vulkan_sdk_path"] != "":
|
|
mvk_list.insert(0, os.path.expanduser(env["vulkan_sdk_path"]))
|
|
mvk_list.insert(
|
|
0,
|
|
os.path.join(
|
|
os.path.expanduser(env["vulkan_sdk_path"]), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/"
|
|
),
|
|
)
|
|
|
|
for mvk_path in mvk_list:
|
|
if mvk_path and os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")):
|
|
mvk_found = True
|
|
print("MoltenVK found at: " + mvk_path)
|
|
env.Append(LINKFLAGS=["-L" + mvk_path])
|
|
break
|
|
|
|
if not mvk_found:
|
|
print(
|
|
"MoltenVK SDK installation directory not found, use 'vulkan_sdk_path' SCons parameter to specify SDK path."
|
|
)
|
|
sys.exit(255)
|