diff --git a/pkgs/applications/editors/emacs/generic.nix b/pkgs/applications/editors/emacs/generic.nix index a84cb41bf30..101dbdaa2e9 100644 --- a/pkgs/applications/editors/emacs/generic.nix +++ b/pkgs/applications/editors/emacs/generic.nix @@ -42,7 +42,12 @@ assert withXwidgets -> withGTK3 && webkitgtk != null; let -in stdenv.mkDerivation { +in stdenv.mkDerivation (lib.optionalAttrs nativeComp { + NATIVE_FULL_AOT = "1"; + LIBRARY_PATH = "${lib.getLib stdenv.cc.libc}/lib"; +} // lib.optionalAttrs stdenv.isDarwin { + CFLAGS = "-DMAC_OS_X_VERSION_MAX_ALLOWED=101200"; +} // { inherit pname version patches; src = fetchurl { @@ -88,10 +93,6 @@ in stdenv.mkDerivation { "" ]; - CFLAGS = "-DMAC_OS_X_VERSION_MAX_ALLOWED=101200"; - - LIBRARY_PATH = if nativeComp then "${lib.getLib stdenv.cc.libc}/lib" else ""; - nativeBuildInputs = [ pkgconfig makeWrapper ] ++ lib.optionals srcRepo [ autoreconfHook texinfo ] ++ lib.optional (withX && (withGTK3 || withXwidgets)) wrapGAppsHook; @@ -155,6 +156,11 @@ in stdenv.mkDerivation { 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 '' + mkdir -p $out/share/emacs/native-lisp + $out/bin/emacs --batch \ + --eval "(add-to-list '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" [ @@ -195,4 +201,4 @@ in stdenv.mkDerivation { separately. ''; }; -} +}) diff --git a/pkgs/applications/editors/emacs/site-start.el b/pkgs/applications/editors/emacs/site-start.el index 86cad1132f6..01a6422d731 100644 --- a/pkgs/applications/editors/emacs/site-start.el +++ b/pkgs/applications/editors/emacs/site-start.el @@ -34,6 +34,25 @@ least specific (the system profile)" (setenv "EMACSLOADPATH" (when new-env-list (mapconcat 'identity new-env-list ":")))))) +(let ((wrapper-site-lisp (getenv "emacsWithPackages_siteLispNative")) + (env-load-path (getenv "EMACSNATIVELOADPATH"))) + (when wrapper-site-lisp + (setenv "emacsWithPackages_siteLispNative" nil)) + (when (and wrapper-site-lisp env-load-path) + (let* ((env-list (split-string env-load-path ":")) + (new-env-list (delete wrapper-site-lisp env-list))) + (setenv "EMACSNATIVELOADPATH" (when new-env-list + (mapconcat 'identity new-env-list ":")))))) + +;;; Set up native-comp load path. +(when (featurep 'comp) + ;; Append native-comp subdirectories from `NIX_PROFILES'. + (setq comp-eln-load-path + (append (mapcar (lambda (profile-dir) + (concat profile-dir "/share/emacs/native-lisp/")) + (nix--profile-paths)) + comp-eln-load-path))) + ;;; Make `woman' find the man pages (defvar woman-manpath) (eval-after-load 'woman diff --git a/pkgs/build-support/emacs/generic.nix b/pkgs/build-support/emacs/generic.nix index 956787ad59e..588699517ba 100644 --- a/pkgs/build-support/emacs/generic.nix +++ b/pkgs/build-support/emacs/generic.nix @@ -60,10 +60,13 @@ stdenv.mkDerivation ({ LIBRARY_PATH = "${lib.getLib stdenv.cc.libc}/lib"; - postInstall = '' - find $out/share/emacs -type f -name '*.el' -print0 | xargs -0 -n 1 -I {} -P $NIX_BUILD_CORES sh -c "emacs --batch -f batch-native-compile {} || true" - ''; + addEmacsNativeLoadPath = true; + postInstall = '' + find $out/share/emacs -type f -name '*.el' -print0 \ + | xargs -0 -n 1 -I {} -P $NIX_BUILD_CORES sh -c \ + "emacs --batch --eval=\"(add-to-list 'comp-eln-load-path \\\"$out/share/emacs/native-lisp/\\\")\" -f batch-native-compile {} || true" + ''; } // removeAttrs args [ "buildInputs" "packageRequires" diff --git a/pkgs/build-support/emacs/setup-hook.sh b/pkgs/build-support/emacs/setup-hook.sh index 83e995631b3..f6f2331b8e0 100644 --- a/pkgs/build-support/emacs/setup-hook.sh +++ b/pkgs/build-support/emacs/setup-hook.sh @@ -7,9 +7,20 @@ addToEmacsLoadPath() { fi } +addToEmacsNativeLoadPath() { + local nativeDir="$1" + if [[ -d $nativeDir && ${EMACSNATIVELOADPATH-} != *"$nativeDir":* ]]; then + export EMACSNATIVELOADPATH="$nativeDir:${EMACSNATIVELOADPATH-}" + fi +} + addEmacsVars () { addToEmacsLoadPath "$1/share/emacs/site-lisp" + if [ -n "${addEmacsNativeLoadPath:-}" ]; then + addToEmacsNativeLoadPath "$1/share/emacs/native-lisp" + fi + # Add sub paths to the Emacs load path if it is a directory # containing .el files. This is necessary to build some packages, # e.g., using trivialBuild. diff --git a/pkgs/build-support/emacs/wrapper.nix b/pkgs/build-support/emacs/wrapper.nix index 0afd0f831fe..eca80ecf0af 100644 --- a/pkgs/build-support/emacs/wrapper.nix +++ b/pkgs/build-support/emacs/wrapper.nix @@ -34,7 +34,15 @@ in customEmacsPackages.emacsWithPackages (epkgs: [ epkgs.evil epkgs.magit ]) { lib, lndir, makeWrapper, runCommand }: self: -with lib; let inherit (self) emacs; in +with lib; + +let + + inherit (self) emacs; + + nativeComp = emacs.nativeComp or false; + +in packagesFun: # packages explicitly requested by the user @@ -95,6 +103,9 @@ runCommand } mkdir -p $out/bin mkdir -p $out/share/emacs/site-lisp + ${optionalString emacs.nativeComp '' + mkdir -p $out/share/emacs/native-lisp + ''} local requires for pkg in $explicitRequires; do @@ -116,6 +127,9 @@ runCommand linkEmacsPackage() { linkPath "$1" "bin" "bin" linkPath "$1" "share/emacs/site-lisp" "share/emacs/site-lisp" + ${optionalString nativeComp '' + linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp" + ''} } # Iterate over the array of inputs (avoiding nix's own interpolation) @@ -138,12 +152,21 @@ runCommand (load-file "$emacs/share/emacs/site-lisp/site-start.el") (add-to-list 'load-path "$out/share/emacs/site-lisp") (add-to-list 'exec-path "$out/bin") + ${optionalString nativeComp '' + (add-to-list 'comp-eln-load-path "$out/share/emacs/native-lisp/") + ''} EOF # Link subdirs.el from the emacs distribution ln -s $emacs/share/emacs/site-lisp/subdirs.el -T $subdirs # Byte-compiling improves start-up time only slightly, but costs nothing. $emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs" + + ${optionalString nativeComp '' + $emacs/bin/emacs --batch \ + --eval "(add-to-list 'comp-eln-load-path \"$out/share/emacs/native-lisp/\")" \ + -f batch-native-compile "$siteStart" "$subdirs" + ''} ''; inherit (emacs) meta; @@ -159,8 +182,14 @@ runCommand substitute ${./wrapper.sh} $out/bin/$progname \ --subst-var-by bash ${emacs.stdenv.shell} \ --subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \ + --subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp:" \ --subst-var prog chmod +x $out/bin/$progname + + makeWrapper "$prog" "$out/bin/$progname" \ + --suffix EMACSLOADPATH ":" "$deps/share/emacs/site-lisp:" \ + --suffix EMACSNATIVELOADPATH ":" "$deps/share/emacs/native-lisp:" + done # Wrap MacOS app @@ -173,11 +202,16 @@ runCommand $emacs/Applications/Emacs.app/Contents/Resources \ $out/Applications/Emacs.app/Contents + substitute ${./wrapper.sh} $out/Applications/Emacs.app/Contents/MacOS/Emacs \ --subst-var-by bash ${emacs.stdenv.shell} \ --subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \ --subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs" chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs + + makeWrapper $emacs/Applications/Emacs.app/Contents/MacOS/Emacs $out/Applications/Emacs.app/Contents/MacOS/Emacs \ + --suffix EMACSLOADPATH ":" "$deps/share/emacs/site-lisp:" \ + --suffix EMACSNATIVELOADPATH ":" "$deps/share/emacs/native-lisp:" fi mkdir -p $out/share diff --git a/pkgs/build-support/emacs/wrapper.sh b/pkgs/build-support/emacs/wrapper.sh index 96c9a8a60ea..e8eecb8c869 100644 --- a/pkgs/build-support/emacs/wrapper.sh +++ b/pkgs/build-support/emacs/wrapper.sh @@ -3,6 +3,7 @@ IFS=: newLoadPath=() +newNativeLoadPath=() added= if [[ -n $EMACSLOADPATH ]] @@ -21,7 +22,26 @@ else newLoadPath+=("") fi +if [[ -n $EMACSNATIVELOADPATH ]] +then + while read -rd: entry + do + if [[ -z $entry && -z $added ]] + then + newNativeLoadPath+=(@wrapperSiteLispNative@) + added=1 + fi + newNativeLoadPath+=("$entry") + done <<< "$EMACSNATIVELOADPATH:" +else + newNativeLoadPath+=(@wrapperSiteLispNative@) + newNativeLoadPath+=("") +fi + export EMACSLOADPATH="${newLoadPath[*]}" export emacsWithPackages_siteLisp=@wrapperSiteLisp@ +export EMACSNATIVELOADPATH="${newNativeLoadPath[*]}" +export emacsWithPackages_siteLispNative=@wrapperSiteLispNative@ + exec @prog@ "$@"