godot: add darwin support (#420528)

This commit is contained in:
David McFarland
2026-01-28 19:33:08 +00:00
committed by GitHub
2 changed files with 206 additions and 77 deletions
+190 -77
View File
@@ -1,8 +1,10 @@
{
alsa-lib,
apple-sdk_26,
autoPatchelfHook,
buildPackages,
callPackage,
darwin,
dbus,
dotnetCorePackages,
embree,
@@ -38,6 +40,7 @@
makeWrapper,
mbedtls,
miniupnpc,
moltenvk,
openxr-loader,
pcre2,
perl,
@@ -49,29 +52,34 @@
speechd-minimal,
stdenv,
stdenvNoCC,
strip-nondeterminism,
testers,
udev,
unzip,
updateScript,
version,
vulkan-loader,
wayland,
wayland-scanner,
withAlsa ? true,
withAlsa ? stdenv.hostPlatform.isLinux,
withDbus ? true,
withFontconfig ? true,
withMono ? false,
nugetDeps ? null,
withPlatform ? "linuxbsd",
# only linux supports builtin_ flags properly
withBuiltins ? !stdenv.hostPlatform.isLinux,
withPlatform ? if stdenv.hostPlatform.isDarwin then "macos" else "linuxbsd",
withPrecision ? "single",
withPulseaudio ? true,
withSpeechd ? true,
withTouch ? true,
withUdev ? true,
withUdev ? stdenv.hostPlatform.isLinux,
# Wayland in Godot requires X11 until upstream fix is merged
# https://github.com/godotengine/godot/pull/73504
withWayland ? true,
withX11 ? true,
withWayland ? stdenv.hostPlatform.isLinux,
withX11 ? stdenv.hostPlatform.isLinux,
wslay,
zip,
zstd,
}:
assert lib.asserts.assertOneOf "withPrecision" withPrecision [
@@ -90,6 +98,8 @@ let
dottedVersion = lib.replaceStrings [ "-" ] [ "." ] version + lib.optionalString withMono ".mono";
harfbuzz-icu = harfbuzz.override { withIcu = true; };
mkTarget =
target:
let
@@ -116,8 +126,14 @@ let
}
// lib.optionalAttrs editor (
let
platform =
{
linuxbsd = "Linux";
macos = "macOS";
}
.${withPlatform};
project-src =
runCommand "${pkg.name}-project-src"
runCommand "${pkg.name}-6"
{
nativeBuildInputs = [ pkg ] ++ lib.optional (dotnet-sdk != null) dotnet-sdk;
}
@@ -144,12 +160,19 @@ let
monoNode.owner = node
''
+ ''
${""}
var scene = PackedScene.new()
var scenePath = "res://test.tscn"
scene.pack(node)
node.free()
var x = ResourceSaver.save(scene, scenePath)
ProjectSettings["application/run/main_scene"] = scenePath
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
${""}
ProjectSettings["rendering/textures/vram_compression/import_etc2_astc"] = true
''
+ ''
ProjectSettings.save()
quit()
EOF
@@ -164,13 +187,18 @@ let
cat >export_presets.cfg <<'EOF'
[preset.0]
name="build"
platform="Linux"
platform="${platform}"
runnable=true
export_filter="all_resources"
include_filter=""
exclude_filter=""
[preset.0.options]
binary_format/architecture="${arch}"
binary_format/architecture="${if stdenv.hostPlatform.isDarwin then "universal" else arch}"
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
application/bundle_identifier="test"
''
+ ''
EOF
''
+ lib.optionalString withMono ''
@@ -224,8 +252,11 @@ let
runHook preBuild
export HOME=$(mktemp -d)
mkdir -p $HOME/.local/share/godot/
ln -s "${final.export-template}"/share/godot/export_templates "$HOME"/.local/share/godot/
local dataDir="$HOME/${
if stdenv.hostPlatform.isDarwin then "Library/Application Support/Godot" else ".local/share/godot"
}/"
mkdir -p "$dataDir"
ln -s "${final.export-template}"/share/godot/export_templates "$dataDir"
godot${suffix} --headless --build-solutions -s create-scene.gd
@@ -236,7 +267,7 @@ let
runHook preInstall
mkdir -p "$out"/bin
godot${suffix} --headless --export-release build "$out"/bin/test
godot${suffix} --headless --export-release build "$out"/bin/test${lib.optionalString stdenv.hostPlatform.isDarwin ".app"}
runHook postInstall
'';
@@ -247,7 +278,7 @@ let
(
set -eo pipefail
HOME=$(mktemp -d)
"${final.export}"/bin/test --headless | tail -n+3 | (
"${final.export}"/bin/test${lib.optionalString stdenv.hostPlatform.isDarwin ".app/Contents/MacOS/Unnamed"} --headless | tail -n+3 | (
''
+ lib.optionalString withMono ''
# indent
@@ -280,9 +311,8 @@ let
export-template = pkg.export-templates-bin;
export = prev.export.overrideAttrs (prev: {
nativeBuildInputs = prev.nativeBuildInputs or [ ] ++ [
autoPatchelfHook
];
nativeBuildInputs =
prev.nativeBuildInputs or [ ] ++ lib.optional stdenv.hostPlatform.isElf autoPatchelfHook;
# stripping dlls results in:
# Failed to load System.Private.CoreLib.dll (error code 0x8007000B)
@@ -291,15 +321,17 @@ let
runtimeDependencies =
prev.runtimeDependencies or [ ]
++ map lib.getLib [
alsa-lib
libpulseaudio
libX11
libXcursor
libXext
libXi
libXrandr
udev
vulkan-loader
]
++ lib.optionals stdenv.hostPlatform.isLinux [
alsa-lib
udev
];
});
}
@@ -359,6 +391,11 @@ let
dotnet restore modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
'';
# darwin needs $HOME/.cache/clang/ModuleCache
preBuild = lib.optionalString stdenv.hostPlatform.isDarwin ''
export HOME=$(mktemp -d)
'';
# From: https://github.com/godotengine/godot/blob/4.2.2-stable/SConstruct
sconsFlags = mkSconsFlagsFromAttrSet (
{
@@ -385,7 +422,8 @@ let
# aliasing bugs exist with hardening+LTO
# https://github.com/godotengine/godot/pull/104501
ccflags = "-fno-strict-aliasing";
linkflags = "-Wl,--build-id";
# on darwin: ld: unknown option: --build-id
linkflags = lib.optionalString (!stdenv.hostPlatform.isDarwin) "-Wl,--build-id";
# libraries that aren't available in nixpkgs
builtin_msdfgen = true;
@@ -408,12 +446,19 @@ let
// lib.optionalAttrs (lib.versionAtLeast version "4.5") {
redirect_build_objects = false; # Avoid copying build objects to output
}
// lib.optionalAttrs stdenv.hostPlatform.isDarwin {
generate_bundle = "yes";
}
);
enableParallelBuilding = true;
strictDeps = true;
propagatedSandboxProfile = lib.optionalString stdenv.hostPlatform.isDarwin ''
(allow file-read* (subpath "/System/Library/CoreServices/SystemAppearance.bundle"))
'';
patches = [
./Linux-fix-missing-library-with-builtin_glslang-false.patch
]
@@ -431,12 +476,17 @@ let
# Fix a crash in the mono test project build. It no longer seems to
# happen in 4.4, but an existing fix couldn't be identified.
./CSharpLanguage-fix-crash-in-reload_assemblies-after-.patch
];
]
++ lib.optional (
stdenv.hostPlatform.isDarwin && lib.versionAtLeast version "4.4"
) ./fix-moltenvk-detection.patch;
postPatch = ''
# this stops scons from hiding e.g. NIX_CFLAGS_COMPILE
perl -pi -e '{ $r += s:(env = Environment\(.*):\1\nenv["ENV"] = os.environ: } END { exit ($r != 1) }' SConstruct
''
+ lib.optionalString (!withBuiltins) ''
# disable all builtin libraries by default
perl -pi -e '{ $r |= s:(opts.Add\(BoolVariable\("builtin_.*, )True(\)\)):\1False\2: } END { exit ($r != 1) }' SConstruct
@@ -444,9 +494,8 @@ let
+ lib.optionalString (lib.versionOlder version "4.6") ''
substituteInPlace platform/linuxbsd/detect.py \
--replace-fail /usr/include/recastnavigation ${lib.escapeShellArg (lib.getDev recastnavigation)}/include/recastnavigation
''
+ ''
+ lib.optionalString (libGL != null) ''
substituteInPlace thirdparty/glad/egl.c \
--replace-fail \
'static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"}' \
@@ -461,69 +510,103 @@ let
--replace-fail \
'"libGL.so.1"' \
'"${lib.getLib libGL}/lib/libGL.so"'
''
+ ''
substituteInPlace thirdparty/volk/volk.c \
--replace-fail \
'dlopen("libvulkan.so.1"' \
'dlopen("${lib.getLib vulkan-loader}/lib/libvulkan.so"'
'';
''
+ lib.optionalString stdenv.hostPlatform.isDarwin (
''
substituteInPlace platform/macos/export/export_plugin.cpp \
--replace-fail \
/usr/bin/codesign \
'${lib.getExe' darwin.sigtool "sigtool"}'
''
# https://github.com/godotengine/godot/issues/107199
+ lib.optionalString (lib.versionAtLeast version "4.5") ''
substituteInPlace drivers/metal/SCsub \
--replace-fail \
'env_metal.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])' \
""
''
# godot zips these files and fails if mtime < 1980
+ lib.optionalString (!editor) ''
find misc/dist/macos_template.app -exec touch {} \;
''
);
depsBuildBuild = lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
buildPackages.stdenv.cc
pkg-config
];
buildInputs = [
embree
enet
freetype
glslang
graphite2
(harfbuzz.override { withIcu = true; })
icu
libtheora
libwebp
mbedtls
miniupnpc
openxr-loader
pcre2
recastnavigation
wslay
zstd
]
++ lib.optionals (lib.versionAtLeast version "4.5") [
libjpeg_turbo
sdl3
]
++ lib.optionals (editor && withMono) dotnet-sdk.packages
++ lib.optional withAlsa alsa-lib
++ lib.optional (withX11 || withWayland) libxkbcommon
++ lib.optionals withX11 [
libX11
libXcursor
libXext
libXfixes
libXi
libXinerama
libXrandr
libXrender
]
++ lib.optionals withWayland [
libdecor
wayland
]
++ lib.optionals withDbus [
dbus
]
++ lib.optionals withFontconfig [
fontconfig
]
++ lib.optional withPulseaudio libpulseaudio
++ lib.optionals withSpeechd [
speechd-minimal
glib
]
++ lib.optional withUdev udev;
env.NIX_CFLAGS_COMPILE = toString (
lib.optionals stdenv.hostPlatform.isDarwin [
"-I${lib.getDev harfbuzz-icu}/include/harfbuzz"
"-I${lib.getDev recastnavigation}/include/recastnavigation"
]
);
buildInputs =
lib.optionals (!withBuiltins) (
[
embree
enet
freetype
glslang
graphite2
harfbuzz-icu
icu
libtheora
libwebp
mbedtls
miniupnpc
openxr-loader
pcre2
recastnavigation
wslay
zstd
]
++ lib.optionals (lib.versionAtLeast version "4.5") [
libjpeg_turbo
sdl3
]
)
++ lib.optionals (editor && withMono) dotnet-sdk.packages
++ lib.optional withAlsa alsa-lib
++ lib.optional (withX11 || withWayland) libxkbcommon
++ lib.optionals withX11 [
libX11
libXcursor
libXext
libXfixes
libXi
libXinerama
libXrandr
libXrender
]
++ lib.optionals withWayland [
libdecor
wayland
]
++ lib.optionals withDbus [
dbus
]
++ lib.optionals withFontconfig [
fontconfig
]
++ lib.optional withPulseaudio libpulseaudio
++ lib.optionals withSpeechd [
speechd-minimal
glib
]
++ lib.optional withUdev udev
++ lib.optionals stdenv.hostPlatform.isDarwin [
apple-sdk_26
moltenvk
];
nativeBuildInputs = [
installShellFiles
@@ -535,7 +618,17 @@ let
++ lib.optional (editor && withMono) [
makeWrapper
dotnet-sdk
];
]
++ lib.optionals stdenv.hostPlatform.isDarwin (
[
darwin.sigtool
]
++ lib.optionals (!editor) [
strip-nondeterminism
unzip
zip
]
);
postBuild = lib.optionalString (editor && withMono) ''
echo "Generating Glue"
@@ -548,7 +641,7 @@ let
runHook preInstall
mkdir -p "$out"/{bin,libexec}
cp -r bin/* "$out"/libexec
cp -r bin/${binary} "$out"/libexec/
cd "$out"/bin
ln -s ../libexec/${binary} godot${lib.versions.majorMinor version}${suffix}
@@ -574,12 +667,17 @@ let
cp icon.png "$out/share/icons/godot.png"
''
+ lib.optionalString withMono ''
cp -r bin/GodotSharp "$out"/libexec/
mkdir -p "$out"/share/nuget
mv "$out"/libexec/GodotSharp/Tools/nupkgs "$out"/share/nuget/source
wrapProgram "$out"/libexec/${binary} \
--prefix NUGET_FALLBACK_PACKAGES ';' "$out"/share/nuget/packages/
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
mkdir -p "$out"/Applications
cp -r bin/godot_macos_editor.app "$out"/Applications/Godot.app
''
else
let
template =
@@ -588,6 +686,7 @@ let
[
{
linuxbsd = "linux";
macos = "macos";
}
.${withPlatform}
]
@@ -601,6 +700,15 @@ let
mkdir -p "$templates"
ln -s "$out"/libexec/${binary} "$templates"/${template}
''
# TODO: teach godot to use a template that isn't zipped. for now we
# just need to make it uncompressed so it doesn't break dependencies
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
cd bin
unzip godot_macos${lib.optionalString withMono "_mono"}.zip
zip -rq0 "$templates"/macos.zip macos_template.app
strip-nondeterminism --type zip "$templates"/macos.zip
cd -
''
)
+ ''
runHook postInstall
@@ -639,7 +747,12 @@ let
"x86_64-linux"
"aarch64-linux"
]
++ lib.optional (!withMono) "i686-linux";
++ lib.optional (!withMono) "i686-linux"
# 4.3 doesn't compile on darwin, and 4.4 doesn't pass tests
++ lib.optionals (lib.versionAtLeast version "4.5") [
"x86_64-darwin"
"aarch64-darwin"
];
maintainers = with lib.maintainers; [
shiryel
corngood
@@ -0,0 +1,16 @@
diff --git a/platform/macos/detect.py b/platform/macos/detect.py
index 227738877d..5a4bfa77d9 100644
--- a/platform/macos/detect.py
+++ b/platform/macos/detect.py
@@ -265,11 +265,6 @@ def configure(env: "SConsEnvironment"):
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]]