···11+{ godot3-mono }:
22+33+godot3-mono.overrideAttrs (self: base: {
44+ pname = "godot3-mono-export-templates";
55+ godotBuildDescription = "nix mono export templates";
66+77+ # As described in default.nix, adding the link flags to pulseaudio in detect.py was necessary to
88+ # allow the dlopen calls to succeed in Nix builds of godot. However, it seems that this *breaks*
99+ # the export templates, resulting in programs exported from godot using these export templates to
1010+ # be unable to load this library.
1111+ shouldAddLinkFlagsToPulse = false;
1212+1313+ shouldBuildTools = false;
1414+ godotBuildTarget = "release";
1515+ godotBinInstallPath = "share/godot/templates/${self.version}.stable.mono";
1616+ installedGodotBinName = "linux_${self.godotBuildPlatform}_64_${self.godotBuildTarget}";
1717+1818+ # https://docs.godotengine.org/en/stable/development/compiling/optimizing_for_size.html
1919+ # Stripping reduces the template size from around 500MB to 40MB for Linux.
2020+ # This also impacts the size of the exported games.
2121+ # This is added explicitly here because mkDerivation does not automatically
2222+ # strip binaries in the template directory.
2323+ stripAllList = (base.stripAllList or []) ++ [ "share/godot/templates" ];
2424+2525+ meta = base.meta // {
2626+ homepage = "https://docs.godotengine.org/en/stable/development/compiling/compiling_with_mono.html#export-templates";
2727+ };
2828+})
+66
pkgs/development/tools/godot/3/mono/glue.nix
···11+{ godot3, mono }:
22+33+godot3.overrideAttrs (self: base: {
44+ pname = "godot3-mono-glue";
55+ godotBuildDescription = "mono glue";
66+ godotBuildPlatform = "server";
77+88+ sconsFlags = base.sconsFlags ++ [
99+ "module_mono_enabled=true"
1010+ "mono_glue=false" # Indicates not to expect already existing glue.
1111+ "mono_prefix=${mono}"
1212+ ];
1313+1414+ nativeBuildInputs = base.nativeBuildInputs ++ [ mono ];
1515+1616+ patches =
1717+ base.patches ++
1818+ map (rp: ./patches + rp) (
1919+ [
2020+ # When building godot mono, a "glue version" gets baked into it, and into the mono glue code
2121+ # generated by it. Godot mono export templates are also get a glue version baked in. If you
2222+ # export a godot mono project using an export template for which the glue version doesn't
2323+ # match that of the godot mono tool itself, then the resulting game will fail with an error
2424+ # saying "The assembly 'GodotSharp' is out of sync." Thus, if we want our build of godot mono
2525+ # to be compatible with the official export templates, we need to ensure it is built with the
2626+ # same glue version as the official build.
2727+ #
2828+ # A python script in the godot source, i.e. modules/mono/build_scripts/gen_cs_glue_version.py,
2929+ # is used by the build process to generate the glue version number. The official version of it
3030+ # does so based on the latest modified time of all the C# files in the GodotSharp solution. This
3131+ # is problematic because it is difficult to reproduce the exact timestamps that the files had
3232+ # when the official build was created. This is further complicated by the fact that nix clears
3333+ # the timestamps on the source files when they're unpacked. Thus, we can't simply regenerate the
3434+ # official glue version by building from the official source.
3535+ #
3636+ # To address this, we are patching the python script with a hard-coded glue version number. This
3737+ # patch file needs to be updated for every new version of godot, so to enforce this, the godot
3838+ # version is baked in to the file name, causing the build to fail until the patch is updated.
3939+ #
4040+ # The correct glue version number for a given godot version is obtained by running the official
4141+ # build of that version of godot with the --generate-mono-glue flag. This generates the mono
4242+ # glue files. One of those files, mono_glue.gen.cpp, has a function called get_cs_glue_version()
4343+ # which contains a hard-coded number. This is the glue version to put in the patch file.
4444+ #
4545+ # For convenience, the accompanying update-glue-version.sh script automates this work. Run it by
4646+ # passing the godot version as an argument, e.g. "3.5.2".
4747+ "/gen_cs_glue_version.py/hardcodeGlueVersion_${self.version}.patch"
4848+ ]
4949+ );
5050+5151+ outputs = [ "out" ];
5252+5353+ installPhase = ''
5454+ runHook preInstall
5555+5656+ glue="$out"/modules/mono/glue
5757+ mkdir -p "$glue"
5858+ bin/godot_server.x11.opt.tools.*.mono --generate-mono-glue "$glue"
5959+6060+ runHook postInstall
6161+ '';
6262+6363+ meta = base.meta // {
6464+ homepage = "https://docs.godotengine.org/en/stable/development/compiling/compiling_with_mono.html#generate-the-glue";
6565+ };
6666+})
···11+{ godot3-mono, nuget-to-nix }:
22+33+godot3-mono.overrideAttrs (self: base: {
44+ pname = "godot3-mono-make-deps";
55+66+ nativeBuildInputs = base.nativeBuildInputs ++ [ nuget-to-nix ];
77+88+ nugetDeps = null;
99+ nugetSource = null;
1010+ nugetConfig = null;
1111+1212+ shouldConfigureNuget = false;
1313+1414+ outputs = [ "out" ];
1515+ buildPhase = " ";
1616+ installPhase = ''echo "No output intended. Run make-deps.sh instead." > $out'';
1717+1818+ # This script is used to update the accompanying deps.nix file, a nix expression listing the
1919+ # nuget packages that the godot-mono code depends on, along with their sha256 hashes. This
2020+ # file is referenced by the godot-mono derivation and needs to be updated every time the
2121+ # godot version is updated. The way it works is:
2222+ #
2323+ # 1) Creates and navigates to a temporary directory and then explicitly runs the unpack,
2424+ # patch, and configure phases from the godot-mono derivation.
2525+ # 2) Instead of building at this point, a nuget restore is performed, downloading all the
2626+ # nuget dependencies of godot-mono into a local folder.
2727+ # 3) Once these have been downloaded, the nuget-to-nix tool is used to generate a nix
2828+ # expression listing the locally obtained nuget packages, along with their sha256 hashes.
2929+ # 4) This nix expression is saved as deps.nix in the PWD.
3030+ #
3131+ # This process is impure, because it entails downloading files with unknown hashes, so it
3232+ # is run manually by the maintainer within a nix-shell environment. Running the accompanying
3333+ # make-deps.sh instead simplifies this.
3434+ makeDeps = ''
3535+ set -e
3636+ outdir="$(pwd)"
3737+ wrkdir="$(mktemp -d)"
3838+ trap 'rm -rf -- "$wrkdir"' EXIT
3939+ pushd "$wrkdir" > /dev/null
4040+ unpackPhase
4141+ cd source
4242+ patchPhase
4343+ configurePhase
4444+4545+ # Without RestorePackagesPath set, it restores packages to a temp directory. Specifying
4646+ # a path ensures we have a place to run nuget-to-nix.
4747+ nugetRestore() { dotnet msbuild -t:Restore -p:RestorePackagesPath=nugetPackages $1; }
4848+4949+ nugetRestore modules/mono/glue/GodotSharp/GodotSharp.sln
5050+ nugetRestore modules/mono/editor/GodotTools/GodotTools.sln
5151+5252+ nuget-to-nix nugetPackages > "$outdir"/deps.nix
5353+ popd > /dev/null
5454+ '';
5555+5656+ meta = base.meta // {
5757+ description = "Derivation with no output that exists to provide an environment for make-deps.sh";
5858+ };
5959+})
···11+diff --git a/modules/mono/build_scripts/gen_cs_glue_version.py b/modules/mono/build_scripts/gen_cs_glue_version.py
22+index 98bbb4d9be..5189f2551b 100644
33+--- a/modules/mono/build_scripts/gen_cs_glue_version.py
44++++ b/modules/mono/build_scripts/gen_cs_glue_version.py
55+@@ -1,16 +1,5 @@
66+ def generate_header(solution_dir, version_header_dst):
77+- import os
88+-
99+- latest_mtime = 0
1010+- for root, dirs, files in os.walk(solution_dir, topdown=True):
1111+- dirs[:] = [d for d in dirs if d not in ["Generated"]] # Ignored generated files
1212+- files = [f for f in files if f.endswith(".cs")]
1313+- for file in files:
1414+- filepath = os.path.join(root, file)
1515+- mtime = os.path.getmtime(filepath)
1616+- latest_mtime = mtime if mtime > latest_mtime else latest_mtime
1717+-
1818+- glue_version = int(latest_mtime) # The latest modified time will do for now
1919++ glue_version = 1678112021
2020+2121+ with open(version_header_dst, "w") as version_header:
2222+ version_header.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")