forked from IllustratedMan-code/Godot-Flake
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgodot.nix
More file actions
263 lines (236 loc) · 7.54 KB
/
godot.nix
File metadata and controls
263 lines (236 loc) · 7.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# Godot.nix
# this modules focuses on building godot
{ pkgs, inputs }:
# the "real" function inputs
{ name ? "godot", profile ? "", options ? { }, withTemplates ? true
, withBindings ? true, ... }:
with builtins;
let
# shortcuts
inherit (pkgs) lib stdenv stdenvNoCC system;
# get the godot version with IFD
version = let
# get version file from godot itself
godotVersionFile = stdenvNoCC.mkDerivation {
src = inputs.godot;
name = "godot-version";
noBuildPhase = true;
installPhase = ''
mkdir -p "$out/"
cp version.py $out/version.py
'';
};
removeChars = l: str:
lib.strings.stringAsChars (x: if (any (c: x == c) l) then "" else x) str;
splitLine = lstr: (lib.strings.splitString "\n" lstr);
removeEmpty = l: filter (x: x != "") l;
hasAllAttrs = names: set: all (x: x) (map (a: hasAttr a set) names);
mkPair = str:
let split = (lib.strings.splitString " = " str);
in lib.attrsets.nameValuePair (elemAt split 0) (elemAt split 1);
godotVersionAttrs = builtins.listToAttrs (map mkPair (removeEmpty
(map (removeChars [ "\n" ''"'' ])
(splitLine (readFile "${godotVersionFile}/version.py")))));
# build AttrSet
in ({
asString =
"${godotVersionAttrs.major}.${godotVersionAttrs.minor}.${godotVersionAttrs.patch}-${godotVersionAttrs.status}";
} // godotVersionAttrs);
# default godot from nix (for meta)
nix-godot = pkgs.godot_4;
# x86_64-linux -> linux
# aarch64-linux -> linux
# aarch64-darwin -> darwin
platform = let
regex = "[\\w\\_\\-]*-([a-zA-Z]+)";
getElem = x: elemAt (elemAt (x) 1) 0;
in getElem (split regex system);
# default options for building godot in production (.ie for using it)
defaultOptions = {
optimize = "speed"; # default is "speed_trace"
lto = "full"; # godot default is "none";
production = true; # godot default is false
use_volk = false; # godot default is true;
};
# get the option (to have correct libs)
condGet = n: s: d: if hasAttr n s then getAttr n s else d;
getOption = opt: def: condGet opt options (condGet opt defaultOptions def);
# parse options :
use_x11 = getOption "x11" true;
use_llvm = getOption "llvm" false;
use_openGL = getOption "opengl3" true;
use_vulkan = getOption "vulkan" true;
use_mono = getOption "module_mono_enabled" false;
condLib = c: l: if c then l else [ ];
# mono/C#
# TODO : test what version of mono/dotnet is required
libMono = with pkgs; [ mono6 msbuild dotnetPackages.Nuget ];
# llvm compiler
libllvm = with pkgs; [
llvm
lld
clang
clangStdenv
llvmPackages.libcxxClang
llvmPackages.clangUseLLVM
];
# x11 libraries
libXorg = with pkgs.xorg; [
libX11
libXcursor
libXi
libXinerama
libXrandr
libXrender
libXext
libXfixes
];
libVulkan = with pkgs; [ vulkan-loader vulkan-headers vulkan-tools ];
# OpenGL libraries
libOpenGL = with pkgs; [
glslang
libGLU
libGL
]; # ++ [pkgs.nixgl.auto.nixGLDefault];
# absolutely needed libs for runtime
libRuntime = with pkgs; [
udev
systemd
systemd.dev
libpulseaudio
freetype
openssl
alsa-lib
fontconfig.lib
speechd
libxkbcommon
dbus.lib
];
buildTools = with pkgs;
[
scons
pkg-config
installShellFiles
autoPatchelfHook
bashInteractive
patchelf
gcc
] ++ condLib use_llvm libllvm;
# runtime dependencies
runtimeDependencies = libRuntime ++ condLib use_x11 libXorg
++ condLib use_mono libMono ++ condLib use_openGL libOpenGL
++ condLib use_vulkan libVulkan;
# As a rule of thumb: Buildtools as nativeBuildInputs,
# libraries and executables you only need after the build as buildInputs
nativeBuildInputs = buildTools ++ condLib use_x11 libXorg
++ condLib use_openGL libOpenGL ++ condLib use_mono libMono
++ condLib use_vulkan libVulkan;
buildInputs = [ pkgs.zlib pkgs.yasm ] ++ condLib use_x11 libXorg
++ condLib use_openGL libOpenGL ++ condLib use_mono libMono
++ condLib use_vulkan libVulkan;
# turn option set into scons options
mkSconsOptions = optionSet:
let
condAttr = n: s: d: if hasAttr n s then getAttr n s else d;
boolToString = cond: if cond then "yes" else "no";
in (lib.mapAttrsToList (k: v:
if (lib.isBool v) then
("${k}=${boolToString v}")
else if (lib.isString v) then
("${k}=${v}")
else
"${k}=${toJSON v}") optionSet);
# sconsFlags for everyone
mkSconsFlags = target:
[
("platform=${platform}")
("target=${target}")
("tools=${if target == "editor" then "yes" else "no"}")
] ++ (if (profile != "") then
[ "profile=${profile}" ]
else
(mkSconsOptions options));
# the editor
godot-editor = stdenv.mkDerivation {
inherit nativeBuildInputs buildInputs runtimeDependencies;
pname = "${name}-editor";
version = "${version.asString}";
src = inputs.godot;
# nixpkgs use Godot4 and godot4 instead of godot, so we replace
installPhase = replaceStrings [ "odot4" ] [ "odot" ] nix-godot.installPhase;
enableParallelBuilding = true;
sconsFlags = mkSconsFlags "editor";
# apply the necessary patches
patches = [
./patches/xfixes.patch # fix x11 libs
./patches/gl.patch # fix gl libs
];
# some extra info
meta = with lib; {
homepage = nix-godot.meta.homepage;
description = nix-godot.meta.description;
license = licenses.mit;
};
};
# the templates
mkTemplate = target:
godot-editor.overrideAttrs (final: prev:
(prev // {
pname = "${name}-${target}";
sconsFlags = mkSconsFlags target;
installPhase = ''
mkdir -p "$out/share/godot/templates/${prev.version}"
cp bin/godot.* $out/share/godot/templates/${prev.version}/${platform}-${target}
'';
}));
godot-debug = mkTemplate "template_debug";
godot-release = mkTemplate "template_release";
# Godot-cpp bindings
godot-cpp = let target = "editor"; # no needs for other targets
in stdenv.mkDerivation {
inherit buildInputs runtimeDependencies;
nativeBuildInputs = nativeBuildInputs ++ [ godot-editor ];
# make name:
name = "godot-cpp-${target}-${version.asString}";
version = version.asString;
src = inputs.godot-cpp;
# this does not work, sadly
# configurePhase = "${godot-editor}/bin/godot --dump-extension-api extension_api.json";
# "custom_api_file=extension_api.json"
# patch
patches = [
./patches/godot-cpp.patch # fix path for g++
];
# build flags
sconsFlags = [ "generate_bindings=true" "-s" ] ++ godot-editor.sconsFlags;
# maybe split outputs ["SConstruct" "binding_generator" ... ]
outputs = [ "out" ];
installPhase = ''
mkdir -p $out
cp -r src $out/src
cp -r SConstruct $out/
cp -r binding_generator.py $out/
cp -r gdextension $out/
cp -r include $out/
cp -r tools $out/
cp -r gen $out/
chmod 755 $out -R
chmod 755 $out/gen/include/godot_cpp/core/ext_wrappers.gen.inc
'';
};
in {
# build to needs
inherit godot-editor godot-debug godot-release godot-cpp;
# inherit (build) nativeBuildInputs buildInputs runtimeDependencies;
# full engine
godot = pkgs.buildEnv {
name = "${name}-${version.asString}";
paths = [ godot-editor ]
++ (lib.optional withTemplates [ godot-release godot-debug ])
++ (lib.optional withBindings [ godot-cpp ]);
};
shell = pkgs.mkShell {
# inputsFrom = [godot-editor];
inherit nativeBuildInputs buildInputs;
};
}