nixos/kubernetes/kubelet: Fix sandbox image load on containerd 2.x (#364558)
[NixPkgs.git] / pkgs / applications / editors / emacs / make-emacs.nix
blob63f4d1e59cb51a3f4f564f9fda91145801624b54
2   pname,
3   version,
4   variant,
5   src,
6   patches ? _: [ ],
7   meta,
8 }:
11   lib,
12   stdenv,
13   Xaw3d,
14   acl,
15   alsa-lib,
16   autoreconfHook,
17   cairo,
18   dbus,
19   emacsPackagesFor,
20   fetchpatch,
21   gettext,
22   giflib,
23   glib-networking,
24   gnutls,
25   gpm,
26   gsettings-desktop-schemas,
27   gtk3,
28   gtk3-x11,
29   harfbuzz,
30   imagemagick,
31   jansson,
32   libXaw,
33   libXcursor,
34   libXi,
35   libXpm,
36   libgccjit,
37   libjpeg,
38   libotf,
39   libpng,
40   librsvg,
41   libselinux,
42   libtiff,
43   libwebp,
44   libxml2,
45   llvmPackages_14,
46   m17n_lib,
47   mailutils,
48   makeWrapper,
49   motif,
50   ncurses,
51   nixosTests,
52   pkg-config,
53   recurseIntoAttrs,
54   sigtool,
55   sqlite,
56   substituteAll,
57   systemd,
58   tree-sitter,
59   texinfo,
60   webkitgtk_4_0,
61   wrapGAppsHook3,
62   zlib,
64   # Boolean flags
65   withNativeCompilation ? stdenv.buildPlatform.canExecute stdenv.hostPlatform,
66   noGui ? false,
67   srcRepo ? true,
68   withAcl ? false,
69   withAlsaLib ? false,
70   withAthena ? false,
71   withCsrc ? true,
72   withDbus ? stdenv.hostPlatform.isLinux,
73   withGTK3 ? withPgtk && !noGui,
74   withGlibNetworking ? withPgtk || withGTK3 || (withX && withXwidgets),
75   withGpm ? stdenv.hostPlatform.isLinux,
76   withImageMagick ? lib.versionOlder version "27" && (withX || withNS),
77   # Emacs 30+ has native JSON support
78   withJansson ? lib.versionOlder version "30",
79   withMailutils ? true,
80   withMotif ? false,
81   withNS ? stdenv.hostPlatform.isDarwin && !(variant == "macport" || noGui),
82   withPgtk ? false,
83   withSelinux ? stdenv.hostPlatform.isLinux,
84   withSQLite3 ? lib.versionAtLeast version "29",
85   withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd,
86   withToolkitScrollBars ? true,
87   withTreeSitter ? lib.versionAtLeast version "29",
88   withWebP ? lib.versionAtLeast version "29",
89   withX ? !(stdenv.hostPlatform.isDarwin || noGui || withPgtk),
90   withXinput2 ? withX && lib.versionAtLeast version "29",
91   withXwidgets ?
92     !stdenv.hostPlatform.isDarwin
93     && !noGui
94     && (withGTK3 || withPgtk)
95     && (lib.versionOlder version "30"), # XXX: upstream bug 66068 precludes newer versions of webkit2gtk (https://lists.gnu.org/archive/html/bug-gnu-emacs/2024-09/msg00695.html)
96   withSmallJaDic ? false,
97   withCompressInstall ? true,
99   # Options
100   siteStart ? ./site-start.el,
101   toolkit ? (
102     if withGTK3 then
103       "gtk3"
104     else if withMotif then
105       "motif"
106     else if withAthena then
107       "athena"
108     else
109       "lucid"
110   ),
112   # macOS dependencies for NS and macPort
113   Accelerate,
114   AppKit,
115   Carbon,
116   Cocoa,
117   GSS,
118   IOKit,
119   ImageCaptureCore,
120   ImageIO,
121   OSAKit,
122   Quartz,
123   QuartzCore,
124   UniformTypeIdentifiers,
125   WebKit,
128 assert (withGTK3 && !withNS && variant != "macport") -> withX || withPgtk;
130 assert noGui -> !(withX || withGTK3 || withNS || variant == "macport");
131 assert withAcl -> stdenv.hostPlatform.isLinux;
132 assert withAlsaLib -> stdenv.hostPlatform.isLinux;
133 assert withGpm -> stdenv.hostPlatform.isLinux;
134 assert withNS -> stdenv.hostPlatform.isDarwin && !(withX || variant == "macport");
135 assert withPgtk -> withGTK3 && !withX;
136 assert withXwidgets -> !noGui && (withGTK3 || withPgtk);
139   libGccJitLibraryPaths =
140     [
141       "${lib.getLib libgccjit}/lib/gcc"
142       "${lib.getLib stdenv.cc.libc}/lib"
143     ]
144     ++ lib.optionals (stdenv.cc ? cc.lib.libgcc) [
145       "${lib.getLib stdenv.cc.cc.lib.libgcc}/lib"
146     ];
148   inherit (if variant == "macport" then llvmPackages_14.stdenv else stdenv)
149     mkDerivation
150     ;
152 mkDerivation (finalAttrs: {
153   pname =
154     pname
155     + (
156       if noGui then
157         "-nox"
158       else if variant == "macport" then
159         "-macport"
160       else if withPgtk then
161         "-pgtk"
162       else if withGTK3 then
163         "-gtk3"
164       else
165         ""
166     );
167   inherit version;
169   inherit src;
171   patches =
172     patches fetchpatch
173     ++ lib.optionals withNativeCompilation [
174       (substituteAll {
175         src =
176           if lib.versionOlder finalAttrs.version "29" then
177             ./native-comp-driver-options-28.patch
178           else if lib.versionOlder finalAttrs.version "30" then
179             ./native-comp-driver-options.patch
180           else
181             ./native-comp-driver-options-30.patch;
182         backendPath = (
183           lib.concatStringsSep " " (
184             builtins.map (x: ''"-B${x}"'') (
185               [
186                 # Paths necessary so the JIT compiler finds its libraries:
187                 "${lib.getLib libgccjit}/lib"
188               ]
189               ++ libGccJitLibraryPaths
190               ++ [
191                 # Executable paths necessary for compilation (ld, as):
192                 "${lib.getBin stdenv.cc.cc}/bin"
193                 "${lib.getBin stdenv.cc.bintools}/bin"
194                 "${lib.getBin stdenv.cc.bintools.bintools}/bin"
195               ]
196             )
197           )
198         );
199       })
200     ];
202   postPatch = lib.concatStringsSep "\n" [
203     (lib.optionalString srcRepo ''
204       rm -fr .git
205     '')
207     # Add the name of the wrapped gvfsd
208     # This used to be carried as a patch but it often got out of sync with
209     # upstream and was hard to maintain for emacs-overlay.
210     (lib.concatStrings (
211       map
212         (fn: ''
213           sed -i 's#(${fn} "gvfs-fuse-daemon")#(${fn} "gvfs-fuse-daemon") (${fn} ".gvfsd-fuse-wrapped")#' lisp/net/tramp-gvfs.el
214         '')
215         [
216           "tramp-compat-process-running-p"
217           "tramp-process-running-p"
218         ]
219     ))
221     # Reduce closure size by cleaning the environment of the emacs dumper
222     ''
223       substituteInPlace src/Makefile.in \
224         --replace 'RUN_TEMACS = ./temacs' 'RUN_TEMACS = env -i ./temacs'
225     ''
227     ''
228       substituteInPlace lisp/international/mule-cmds.el \
229         --replace /usr/share/locale ${gettext}/share/locale
231       for makefile_in in $(find . -name Makefile.in -print); do
232         substituteInPlace $makefile_in --replace /bin/pwd pwd
233       done
234     ''
236     ""
237   ];
239   nativeBuildInputs =
240     [
241       makeWrapper
242       pkg-config
243     ]
244     ++ lib.optionals (variant == "macport") [
245       texinfo
246     ]
247     ++ lib.optionals srcRepo [
248       autoreconfHook
249       texinfo
250     ]
251     ++ lib.optionals (withPgtk || withX && (withGTK3 || withXwidgets)) [ wrapGAppsHook3 ];
253   buildInputs =
254     [
255       gettext
256       gnutls
257       (lib.getDev harfbuzz)
258     ]
259     ++ lib.optionals withJansson [
260       jansson
261     ]
262     ++ [
263       libxml2
264       ncurses
265     ]
266     ++ lib.optionals withAcl [
267       acl
268     ]
269     ++ lib.optionals withAlsaLib [
270       alsa-lib
271     ]
272     ++ lib.optionals withGpm [
273       gpm
274     ]
275     ++ lib.optionals withDbus [
276       dbus
277     ]
278     ++ lib.optionals withSelinux [
279       libselinux
280     ]
281     ++ lib.optionals (!stdenv.hostPlatform.isDarwin && withGTK3) [
282       gsettings-desktop-schemas
283     ]
284     ++ lib.optionals (stdenv.hostPlatform.isLinux && withX) [
285       libotf
286       m17n_lib
287     ]
288     ++ lib.optionals (withX && withGTK3) [
289       gtk3-x11
290     ]
291     ++ lib.optionals (withX && withMotif) [
292       motif
293     ]
294     ++ lib.optionals withGlibNetworking [
295       glib-networking
296     ]
297     ++ lib.optionals withNativeCompilation [
298       libgccjit
299       zlib
300     ]
301     ++ lib.optionals withImageMagick [
302       imagemagick
303     ]
304     ++ lib.optionals withPgtk [
305       giflib
306       gtk3
307       libXpm
308       libjpeg
309       libpng
310       librsvg
311       libtiff
312     ]
313     ++ lib.optionals withSQLite3 [
314       sqlite
315     ]
316     ++ lib.optionals withSystemd [
317       systemd
318     ]
319     ++ lib.optionals withTreeSitter [
320       tree-sitter
321     ]
322     ++ lib.optionals withWebP [
323       libwebp
324     ]
325     ++ lib.optionals withX [
326       Xaw3d
327       cairo
328       giflib
329       libXaw
330       libXpm
331       libjpeg
332       libpng
333       librsvg
334       libtiff
335     ]
336     ++ lib.optionals withXinput2 [
337       libXi
338     ]
339     ++ lib.optionals withXwidgets [
340       webkitgtk_4_0
341     ]
342     ++ lib.optionals stdenv.hostPlatform.isDarwin [
343       sigtool
344     ]
345     ++ lib.optionals withNS [
346       librsvg
347       AppKit
348       GSS
349       ImageIO
350     ]
351     ++ lib.optionals (variant == "macport") [
352       Accelerate
353       AppKit
354       Carbon
355       Cocoa
356       IOKit
357       OSAKit
358       Quartz
359       QuartzCore
360       WebKit
361       # TODO are these optional?
362       GSS
363       ImageCaptureCore
364       ImageIO
365     ]
366     ++ lib.optionals (variant == "macport" && stdenv.hostPlatform.isAarch64) [
367       UniformTypeIdentifiers
368     ];
370   # Emacs needs to find movemail at run time, see info (emacs) Movemail
371   propagatedUserEnvPkgs = lib.optionals withMailutils [
372     mailutils
373   ];
375   hardeningDisable = [ "format" ];
377   configureFlags =
378     [
379       (lib.enableFeature false "build-details") # for a (more) reproducible build
380       (lib.withFeature true "modules")
381     ]
382     ++ (
383       if withNS then
384         [
385           (lib.enableFeature false "ns-self-contained")
386         ]
387       else if withX then
388         [
389           (lib.withFeatureAs true "x-toolkit" toolkit)
390           (lib.withFeature true "cairo")
391           (lib.withFeature true "xft")
392         ]
393       else if withPgtk then
394         [
395           (lib.withFeature true "pgtk")
396         ]
397       else
398         [
399           (lib.withFeature false "gif")
400           (lib.withFeature false "jpeg")
401           (lib.withFeature false "png")
402           (lib.withFeature false "tiff")
403           (lib.withFeature false "x")
404           (lib.withFeature false "xpm")
405         ]
406     )
407     ++ lib.optionals (variant == "macport") [
408       (lib.enableFeatureAs true "mac-app" "$$out/Applications")
409       (lib.withFeature true "gnutls")
410       (lib.withFeature true "mac")
411       (lib.withFeature true "xml2")
412     ]
413     ++ lib.optionals stdenv.hostPlatform.isDarwin [
414       (lib.withFeature withNS "ns")
415     ]
416     ++ [
417       (lib.withFeature withCompressInstall "compress-install")
418       (lib.withFeature withToolkitScrollBars "toolkit-scroll-bars")
419       (lib.withFeature withNativeCompilation "native-compilation")
420       (lib.withFeature withImageMagick "imagemagick")
421       (lib.withFeature withMailutils "mailutils")
422       (lib.withFeature withSmallJaDic "small-ja-dic")
423       (lib.withFeature withTreeSitter "tree-sitter")
424       (lib.withFeature withXinput2 "xinput2")
425       (lib.withFeature withXwidgets "xwidgets")
426       (lib.withFeature withDbus "dbus")
427       (lib.withFeature withSelinux "selinux")
428     ];
430   env =
431     lib.optionalAttrs withNativeCompilation {
432       NATIVE_FULL_AOT = "1";
433       LIBRARY_PATH = lib.concatStringsSep ":" libGccJitLibraryPaths;
434     }
435     // lib.optionalAttrs (variant == "macport") {
436       # Fixes intermittent segfaults when compiled with LLVM >= 7.0.
437       # See https://github.com/NixOS/nixpkgs/issues/127902
438       NIX_CFLAGS_COMPILE = "-include ${./macport_noescape_noop.h}";
439     };
441   enableParallelBuilding = true;
443   installTargets = [
444     "tags"
445     "install"
446   ];
448   postInstall =
449     ''
450       mkdir -p $out/share/emacs/site-lisp
451       cp ${siteStart} $out/share/emacs/site-lisp/site-start.el
453       $out/bin/emacs --batch -f batch-byte-compile $out/share/emacs/site-lisp/site-start.el
455       siteVersionDir=`ls $out/share/emacs | grep -v site-lisp | head -n 1`
457       rm -r $out/share/emacs/$siteVersionDir/site-lisp
458     ''
459     + lib.optionalString withCsrc ''
460       for srcdir in src lisp lwlib ; do
461         dstdir=$out/share/emacs/$siteVersionDir/$srcdir
462         mkdir -p $dstdir
463         find $srcdir -name "*.[chm]" -exec cp {} $dstdir \;
464         cp $srcdir/TAGS $dstdir
465         echo '((nil . ((tags-file-name . "TAGS"))))' > $dstdir/.dir-locals.el
466       done
467     ''
468     + lib.optionalString withNS ''
469       mkdir -p $out/Applications
470       mv nextstep/Emacs.app $out/Applications
471     ''
472     + lib.optionalString (withNativeCompilation && (withNS || variant == "macport")) ''
473       ln -snf $out/lib/emacs/*/native-lisp $out/Applications/Emacs.app/Contents/native-lisp
474     ''
475     + lib.optionalString withNativeCompilation ''
476       echo "Generating native-compiled trampolines..."
477       # precompile trampolines in parallel, but avoid spawning one process per trampoline.
478       # 1000 is a rough lower bound on the number of trampolines compiled.
479       $out/bin/emacs --batch --eval "(mapatoms (lambda (s) \
480         (when (subr-primitive-p (symbol-function s)) (print s))))" \
481         | xargs -n $((1000/NIX_BUILD_CORES + 1)) -P $NIX_BUILD_CORES \
482           $out/bin/emacs --batch -l comp --eval "(while argv \
483             (comp-trampoline-compile (intern (pop argv))))"
484       mkdir -p $out/share/emacs/native-lisp
485       $out/bin/emacs --batch \
486         --eval "(add-to-list 'native-comp-eln-load-path \"$out/share/emacs/native-lisp\")" \
487         -f batch-native-compile $out/share/emacs/site-lisp/site-start.el
488     '';
490   postFixup = lib.optionalString (stdenv.hostPlatform.isLinux && withX && toolkit == "lucid") ''
491     patchelf --add-rpath ${lib.makeLibraryPath [ libXcursor ]} $out/bin/emacs
492     patchelf --add-needed "libXcursor.so.1" "$out/bin/emacs"
493   '';
495   passthru = {
496     inherit withNativeCompilation;
497     inherit withTreeSitter;
498     inherit withXwidgets;
499     pkgs = recurseIntoAttrs (emacsPackagesFor finalAttrs.finalPackage);
500     tests = { inherit (nixosTests) emacs-daemon; };
501   };
503   meta = meta // {
504     broken = withNativeCompilation && !(stdenv.buildPlatform.canExecute stdenv.hostPlatform);
505   };