mysql80: fix darwin and LLVM 19 build (#374591)
[NixPkgs.git] / pkgs / applications / editors / vscode / generic.nix
blob0b5f20efd1654ce5397fd08902b5a87adad8e06b
2   stdenv,
3   lib,
4   copyDesktopItems,
5   makeDesktopItem,
6   unzip,
7   libsecret,
8   libXScrnSaver,
9   libxshmfence,
10   buildPackages,
11   at-spi2-atk,
12   autoPatchelfHook,
13   alsa-lib,
14   libgbm,
15   nss,
16   nspr,
17   xorg,
18   systemd,
19   fontconfig,
20   libdbusmenu,
21   glib,
22   buildFHSEnv,
23   wayland,
24   libglvnd,
25   libkrb5,
27   # Populate passthru.tests
28   tests,
30   # needed to fix "Save as Root"
31   asar,
32   bash,
34   # Attributes inherit from specific versions
35   version,
36   src,
37   meta,
38   sourceRoot,
39   commandLineArgs,
40   executableName,
41   longName,
42   shortName,
43   pname,
44   updateScript,
45   dontFixup ? false,
46   rev ? null,
47   vscodeServer ? null,
48   sourceExecutableName ? executableName,
49   useVSCodeRipgrep ? false,
50   ripgrep,
53 stdenv.mkDerivation (
54   finalAttrs:
55   let
57     # Vscode and variants allow for users to download and use extensions
58     # which often include the usage of pre-built binaries.
59     # This has been an on-going painpoint for many users, as
60     # a full extension update cycle has to be done through nixpkgs
61     # in order to create or update extensions.
62     # See: #83288 #91179 #73810 #41189
63     #
64     # buildFHSEnv allows for users to use the existing vscode
65     # extension tooling without significant pain.
66     fhs =
67       {
68         additionalPkgs ? pkgs: [ ],
69       }:
70       buildFHSEnv {
71         # also determines the name of the wrapped command
72         pname = executableName;
73         inherit version;
75         # additional libraries which are commonly needed for extensions
76         targetPkgs =
77           pkgs:
78           (with pkgs; [
79             # ld-linux-x86-64-linux.so.2 and others
80             glibc
82             # dotnet
83             curl
84             icu
85             libunwind
86             libuuid
87             lttng-ust
88             openssl
89             zlib
91             # mono
92             krb5
93           ])
94           ++ additionalPkgs pkgs;
96         extraBwrapArgs = [
97           "--bind-try /etc/nixos/ /etc/nixos/"
98         ];
100         # symlink shared assets, including icons and desktop entries
101         extraInstallCommands = ''
102           ln -s "${finalAttrs.finalPackage}/share" "$out/"
103         '';
105         runScript = "${finalAttrs.finalPackage}/bin/${executableName}";
107         # vscode likes to kill the parent so that the
108         # gui application isn't attached to the terminal session
109         dieWithParent = false;
111         passthru = {
112           inherit executableName;
113           inherit (finalAttrs.finalPackage) pname version; # for home-manager module
114         };
116         meta = meta // {
117           description = ''
118             Wrapped variant of ${pname} which launches in a FHS compatible environment.
119             Should allow for easy usage of extensions without nix-specific modifications.
120           '';
121         };
122       };
123   in
124   {
126     inherit
127       pname
128       version
129       src
130       sourceRoot
131       dontFixup
132       ;
134     passthru =
135       {
136         inherit
137           executableName
138           longName
139           tests
140           updateScript
141           ;
142         fhs = fhs { };
143         fhsWithPackages = f: fhs { additionalPkgs = f; };
144       }
145       // lib.optionalAttrs (vscodeServer != null) {
146         inherit rev vscodeServer;
147       };
149     desktopItems = [
150       (makeDesktopItem {
151         name = executableName;
152         desktopName = longName;
153         comment = "Code Editing. Redefined.";
154         genericName = "Text Editor";
155         exec = "${executableName} %F";
156         icon = "vs${executableName}";
157         startupNotify = true;
158         startupWMClass = shortName;
159         categories = [
160           "Utility"
161           "TextEditor"
162           "Development"
163           "IDE"
164         ];
165         keywords = [ "vscode" ];
166         actions.new-empty-window = {
167           name = "New Empty Window";
168           exec = "${executableName} --new-window %F";
169           icon = "vs${executableName}";
170         };
171       })
172       (makeDesktopItem {
173         name = executableName + "-url-handler";
174         desktopName = longName + " - URL Handler";
175         comment = "Code Editing. Redefined.";
176         genericName = "Text Editor";
177         exec = executableName + " --open-url %U";
178         icon = "vs${executableName}";
179         startupNotify = true;
180         startupWMClass = shortName;
181         categories = [
182           "Utility"
183           "TextEditor"
184           "Development"
185           "IDE"
186         ];
187         mimeTypes = [ "x-scheme-handler/vs${executableName}" ];
188         keywords = [ "vscode" ];
189         noDisplay = true;
190       })
191     ];
193     buildInputs =
194       [
195         libsecret
196         libXScrnSaver
197         libxshmfence
198       ]
199       ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [
200         alsa-lib
201         at-spi2-atk
202         libkrb5
203         libgbm
204         nss
205         nspr
206         systemd
207         xorg.libxkbfile
208       ];
210     runtimeDependencies = lib.optionals stdenv.hostPlatform.isLinux [
211       (lib.getLib systemd)
212       fontconfig.lib
213       libdbusmenu
214       wayland
215       libsecret
216     ];
218     nativeBuildInputs =
219       [ unzip ]
220       ++ lib.optionals stdenv.hostPlatform.isLinux [
221         autoPatchelfHook
222         asar
223         copyDesktopItems
224         # override doesn't preserve splicing https://github.com/NixOS/nixpkgs/issues/132651
225         # Has to use `makeShellWrapper` from `buildPackages` even though `makeShellWrapper` from the inputs is spliced because `propagatedBuildInputs` would pick the wrong one because of a different offset.
226         (buildPackages.wrapGAppsHook3.override { makeWrapper = buildPackages.makeShellWrapper; })
227       ];
229     dontBuild = true;
230     dontConfigure = true;
231     noDumpEnvVars = true;
233     installPhase =
234       ''
235         runHook preInstall
236       ''
237       + (
238         if stdenv.hostPlatform.isDarwin then
239           ''
240             mkdir -p "$out/Applications/${longName}.app" "$out/bin"
241             cp -r ./* "$out/Applications/${longName}.app"
242             ln -s "$out/Applications/${longName}.app/Contents/Resources/app/bin/${sourceExecutableName}" "$out/bin/${executableName}"
243           ''
244         else
245           ''
246             mkdir -p "$out/lib/vscode" "$out/bin"
247             cp -r ./* "$out/lib/vscode"
249             ln -s "$out/lib/vscode/bin/${sourceExecutableName}" "$out/bin/${executableName}"
251             # These are named vscode.png, vscode-insiders.png, etc to match the name in upstream *.deb packages.
252             mkdir -p "$out/share/pixmaps"
253             cp "$out/lib/vscode/resources/app/resources/linux/code.png" "$out/share/pixmaps/vs${executableName}.png"
255             # Override the previously determined VSCODE_PATH with the one we know to be correct
256             sed -i "/ELECTRON=/iVSCODE_PATH='$out/lib/vscode'" "$out/bin/${executableName}"
257             grep -q "VSCODE_PATH='$out/lib/vscode'" "$out/bin/${executableName}" # check if sed succeeded
259             # Remove native encryption code, as it derives the key from the executable path which does not work for us.
260             # The credentials should be stored in a secure keychain already, so the benefit of this is questionable
261             # in the first place.
262             rm -rf $out/lib/vscode/resources/app/node_modules/vscode-encrypt
263           ''
264       )
265       + ''
266         runHook postInstall
267       '';
269     preFixup = ''
270       gappsWrapperArgs+=(
271           ${
272             # we cannot use runtimeDependencies otherwise libdbusmenu do not work on kde
273             lib.optionalString stdenv.hostPlatform.isLinux
274               "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ libdbusmenu ]}"
275           }
276         # Add gio to PATH so that moving files to the trash works when not using a desktop environment
277         --prefix PATH : ${glib.bin}/bin
278         --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}"
279         --add-flags ${lib.escapeShellArg commandLineArgs}
280       )
281     '';
283     # See https://github.com/NixOS/nixpkgs/issues/49643#issuecomment-873853897
284     # linux only because of https://github.com/NixOS/nixpkgs/issues/138729
285     postPatch =
286       lib.optionalString stdenv.hostPlatform.isLinux ''
287         # this is a fix for "save as root" functionality
288         packed="resources/app/node_modules.asar"
289         unpacked="resources/app/node_modules"
290         asar extract "$packed" "$unpacked"
291         substituteInPlace $unpacked/@vscode/sudo-prompt/index.js \
292           --replace "/usr/bin/pkexec" "/run/wrappers/bin/pkexec" \
293           --replace "/bin/bash" "${bash}/bin/bash"
294         rm -rf "$packed"
296         # without this symlink loading JsChardet, the library that is used for auto encoding detection when files.autoGuessEncoding is true,
297         # fails to load with: electron/js2c/renderer_init: Error: Cannot find module 'jschardet'
298         # and the window immediately closes which renders VSCode unusable
299         # see https://github.com/NixOS/nixpkgs/issues/152939 for full log
300         ln -rs "$unpacked" "$packed"
301       ''
302       + (
303         let
304           vscodeRipgrep =
305             if stdenv.hostPlatform.isDarwin then
306               if lib.versionAtLeast version "1.94.0" then
307                 "Contents/Resources/app/node_modules/@vscode/ripgrep/bin/rg"
308               else
309                 "Contents/Resources/app/node_modules.asar.unpacked/@vscode/ripgrep/bin/rg"
310             else
311               "resources/app/node_modules/@vscode/ripgrep/bin/rg";
312         in
313         if !useVSCodeRipgrep then
314           ''
315             rm ${vscodeRipgrep}
316             ln -s ${ripgrep}/bin/rg ${vscodeRipgrep}
317           ''
318         else
319           ''
320             chmod +x ${vscodeRipgrep}
321           ''
322       );
324     postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
325       patchelf \
326         --add-needed ${libglvnd}/lib/libGLESv2.so.2 \
327         --add-needed ${libglvnd}/lib/libGL.so.1 \
328         --add-needed ${libglvnd}/lib/libEGL.so.1 \
329         $out/lib/vscode/${executableName}
330     '';
332     inherit meta;
333   }