summary refs log tree commit diff
path: root/pkgs/applications/editors/emacs/generic.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/applications/editors/emacs/generic.nix')
-rw-r--r--pkgs/applications/editors/emacs/generic.nix104
1 files changed, 66 insertions, 38 deletions
diff --git a/pkgs/applications/editors/emacs/generic.nix b/pkgs/applications/editors/emacs/generic.nix
index 69bb51e10f2..bcd55258a49 100644
--- a/pkgs/applications/editors/emacs/generic.nix
+++ b/pkgs/applications/editors/emacs/generic.nix
@@ -7,24 +7,28 @@
   , patches ? [ ]
 }:
 { stdenv, lib, fetchurl, fetchpatch, ncurses, xlibsWrapper, libXaw, libXpm
-, Xaw3d, libXcursor,  pkgconfig, gettext, libXft, dbus, libpng, libjpeg, libungif
+, Xaw3d, libXcursor,  pkg-config, gettext, libXft, dbus, libpng, libjpeg, giflib
 , libtiff, librsvg, gconf, libxml2, imagemagick, gnutls, libselinux
-, alsaLib, cairo, acl, gpm, AppKit, GSS, ImageIO, m17n_lib, libotf
-, jansson, harfbuzz
-, libgccjit, targetPlatform, binutils, binutils-unwrapped, makeWrapper # native-comp params
+, alsa-lib, cairo, acl, gpm, AppKit, GSS, ImageIO, m17n_lib, libotf
+, sigtool, jansson, harfbuzz
+, dontRecurseIntoAttrs ,emacsPackagesFor
+, libgccjit, targetPlatform, makeWrapper # native-comp params
 , systemd ? null
 , withX ? !stdenv.isDarwin
 , withNS ? stdenv.isDarwin
 , withGTK2 ? false, gtk2-x11 ? null
 , withGTK3 ? true, gtk3-x11 ? null, gsettings-desktop-schemas ? null
 , withXwidgets ? false, webkitgtk ? null, wrapGAppsHook ? null, glib-networking ? null
+, withMotif ? false, motif ? null
 , withCsrc ? true
 , srcRepo ? false, autoreconfHook ? null, texinfo ? null
 , siteStart ? ./site-start.el
 , nativeComp ? false
+, withImageMagick ? lib.versionOlder version "27" && (withX || withNS)
 , toolkit ? (
   if withGTK2 then "gtk2"
   else if withGTK3 then "gtk3"
+  else if withMotif then "motif"
   else "lucid")
 }:
 
@@ -39,11 +43,14 @@ assert withGTK3 -> !withGTK2 && gtk3-x11 != null;
 assert withXwidgets -> withGTK3 && webkitgtk != null;
 
 
-let
-
-in stdenv.mkDerivation {
+let emacs = stdenv.mkDerivation (lib.optionalAttrs nativeComp {
+  NATIVE_FULL_AOT = "1";
+  LIBRARY_PATH = "${lib.getLib stdenv.cc.libc}/lib";
+} // {
   inherit pname version;
 
+  patches = patches fetchpatch;
+
   src = fetchurl {
     url = "mirror://gnu/emacs/${name}.tar.xz";
     inherit sha256;
@@ -56,6 +63,12 @@ in stdenv.mkDerivation {
       rm -fr .git
     '')
 
+    # Reduce closure size by cleaning the environment of the emacs dumper
+    ''
+      substituteInPlace src/Makefile.in \
+        --replace 'RUN_TEMACS = ./temacs' 'RUN_TEMACS = env -i ./temacs'
+    ''
+
     ''
     substituteInPlace lisp/international/mule-cmds.el \
       --replace /usr/share/locale ${gettext}/share/locale
@@ -67,43 +80,46 @@ in stdenv.mkDerivation {
 
     # Make native compilation work both inside and outside of nix build
     (lib.optionalString nativeComp (let
-      libPath = lib.concatStringsSep ":" [
-        "${lib.getLib libgccjit}/lib/gcc/${targetPlatform.config}/${libgccjit.version}"
-        "${lib.getLib stdenv.cc.cc}/lib"
-        "${lib.getLib stdenv.glibc}/lib"
-      ];
+      backendPath = (lib.concatStringsSep " "
+        (builtins.map (x: ''\"-B${x}\"'') [
+          # Paths necessary so the JIT compiler finds its libraries:
+          "${lib.getLib libgccjit}/lib"
+          "${lib.getLib libgccjit}/lib/gcc"
+          "${lib.getLib stdenv.cc.libc}/lib"
+
+          # Executable paths necessary for compilation (ld, as):
+          "${lib.getBin stdenv.cc.cc}/bin"
+          "${lib.getBin stdenv.cc.bintools}/bin"
+          "${lib.getBin stdenv.cc.bintools.bintools}/bin"
+        ]));
     in ''
       substituteInPlace lisp/emacs-lisp/comp.el --replace \
-        "(defcustom comp-async-env-modifier-form nil" \
-        "(defcustom comp-async-env-modifier-form '((setenv \"LIBRARY_PATH\" (string-join (seq-filter (lambda (v) (null (eq v nil))) (list (getenv \"LIBRARY_PATH\") \"${libPath}\")) \":\")))"
-
+        "(defcustom native-comp-driver-options nil" \
+        "(defcustom native-comp-driver-options '(${backendPath})"
     ''))
-
     ""
   ];
 
-  CFLAGS = "-DMAC_OS_X_VERSION_MAX_ALLOWED=101200";
-
-  LIBRARY_PATH = if nativeComp then "${lib.getLib stdenv.cc.libc}/lib" else "";
-
-  nativeBuildInputs = [ pkgconfig makeWrapper ]
+  nativeBuildInputs = [ pkg-config makeWrapper ]
     ++ lib.optionals srcRepo [ autoreconfHook texinfo ]
     ++ lib.optional (withX && (withGTK3 || withXwidgets)) wrapGAppsHook;
 
   buildInputs =
-    [ ncurses gconf libxml2 gnutls alsaLib acl gpm gettext jansson harfbuzz.dev ]
+    [ ncurses gconf libxml2 gnutls alsa-lib acl gpm gettext jansson harfbuzz.dev ]
     ++ lib.optionals stdenv.isLinux [ dbus libselinux systemd ]
     ++ lib.optionals withX
-      [ xlibsWrapper libXaw Xaw3d libXpm libpng libjpeg libungif libtiff libXft
+      [ xlibsWrapper libXaw Xaw3d libXpm libpng libjpeg giflib libtiff libXft
         gconf cairo ]
-    ++ lib.optionals (withX || withNS) [ imagemagick librsvg ]
+    ++ lib.optionals (withX || withNS) [ librsvg ]
+    ++ lib.optionals withImageMagick [ imagemagick ]
     ++ lib.optionals (stdenv.isLinux && withX) [ m17n_lib libotf ]
     ++ lib.optional (withX && withGTK2) gtk2-x11
     ++ lib.optionals (withX && withGTK3) [ gtk3-x11 gsettings-desktop-schemas ]
+    ++ lib.optional (withX && withMotif) motif
     ++ lib.optionals (withX && withXwidgets) [ webkitgtk glib-networking ]
     ++ lib.optionals withNS [ AppKit GSS ImageIO ]
-    ++ lib.optionals nativeComp [ libgccjit ]
-    ;
+    ++ lib.optionals stdenv.isDarwin [ sigtool ]
+    ++ lib.optionals nativeComp [ libgccjit ];
 
   hardeningDisable = [ "format" ];
 
@@ -120,8 +136,9 @@ in stdenv.mkDerivation {
       else [ "--with-x=no" "--with-xpm=no" "--with-jpeg=no" "--with-png=no"
              "--with-gif=no" "--with-tiff=no" ])
     ++ lib.optional withXwidgets "--with-xwidgets"
-    ++ lib.optional nativeComp "--with-nativecomp"
-    ;
+    ++ lib.optional nativeComp "--with-native-compilation"
+    ++ lib.optional withImageMagick "--with-imagemagick"
+  ;
 
   installTargets = [ "tags" "install" ];
 
@@ -133,11 +150,10 @@ in stdenv.mkDerivation {
 
     siteVersionDir=`ls $out/share/emacs | grep -v site-lisp | head -n 1`
 
-    rm -rf $out/var
-    rm -rf $siteVersionDir
+    rm -r $out/share/emacs/$siteVersionDir/site-lisp
   '' + lib.optionalString withCsrc ''
     for srcdir in src lisp lwlib ; do
-      dstdir=$siteVersionDir/$srcdir
+      dstdir=$out/share/emacs/$siteVersionDir/$srcdir
       mkdir -p $dstdir
       find $srcdir -name "*.[chm]" -exec cp {} $dstdir \;
       cp $srcdir/TAGS $dstdir
@@ -146,6 +162,21 @@ in stdenv.mkDerivation {
   '' + lib.optionalString withNS ''
     mkdir -p $out/Applications
     mv nextstep/Emacs.app $out/Applications
+  '' + lib.optionalString (nativeComp && withNS) ''
+    ln -snf $out/lib/emacs/*/native-lisp $out/Applications/Emacs.app/Contents/native-lisp
+  '' + lib.optionalString nativeComp ''
+    echo "Generating native-compiled trampolines..."
+    # precompile trampolines in parallel, but avoid spawning one process per trampoline.
+    # 1000 is a rough lower bound on the number of trampolines compiled.
+    $out/bin/emacs --batch --eval "(mapatoms (lambda (s) \
+      (when (subr-primitive-p (symbol-function s)) (print s))))" \
+      | xargs -n $((1000/NIX_BUILD_CORES + 1)) -P $NIX_BUILD_CORES \
+        $out/bin/emacs --batch -l comp --eval "(while argv \
+          (comp-trampoline-compile (intern (pop argv))))"
+    mkdir -p $out/share/emacs/native-lisp
+    $out/bin/emacs --batch \
+      --eval "(add-to-list 'native-comp-eln-load-path \"$out/share/emacs/native-lisp\")" \
+      -f batch-native-compile $out/share/emacs/site-lisp/site-start.el
   '';
 
   postFixup = lib.concatStringsSep "\n" [
@@ -156,18 +187,14 @@ in stdenv.mkDerivation {
         "$out/bin/emacs"
       patchelf --add-needed "libXcursor.so.1" "$out/bin/emacs"
     '')
-
-    (lib.optionalString nativeComp ''
-      wrapProgram $out/bin/emacs-* --prefix PATH : "${lib.makeBinPath [ binutils binutils-unwrapped ]}"
-    '')
-
   ];
 
   passthru = {
     inherit nativeComp;
+    pkgs = dontRecurseIntoAttrs (emacsPackagesFor emacs);
   };
 
-  meta = with stdenv.lib; {
+  meta = with lib; {
     description = "The extensible, customizable GNU text editor";
     homepage    = "https://www.gnu.org/software/emacs/";
     license     = licenses.gpl3Plus;
@@ -191,4 +218,5 @@ in stdenv.mkDerivation {
       separately.
     '';
   };
-}
+});
+in emacs