mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00

Made possible by EIREXE, xsellier and the SDL team. This commit includes statically linked SDL3 for Windows, Linux and macOS. The vendored copy of SDL3 was setup to only build the required subsystems for gamepad/joystick support, with some patches to be able to make it as minimal as possible and reduce the impact on binary size and code size. Co-authored-by: Álex Román Núñez <eirexe123@gmail.com> Co-authored-by: Xavier Sellier <xsellier@gmail.com> Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
293 lines
10 KiB
Python
293 lines
10 KiB
Python
import os
|
|
import sys
|
|
from typing import TYPE_CHECKING
|
|
|
|
from methods import detect_darwin_sdk_path, get_compiler_version, is_apple_clang, print_error, print_warning
|
|
from platform_methods import detect_arch, detect_mvk, validate_arch
|
|
|
|
if TYPE_CHECKING:
|
|
from SCons.Script.SConscript import SConsEnvironment
|
|
|
|
# To match other platforms
|
|
STACK_SIZE = 8388608
|
|
STACK_SIZE_SANITIZERS = 30 * 1024 * 1024
|
|
|
|
|
|
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"], ignorecase=2),
|
|
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),
|
|
("angle_libs", "Path to the ANGLE static libraries", ""),
|
|
(
|
|
"bundle_sign_identity",
|
|
"The 'Full Name', 'Common Name' or SHA-1 hash of the signing identity used to sign editor .app bundle.",
|
|
"-",
|
|
),
|
|
BoolVariable("generate_bundle", "Generate an APP bundle after building iOS/macOS binaries", False),
|
|
]
|
|
|
|
|
|
def get_doc_classes():
|
|
return [
|
|
"EditorExportPlatformMacOS",
|
|
]
|
|
|
|
|
|
def get_doc_path():
|
|
return "doc_classes"
|
|
|
|
|
|
def get_flags():
|
|
return {
|
|
"arch": detect_arch(),
|
|
"use_volk": False,
|
|
"metal": True,
|
|
"supported": ["metal", "mono"],
|
|
}
|
|
|
|
|
|
def configure(env: "SConsEnvironment"):
|
|
# Validate arch.
|
|
supported_arches = ["x86_64", "arm64"]
|
|
validate_arch(env["arch"], get_name(), supported_arches)
|
|
|
|
## 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=["-ffp-contract=off"])
|
|
env.Append(CCFLAGS=["-fobjc-arc"])
|
|
|
|
cc_version = get_compiler_version(env)
|
|
cc_version_major = cc_version["apple_major"]
|
|
cc_version_minor = cc_version["apple_minor"]
|
|
|
|
# Workaround for Xcode 15 linker bug.
|
|
if is_apple_clang(env) and cc_version_major == 1500 and cc_version_minor == 0:
|
|
env.Prepend(LINKFLAGS=["-ld_classic"])
|
|
|
|
if env.dev_build:
|
|
env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"])
|
|
|
|
ccache_path = os.environ.get("CCACHE", "")
|
|
if ccache_path != "":
|
|
ccache_path = ccache_path + " "
|
|
|
|
if "osxcross" not 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"] = ccache_path + "clang"
|
|
env["CXX"] = ccache_path + "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"] + "-"
|
|
|
|
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"])
|
|
|
|
env.Append(LINKFLAGS=["-Wl,-stack_size," + hex(STACK_SIZE_SANITIZERS)])
|
|
else:
|
|
env.Append(LINKFLAGS=["-Wl,-stack_size," + hex(STACK_SIZE)])
|
|
|
|
if env["use_coverage"]:
|
|
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
|
|
env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"])
|
|
|
|
## Dependencies
|
|
|
|
if env["accesskit"]:
|
|
if env["accesskit_sdk_path"] != "":
|
|
env.Prepend(CPPPATH=[env["accesskit_sdk_path"] + "/include"])
|
|
if env["arch"] == "arm64" or env["arch"] == "universal":
|
|
env.Append(LINKFLAGS=["-L" + env["accesskit_sdk_path"] + "/lib/macos/arm64/static/"])
|
|
if env["arch"] == "x86_64" or env["arch"] == "universal":
|
|
env.Append(LINKFLAGS=["-L" + env["accesskit_sdk_path"] + "/lib/macos/x86_64/static/"])
|
|
env.Append(LINKFLAGS=["-laccesskit"])
|
|
else:
|
|
env.Append(CPPDEFINES=["ACCESSKIT_DYNAMIC"])
|
|
env.Append(CPPDEFINES=["ACCESSKIT_ENABLED"])
|
|
|
|
if env["builtin_libtheora"] and env["arch"] == "x86_64":
|
|
env["x86_libtheora_opt_gcc"] = True
|
|
|
|
if env["sdl"]:
|
|
env.Append(CPPDEFINES=["SDL_ENABLED"])
|
|
env.Append(LINKFLAGS=["-framework", "ForceFeedback"])
|
|
|
|
## 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",
|
|
"GameController",
|
|
"-framework",
|
|
"CoreHaptics",
|
|
"-framework",
|
|
"CoreVideo",
|
|
"-framework",
|
|
"AVFoundation",
|
|
"-framework",
|
|
"CoreMedia",
|
|
"-framework",
|
|
"QuartzCore",
|
|
"-framework",
|
|
"Security",
|
|
"-framework",
|
|
"UniformTypeIdentifiers",
|
|
"-framework",
|
|
"IOSurface",
|
|
]
|
|
)
|
|
env.Append(LIBS=["pthread", "z"])
|
|
|
|
extra_frameworks = set()
|
|
|
|
if env["opengl3"]:
|
|
env.Append(CPPDEFINES=["GLES3_ENABLED"])
|
|
if env["angle_libs"] != "":
|
|
env.AppendUnique(CPPDEFINES=["EGL_STATIC"])
|
|
env.Append(LINKFLAGS=["-L" + env["angle_libs"]])
|
|
env.Append(LINKFLAGS=["-lANGLE.macos." + env["arch"]])
|
|
env.Append(LINKFLAGS=["-lEGL.macos." + env["arch"]])
|
|
env.Append(LINKFLAGS=["-lGLES.macos." + env["arch"]])
|
|
env.Prepend(CPPEXTPATH=["#thirdparty/angle/include"])
|
|
|
|
env.Append(LINKFLAGS=["-rpath", "@executable_path/../Frameworks", "-rpath", "@executable_path"])
|
|
|
|
if env["metal"] and env["arch"] != "arm64":
|
|
print_warning("Target architecture '{}' does not support the Metal rendering driver".format(env["arch"]))
|
|
env["metal"] = False
|
|
|
|
if env["metal"]:
|
|
env.AppendUnique(CPPDEFINES=["METAL_ENABLED", "RD_ENABLED"])
|
|
extra_frameworks.add("Metal")
|
|
extra_frameworks.add("MetalKit")
|
|
extra_frameworks.add("MetalFX")
|
|
env.Prepend(CPPEXTPATH=["#thirdparty/spirv-cross"])
|
|
|
|
if env["vulkan"]:
|
|
env.AppendUnique(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"])
|
|
extra_frameworks.add("Metal")
|
|
if not env["use_volk"]:
|
|
env.Append(LINKFLAGS=["-lMoltenVK"])
|
|
|
|
mvk_path = ""
|
|
arch_variants = ["macos-arm64_x86_64", "macos-" + env["arch"]]
|
|
for arch in arch_variants:
|
|
mvk_path = detect_mvk(env, arch)
|
|
if mvk_path != "":
|
|
mvk_path = os.path.join(mvk_path, arch)
|
|
break
|
|
|
|
if mvk_path != "":
|
|
env.Append(LINKFLAGS=["-L" + mvk_path])
|
|
else:
|
|
print_error(
|
|
"MoltenVK SDK installation directory not found, use 'vulkan_sdk_path' SCons parameter to specify SDK path."
|
|
)
|
|
sys.exit(255)
|
|
|
|
if len(extra_frameworks) > 0:
|
|
frameworks = [item for key in extra_frameworks for item in ["-framework", key]]
|
|
env.Append(LINKFLAGS=frameworks)
|