1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 fetchurl,
6 replaceVars,
7 coreutils,
8 curl,
9 gnugrep,
10 gnused,
11 xdg-utils,
12 dbus,
13 libGL,
14 libX11,
15 hwdata,
16 mangohud32,
17 addDriverRunpath,
18 appstream,
19 glslang,
20 python3Packages,
21 meson,
22 ninja,
23 pkg-config,
24 unzip,
25 wayland,
26 libXNVCtrl,
27 nlohmann_json,
28 spdlog,
29 libxkbcommon,
30 glew,
31 glfw,
32 libXrandr,
33 x11Support ? true,
34 waylandSupport ? true,
35 nvidiaSupport ? lib.meta.availableOn stdenv.hostPlatform libXNVCtrl,
36 gamescopeSupport ? true,
37 mangoappSupport ? gamescopeSupport,
38 mangohudctlSupport ? gamescopeSupport,
39 lowerBitnessSupport ? stdenv.hostPlatform.isx86_64, # Support 32 bit on 64bit
40 nix-update-script,
41}:
42
43assert lib.assertMsg (
44 x11Support || waylandSupport
45) "either x11Support or waylandSupport should be enabled";
46
47assert lib.assertMsg (nvidiaSupport -> x11Support) "nvidiaSupport requires x11Support";
48assert lib.assertMsg (mangoappSupport -> x11Support) "mangoappSupport requires x11Support";
49
50let
51 # Derived from subprojects/imgui.wrap
52 imgui = rec {
53 version = "1.89.9";
54 src = fetchFromGitHub {
55 owner = "ocornut";
56 repo = "imgui";
57 tag = "v${version}";
58 hash = "sha256-0k9jKrJUrG9piHNFQaBBY3zgNIKM23ZA879NY+MNYTU=";
59 };
60 patch = fetchurl {
61 url = "https://wrapdb.mesonbuild.com/v2/imgui_${version}-1/get_patch";
62 hash = "sha256-myEpDFl9dr+NTus/n/oCSxHZ6mxh6R1kjMyQtChD1YQ=";
63 };
64 };
65
66 # Derived from subprojects/implot.wrap
67 implot = rec {
68 version = "0.16";
69 src = fetchFromGitHub {
70 owner = "epezent";
71 repo = "implot";
72 tag = "v${version}";
73 hash = "sha256-/wkVsgz3wiUVZBCgRl2iDD6GWb+AoHN+u0aeqHHgem0=";
74 };
75 patch = fetchurl {
76 url = "https://wrapdb.mesonbuild.com/v2/implot_${version}-1/get_patch";
77 hash = "sha256-HGsUYgZqVFL6UMHaHdR/7YQfKCMpcsgtd48pYpNlaMc=";
78 };
79 };
80
81 # Derived from subprojects/vulkan-headers.wrap
82 vulkan-headers = rec {
83 version = "1.2.158";
84 src = fetchFromGitHub {
85 owner = "KhronosGroup";
86 repo = "Vulkan-Headers";
87 tag = "v${version}";
88 hash = "sha256-5uyk2nMwV1MjXoa3hK/WUeGLwpINJJEvY16kc5DEaks=";
89 };
90 patch = fetchurl {
91 url = "https://wrapdb.mesonbuild.com/v2/vulkan-headers_${version}-2/get_patch";
92 hash = "sha256-hgNYz15z9FjNHoj4w4EW0SOrQh1c4uQSnsOOrt2CDhc=";
93 };
94 };
95in
96stdenv.mkDerivation (finalAttrs: {
97 pname = "mangohud";
98 version = "0.8.1";
99
100 src = fetchFromGitHub {
101 owner = "flightlessmango";
102 repo = "MangoHud";
103 tag = "v${finalAttrs.version}";
104 fetchSubmodules = true;
105 hash = "sha256-FvPhnOvcYE8vVB5R+ZRmuZxrC9U4GA338V7VAuUlHCE=";
106 };
107
108 outputs = [
109 "out"
110 "doc"
111 "man"
112 ];
113
114 # Unpack subproject sources
115 postUnpack = ''
116 (
117 cd "$sourceRoot/subprojects"
118 cp -R --no-preserve=mode,ownership ${imgui.src} imgui-${imgui.version}
119 cp -R --no-preserve=mode,ownership ${implot.src} implot-${implot.version}
120 cp -R --no-preserve=mode,ownership ${vulkan-headers.src} Vulkan-Headers-${vulkan-headers.version}
121 )
122 '';
123
124 patches = [
125 # Add @libraryPath@ template variable to fix loading the preload
126 # library and @dataPath@ to support overlaying Vulkan apps without
127 # requiring MangoHud to be installed
128 ./preload-nix-workaround.patch
129
130 # Hard code dependencies. Can't use makeWrapper since the Vulkan
131 # layer can be used without the mangohud executable by setting MANGOHUD=1.
132 (replaceVars ./hardcode-dependencies.patch {
133 path = lib.makeBinPath [
134 coreutils
135 curl
136 gnugrep
137 gnused
138 xdg-utils
139 ];
140
141 libdbus = dbus.lib;
142 libGL = libGL;
143 libX11 = libX11;
144 inherit hwdata;
145 })
146 ];
147
148 postPatch = ''
149 substituteInPlace bin/mangohud.in \
150 --subst-var-by libraryPath ${
151 lib.makeSearchPath "lib/mangohud" (
152 [
153 (placeholder "out")
154 ]
155 ++ lib.optional lowerBitnessSupport mangohud32
156 )
157 } \
158 --subst-var-by version "${finalAttrs.version}" \
159 --subst-var-by dataDir ${placeholder "out"}/share
160
161 (
162 cd subprojects
163 unzip ${imgui.patch}
164 unzip ${implot.patch}
165 unzip ${vulkan-headers.patch}
166 )
167 '';
168
169 mesonFlags = [
170 "-Duse_system_spdlog=enabled"
171 "-Dtests=disabled" # amdgpu test segfaults in nix sandbox
172 (lib.mesonEnable "with_x11" x11Support)
173 (lib.mesonEnable "with_wayland" waylandSupport)
174 (lib.mesonEnable "with_xnvctrl" nvidiaSupport)
175 (lib.mesonBool "mangoapp" mangoappSupport)
176 (lib.mesonBool "mangohudctl" mangohudctlSupport)
177 ];
178
179 strictDeps = true;
180
181 nativeBuildInputs = [
182 addDriverRunpath
183 glslang
184 python3Packages.mako
185 meson
186 ninja
187 pkg-config
188 unzip
189 ];
190
191 buildInputs = [
192 dbus
193 nlohmann_json
194 spdlog
195 ]
196 ++ lib.optional waylandSupport wayland
197 ++ lib.optional x11Support libX11
198 ++ lib.optional nvidiaSupport libXNVCtrl
199 ++ lib.optional (x11Support || waylandSupport) libxkbcommon
200 ++ lib.optionals mangoappSupport [
201 glew
202 glfw
203 libXrandr
204 ];
205
206 doCheck = true;
207
208 nativeCheckInputs = [
209 appstream
210 ];
211
212 # Support 32bit Vulkan applications by linking in 32bit Vulkan layers
213 # This is needed for the same reason the 32bit preload workaround is needed.
214 postInstall = lib.optionalString lowerBitnessSupport ''
215 ln -s ${mangohud32}/share/vulkan/implicit_layer.d/MangoHud.x86.json \
216 "$out/share/vulkan/implicit_layer.d"
217 '';
218
219 postFixup =
220 let
221 archMap = {
222 "x86_64-linux" = "x86_64";
223 "i686-linux" = "x86";
224 };
225 layerPlatform = archMap."${stdenv.hostPlatform.system}" or null;
226 in
227 # We need to give the different layers separate names or else the loader
228 # might try the 32-bit one first, fail and not attempt to load the 64-bit
229 # layer under the same name.
230 lib.optionalString (layerPlatform != null) ''
231 substituteInPlace $out/share/vulkan/implicit_layer.d/MangoHud.${layerPlatform}.json \
232 --replace-fail "VK_LAYER_MANGOHUD_overlay" "VK_LAYER_MANGOHUD_overlay_${toString stdenv.hostPlatform.parsed.cpu.bits}"
233 ''
234 + lib.optionalString nvidiaSupport ''
235 # Add OpenGL driver and libXNVCtrl paths to RUNPATH to support NVIDIA cards
236 addDriverRunpath "$out/lib/mangohud/libMangoHud.so"
237 patchelf --add-rpath ${libXNVCtrl}/lib "$out/lib/mangohud/libMangoHud.so"
238 ''
239 + lib.optionalString mangoappSupport ''
240 addDriverRunpath "$out/bin/mangoapp"
241 '';
242
243 passthru.updateScript = nix-update-script { };
244
245 meta = with lib; {
246 description = "Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more";
247 homepage = "https://github.com/flightlessmango/MangoHud";
248 changelog = "https://github.com/flightlessmango/MangoHud/releases/tag/v${finalAttrs.version}";
249 platforms = platforms.linux;
250 license = licenses.mit;
251 maintainers = with maintainers; [
252 kira-bruneau
253 zeratax
254 ];
255 };
256})