Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ 2 alsa-lib, 3 autoPatchelfHook, 4 buildPackages, 5 callPackage, 6 dbus, 7 dotnetCorePackages, 8 exportTemplatesHash, 9 fetchFromGitHub, 10 fetchpatch, 11 fontconfig, 12 glib, 13 hash, 14 installShellFiles, 15 lib, 16 libdecor, 17 libGL, 18 libpulseaudio, 19 libX11, 20 libXcursor, 21 libXext, 22 libXfixes, 23 libXi, 24 libXinerama, 25 libxkbcommon, 26 libXrandr, 27 libXrender, 28 makeWrapper, 29 perl, 30 pkg-config, 31 runCommand, 32 scons, 33 speechd-minimal, 34 stdenv, 35 stdenvNoCC, 36 testers, 37 udev, 38 updateScript, 39 version, 40 vulkan-loader, 41 wayland, 42 wayland-scanner, 43 withAlsa ? true, 44 withDbus ? true, 45 withFontconfig ? true, 46 withMono ? false, 47 nugetDeps ? null, 48 withPlatform ? "linuxbsd", 49 withPrecision ? "single", 50 withPulseaudio ? true, 51 withSpeechd ? true, 52 withTouch ? true, 53 withUdev ? true, 54 # Wayland in Godot requires X11 until upstream fix is merged 55 # https://github.com/godotengine/godot/pull/73504 56 withWayland ? true, 57 withX11 ? true, 58}: 59assert lib.asserts.assertOneOf "withPrecision" withPrecision [ 60 "single" 61 "double" 62]; 63let 64 mkSconsFlagsFromAttrSet = lib.mapAttrsToList ( 65 k: v: if builtins.isString v then "${k}=${v}" else "${k}=${builtins.toJSON v}" 66 ); 67 68 arch = stdenv.hostPlatform.linuxArch; 69 70 dotnet-sdk = if withMono then dotnetCorePackages.sdk_8_0-source else null; 71 dotnet-sdk_alt = if withMono then dotnetCorePackages.sdk_9_0-source else null; 72 73 dottedVersion = lib.replaceStrings [ "-" ] [ "." ] version + lib.optionalString withMono ".mono"; 74 75 mkTarget = 76 target: 77 let 78 editor = target == "editor"; 79 suffix = lib.optionalString withMono "-mono" + lib.optionalString (!editor) "-template"; 80 binary = lib.concatStringsSep "." ( 81 [ 82 "godot" 83 withPlatform 84 target 85 ] 86 ++ lib.optional (withPrecision != "single") withPrecision 87 ++ [ arch ] 88 ++ lib.optional withMono "mono" 89 ); 90 91 mkTests = 92 pkg: dotnet-sdk: 93 { 94 version = testers.testVersion { 95 package = pkg; 96 version = dottedVersion; 97 }; 98 } 99 // lib.optionalAttrs (editor) ( 100 let 101 project-src = 102 runCommand "${pkg.name}-project-src" 103 { 104 nativeBuildInputs = [ pkg ] ++ lib.optional (dotnet-sdk != null) dotnet-sdk; 105 } 106 ( 107 '' 108 mkdir "$out" 109 cd "$out" 110 touch project.godot 111 112 cat >create-scene.gd <<'EOF' 113 extends SceneTree 114 115 func _initialize(): 116 var node = Node.new() 117 var script = ResourceLoader.load("res://test.gd") 118 node.set_script(script) 119 '' 120 + lib.optionalString withMono '' 121 ${""} 122 var monoNode = Node.new() 123 var monoScript = ResourceLoader.load("res://Test.cs") 124 monoNode.set_script(monoScript) 125 node.add_child(monoNode) 126 monoNode.owner = node 127 '' 128 + '' 129 var scene = PackedScene.new() 130 var scenePath = "res://test.tscn" 131 scene.pack(node) 132 node.free() 133 var x = ResourceSaver.save(scene, scenePath) 134 ProjectSettings["application/run/main_scene"] = scenePath 135 ProjectSettings.save() 136 quit() 137 EOF 138 139 cat >test.gd <<'EOF' 140 extends Node 141 func _ready(): 142 print("Hello, World!") 143 get_tree().quit() 144 EOF 145 146 cat >export_presets.cfg <<'EOF' 147 [preset.0] 148 name="build" 149 platform="Linux" 150 runnable=true 151 export_filter="all_resources" 152 include_filter="" 153 exclude_filter="" 154 [preset.0.options] 155 binary_format/architecture="${arch}" 156 EOF 157 '' 158 + lib.optionalString withMono '' 159 cat >Test.cs <<'EOF' 160 using Godot; 161 using System; 162 163 public partial class Test : Node 164 { 165 public override void _Ready() 166 { 167 GD.Print("Hello, Mono!"); 168 GetTree().Quit(); 169 } 170 } 171 EOF 172 173 sdk_version=$(basename ${pkg}/share/nuget/packages/godot.net.sdk/*) 174 cat >UnnamedProject.csproj <<EOF 175 <Project Sdk="Godot.NET.Sdk/$sdk_version"> 176 <PropertyGroup> 177 <TargetFramework>net${lib.versions.majorMinor (lib.defaultTo pkg.dotnet-sdk dotnet-sdk).version}</TargetFramework> 178 <EnableDynamicLoading>true</EnableDynamicLoading> 179 </PropertyGroup> 180 </Project> 181 EOF 182 183 configureNuget 184 185 dotnet new sln -n UnnamedProject 186 message=$(dotnet sln add UnnamedProject.csproj) 187 echo "$message" 188 # dotnet sln doesn't return an error when it fails to add the project 189 [[ $message == "Project \`UnnamedProject.csproj\` added to the solution." ]] 190 191 rm nuget.config 192 '' 193 ); 194 195 export-tests = lib.makeExtensible (final: { 196 inherit (pkg) export-template; 197 198 export = stdenvNoCC.mkDerivation { 199 name = "${final.export-template.name}-export"; 200 201 nativeBuildInputs = [ pkg ] ++ lib.optional (dotnet-sdk != null) dotnet-sdk; 202 203 src = project-src; 204 205 buildPhase = '' 206 runHook preBuild 207 208 export HOME=$(mktemp -d) 209 mkdir -p $HOME/.local/share/godot/ 210 ln -s "${final.export-template}"/share/godot/export_templates "$HOME"/.local/share/godot/ 211 212 godot${suffix} --headless --build-solutions -s create-scene.gd 213 214 runHook postBuild 215 ''; 216 217 installPhase = '' 218 runHook preInstall 219 220 mkdir -p "$out"/bin 221 godot${suffix} --headless --export-release build "$out"/bin/test 222 223 runHook postInstall 224 ''; 225 }; 226 227 run = runCommand "${final.export.name}-runs" { passthru = { inherit (final) export; }; } ( 228 '' 229 ( 230 set -eo pipefail 231 HOME=$(mktemp -d) 232 "${final.export}"/bin/test --headless | tail -n+3 | ( 233 '' 234 + lib.optionalString withMono '' 235 # indent 236 read output 237 if [[ "$output" != "Hello, Mono!" ]]; then 238 echo "unexpected output: $output" >&2 239 exit 1 240 fi 241 '' 242 + '' 243 read output 244 if [[ "$output" != "Hello, World!" ]]; then 245 echo "unexpected output: $output" >&2 246 exit 1 247 fi 248 ) 249 touch "$out" 250 ) 251 '' 252 ); 253 }); 254 255 in 256 { 257 export-runs = export-tests.run; 258 259 export-bin-runs = 260 (export-tests.extend ( 261 final: prev: { 262 export-template = pkg.export-templates-bin; 263 264 export = prev.export.overrideAttrs (prev: { 265 nativeBuildInputs = prev.nativeBuildInputs or [ ] ++ [ 266 autoPatchelfHook 267 ]; 268 269 # stripping dlls results in: 270 # Failed to load System.Private.CoreLib.dll (error code 0x8007000B) 271 stripExclude = lib.optional withMono [ "*.dll" ]; 272 273 runtimeDependencies = 274 prev.runtimeDependencies or [ ] 275 ++ map lib.getLib [ 276 alsa-lib 277 libpulseaudio 278 libX11 279 libXcursor 280 libXext 281 libXi 282 libXrandr 283 udev 284 vulkan-loader 285 ]; 286 }); 287 } 288 )).run; 289 } 290 ); 291 292 attrs = finalAttrs: rec { 293 pname = "godot${suffix}"; 294 inherit version; 295 296 src = fetchFromGitHub { 297 owner = "godotengine"; 298 repo = "godot"; 299 tag = version; 300 inherit hash; 301 # Required for the commit hash to be included in the version number. 302 # 303 # `methods.py` reads the commit hash from `.git/HEAD` and manually follows 304 # refs. 305 # 306 # See also 'hash' in 307 # https://docs.godotengine.org/en/stable/classes/class_engine.html#class-engine-method-get-version-info 308 leaveDotGit = true; 309 # Only keep HEAD, because leaveDotGit is non-deterministic: 310 # https://github.com/NixOS/nixpkgs/issues/8567 311 postFetch = '' 312 hash=$(git -C "$out" rev-parse HEAD) 313 rm -r "$out"/.git 314 mkdir "$out"/.git 315 echo "$hash" > "$out"/.git/HEAD 316 ''; 317 }; 318 319 outputs = [ 320 "out" 321 ] 322 ++ lib.optional (editor) "man"; 323 separateDebugInfo = true; 324 325 # Set the build name which is part of the version. In official downloads, this 326 # is set to 'official'. When not specified explicitly, it is set to 327 # 'custom_build'. Other platforms packaging Godot (Gentoo, Arch, Flatpack 328 # etc.) usually set this to their name as well. 329 # 330 # See also 'methods.py' in the Godot repo and 'build' in 331 # https://docs.godotengine.org/en/stable/classes/class_engine.html#class-engine-method-get-version-info 332 BUILD_NAME = "nixpkgs"; 333 334 preConfigure = lib.optionalString (editor && withMono) '' 335 # TODO: avoid pulling in dependencies of windows-only project 336 dotnet sln modules/mono/editor/GodotTools/GodotTools.sln \ 337 remove modules/mono/editor/GodotTools/GodotTools.OpenVisualStudio/GodotTools.OpenVisualStudio.csproj 338 339 dotnet restore modules/mono/glue/GodotSharp/GodotSharp.sln 340 dotnet restore modules/mono/editor/GodotTools/GodotTools.sln 341 dotnet restore modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln 342 ''; 343 344 # From: https://github.com/godotengine/godot/blob/4.2.2-stable/SConstruct 345 sconsFlags = mkSconsFlagsFromAttrSet { 346 # Options from 'SConstruct' 347 precision = withPrecision; # Floating-point precision level 348 production = true; # Set defaults to build Godot for use in production 349 platform = withPlatform; 350 inherit target; 351 debug_symbols = true; 352 353 # Options from 'platform/linuxbsd/detect.py' 354 alsa = withAlsa; 355 dbus = withDbus; # Use D-Bus to handle screensaver and portal desktop settings 356 fontconfig = withFontconfig; # Use fontconfig for system fonts support 357 pulseaudio = withPulseaudio; # Use PulseAudio 358 speechd = withSpeechd; # Use Speech Dispatcher for Text-to-Speech support 359 touch = withTouch; # Enable touch events 360 udev = withUdev; # Use udev for gamepad connection callbacks 361 wayland = withWayland; # Compile with Wayland support 362 x11 = withX11; # Compile with X11 support 363 364 module_mono_enabled = withMono; 365 366 # aliasing bugs exist with hardening+LTO 367 # https://github.com/godotengine/godot/pull/104501 368 ccflags = "-fno-strict-aliasing"; 369 linkflags = "-Wl,--build-id"; 370 371 use_sowrap = false; 372 }; 373 374 enableParallelBuilding = true; 375 376 strictDeps = true; 377 378 patches = lib.optionals (lib.versionOlder version "4.4") [ 379 (fetchpatch { 380 name = "wayland-header-fix.patch"; 381 url = "https://github.com/godotengine/godot/commit/6ce71f0fb0a091cffb6adb4af8ab3f716ad8930b.patch"; 382 hash = "sha256-hgAtAtCghF5InyGLdE9M+9PjPS1BWXWGKgIAyeuqkoU="; 383 }) 384 # Fix a crash in the mono test project build. It no longer seems to 385 # happen in 4.4, but an existing fix couldn't be identified. 386 ./CSharpLanguage-fix-crash-in-reload_assemblies-after-.patch 387 ]; 388 389 postPatch = '' 390 # this stops scons from hiding e.g. NIX_CFLAGS_COMPILE 391 perl -pi -e '{ $r += s:(env = Environment\(.*):\1\nenv["ENV"] = os.environ: } END { exit ($r != 1) }' SConstruct 392 393 substituteInPlace thirdparty/glad/egl.c \ 394 --replace-fail \ 395 'static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"}' \ 396 'static const char *NAMES[] = {"${lib.getLib libGL}/lib/libEGL.so"}' 397 398 substituteInPlace thirdparty/glad/gl.c \ 399 --replace-fail \ 400 'static const char *NAMES[] = {"libGLESv2.so.2", "libGLESv2.so"}' \ 401 'static const char *NAMES[] = {"${lib.getLib libGL}/lib/libGLESv2.so"}' \ 402 403 substituteInPlace thirdparty/glad/gl{,x}.c \ 404 --replace-fail \ 405 '"libGL.so.1"' \ 406 '"${lib.getLib libGL}/lib/libGL.so"' 407 408 substituteInPlace thirdparty/volk/volk.c \ 409 --replace-fail \ 410 'dlopen("libvulkan.so.1"' \ 411 'dlopen("${lib.getLib vulkan-loader}/lib/libvulkan.so"' 412 ''; 413 414 depsBuildBuild = lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [ 415 buildPackages.stdenv.cc 416 pkg-config 417 ]; 418 419 buildInputs = 420 lib.optionals (editor && withMono) dotnet-sdk.packages 421 ++ lib.optional withAlsa alsa-lib 422 ++ lib.optional (withX11 || withWayland) libxkbcommon 423 ++ lib.optionals withX11 [ 424 libX11 425 libXcursor 426 libXext 427 libXfixes 428 libXi 429 libXinerama 430 libXrandr 431 libXrender 432 ] 433 ++ lib.optionals withWayland [ 434 # libdecor 435 wayland 436 ] 437 ++ lib.optionals withDbus [ 438 dbus 439 ] 440 ++ lib.optionals withFontconfig [ 441 fontconfig 442 ] 443 ++ lib.optional withPulseaudio libpulseaudio 444 ++ lib.optionals withSpeechd [ 445 speechd-minimal 446 glib 447 ] 448 ++ lib.optional withUdev udev; 449 450 nativeBuildInputs = [ 451 installShellFiles 452 perl 453 pkg-config 454 scons 455 ] 456 ++ lib.optionals withWayland [ wayland-scanner ] 457 ++ lib.optional (editor && withMono) [ 458 makeWrapper 459 dotnet-sdk 460 ]; 461 462 postBuild = lib.optionalString (editor && withMono) '' 463 echo "Generating Glue" 464 bin/${binary} --headless --generate-mono-glue modules/mono/glue 465 echo "Building C#/.NET Assemblies" 466 python modules/mono/build_scripts/build_assemblies.py --godot-output-dir bin --precision=${withPrecision} 467 ''; 468 469 installPhase = '' 470 runHook preInstall 471 472 mkdir -p "$out"/{bin,libexec} 473 cp -r bin/* "$out"/libexec 474 475 cd "$out"/bin 476 ln -s ../libexec/${binary} godot${lib.versions.majorMinor version}${suffix} 477 ln -s godot${lib.versions.majorMinor version}${suffix} godot${lib.versions.major version}${suffix} 478 ln -s godot${lib.versions.major version}${suffix} godot${suffix} 479 cd - 480 '' 481 + ( 482 if editor then 483 '' 484 installManPage misc/dist/linux/godot.6 485 486 mkdir -p "$out"/share/{applications,icons/hicolor/scalable/apps} 487 cp misc/dist/linux/org.godotengine.Godot.desktop \ 488 "$out/share/applications/org.godotengine.Godot${lib.versions.majorMinor version}${suffix}.desktop" 489 490 substituteInPlace "$out/share/applications/org.godotengine.Godot${lib.versions.majorMinor version}${suffix}.desktop" \ 491 --replace-fail "Exec=godot" "Exec=$out/bin/godot${suffix}" \ 492 --replace-fail "Godot Engine" "Godot Engine ${ 493 lib.versions.majorMinor version + lib.optionalString withMono " (Mono)" 494 }" 495 cp icon.svg "$out/share/icons/hicolor/scalable/apps/godot.svg" 496 cp icon.png "$out/share/icons/godot.png" 497 '' 498 + lib.optionalString withMono '' 499 mkdir -p "$out"/share/nuget 500 mv "$out"/libexec/GodotSharp/Tools/nupkgs "$out"/share/nuget/source 501 502 wrapProgram "$out"/libexec/${binary} \ 503 --prefix NUGET_FALLBACK_PACKAGES ';' "$out"/share/nuget/packages/ 504 '' 505 else 506 let 507 template = 508 (lib.replaceStrings 509 [ "template" ] 510 [ 511 { 512 linuxbsd = "linux"; 513 } 514 .${withPlatform} 515 ] 516 target 517 ) 518 + "." 519 + arch; 520 in 521 '' 522 templates="$out"/share/godot/export_templates/${dottedVersion} 523 mkdir -p "$templates" 524 ln -s "$out"/libexec/${binary} "$templates"/${template} 525 '' 526 ) 527 + '' 528 runHook postInstall 529 ''; 530 531 passthru = { 532 inherit updateScript; 533 tests = 534 mkTests finalAttrs.finalPackage dotnet-sdk 535 // lib.optionalAttrs (editor && withMono) { 536 sdk-override = mkTests finalAttrs.finalPackage dotnet-sdk_alt; 537 }; 538 } 539 // lib.optionalAttrs editor { 540 export-template = mkTarget "template_release"; 541 export-templates-bin = ( 542 callPackage ./export-templates-bin.nix { 543 inherit version withMono; 544 godot = finalAttrs.finalPackage; 545 hash = exportTemplatesHash; 546 } 547 ); 548 }; 549 550 requiredSystemFeatures = [ 551 # fixes: No space left on device 552 "big-parallel" 553 ]; 554 555 meta = { 556 changelog = "https://github.com/godotengine/godot/releases/tag/${version}"; 557 description = "Free and Open Source 2D and 3D game engine"; 558 homepage = "https://godotengine.org"; 559 license = lib.licenses.mit; 560 platforms = [ 561 "x86_64-linux" 562 "aarch64-linux" 563 ] 564 ++ lib.optional (!withMono) "i686-linux"; 565 maintainers = with lib.maintainers; [ 566 shiryel 567 corngood 568 ]; 569 mainProgram = "godot${suffix}"; 570 }; 571 }; 572 573 unwrapped = stdenv.mkDerivation ( 574 if (editor && withMono) then 575 dotnetCorePackages.addNuGetDeps { 576 inherit nugetDeps; 577 overrideFetchAttrs = old: rec { 578 runtimeIds = map (system: dotnetCorePackages.systemToDotnetRid system) old.meta.platforms; 579 buildInputs = 580 old.buildInputs 581 ++ lib.concatLists (lib.attrValues (lib.getAttrs runtimeIds dotnet-sdk.targetPackages)); 582 }; 583 } attrs 584 else 585 attrs 586 ); 587 588 wrapper = 589 if (editor && withMono) then 590 stdenv.mkDerivation (finalAttrs: { 591 __structuredAttrs = true; 592 593 pname = finalAttrs.unwrapped.pname + "-wrapper"; 594 inherit (finalAttrs.unwrapped) version outputs meta; 595 inherit unwrapped dotnet-sdk; 596 597 dontUnpack = true; 598 dontConfigure = true; 599 dontBuild = true; 600 601 nativeBuildInputs = [ makeWrapper ]; 602 strictDeps = true; 603 604 installPhase = '' 605 runHook preInstall 606 607 mkdir -p "$out"/{bin,libexec,share/applications,nix-support} 608 609 cp -d "$unwrapped"/bin/* "$out"/bin/ 610 ln -s "$unwrapped"/libexec/* "$out"/libexec/ 611 ln -s "$unwrapped"/share/nuget "$out"/share/ 612 cp "$unwrapped/share/applications/org.godotengine.Godot${lib.versions.majorMinor version}${suffix}.desktop" \ 613 "$out/share/applications/org.godotengine.Godot${lib.versions.majorMinor version}${suffix}.desktop" 614 615 substituteInPlace "$out/share/applications/org.godotengine.Godot${lib.versions.majorMinor version}${suffix}.desktop" \ 616 --replace-fail "Exec=$unwrapped/bin/godot${suffix}" "Exec=$out/bin/godot${suffix}" 617 ln -s "$unwrapped"/share/icons $out/share/ 618 619 # ensure dotnet hooks get run 620 echo "${finalAttrs.dotnet-sdk}" >> "$out"/nix-support/propagated-build-inputs 621 622 wrapProgram "$out"/libexec/${binary} \ 623 --prefix PATH : "${lib.makeBinPath [ finalAttrs.dotnet-sdk ]}" 624 625 runHook postInstall 626 ''; 627 628 postFixup = lib.concatMapStringsSep "\n" (output: '' 629 [[ -e "''$${output}" ]] || ln -s "${unwrapped.${output}}" "''$${output}" 630 '') finalAttrs.unwrapped.outputs; 631 632 passthru = unwrapped.passthru // { 633 tests = mkTests finalAttrs.finalPackage null // { 634 unwrapped = lib.recurseIntoAttrs unwrapped.tests; 635 sdk-override = lib.recurseIntoAttrs ( 636 mkTests (finalAttrs.finalPackage.overrideAttrs { dotnet-sdk = dotnet-sdk_alt; }) null 637 ); 638 }; 639 }; 640 }) 641 else 642 unwrapped; 643 in 644 wrapper; 645in 646mkTarget "editor"