1# generic builder for Emacs packages
2
3{
4 lib,
5 stdenv,
6 emacs,
7 texinfo,
8 ...
9}:
10
11let
12 inherit (lib) optionalAttrs;
13
14in
15
16lib.extendMkDerivation {
17 constructDrv = stdenv.mkDerivation;
18 extendDrvArgs =
19 finalAttrs:
20
21 {
22 buildInputs ? [ ],
23 nativeBuildInputs ? [ ],
24 packageRequires ? [ ],
25 propagatedBuildInputs ? [ ],
26 propagatedUserEnvPkgs ? [ ],
27 postInstall ? "",
28 meta ? { },
29 turnCompilationWarningToError ? false,
30 ignoreCompilationError ? false,
31 ...
32 }@args:
33
34 {
35 name = args.name or "emacs-${finalAttrs.pname}-${finalAttrs.version}";
36
37 unpackCmd =
38 args.unpackCmd or ''
39 case "$curSrc" in
40 *.el)
41 # keep original source filename without the hash
42 local filename=$(basename "$curSrc")
43 filename="''${filename:33}"
44 cp $curSrc $filename
45 chmod +w $filename
46 sourceRoot="."
47 ;;
48 *)
49 _defaultUnpack "$curSrc"
50 ;;
51 esac
52 '';
53
54 inherit packageRequires;
55 buildInputs = [ emacs ] ++ buildInputs;
56 nativeBuildInputs = [
57 emacs
58 texinfo
59 ]
60 ++ nativeBuildInputs;
61 propagatedBuildInputs = finalAttrs.packageRequires ++ propagatedBuildInputs;
62 propagatedUserEnvPkgs = finalAttrs.packageRequires ++ propagatedUserEnvPkgs;
63
64 strictDeps = args.strictDeps or true;
65 __structuredAttrs = args.__structuredAttrs or true;
66
67 inherit turnCompilationWarningToError ignoreCompilationError;
68
69 meta = {
70 broken = false;
71 platforms = emacs.meta.platforms;
72 }
73 // optionalAttrs ((args.src.meta.homepage or "") != "") {
74 homepage = args.src.meta.homepage;
75 }
76 // meta;
77 }
78
79 // optionalAttrs (emacs.withNativeCompilation or false) {
80
81 addEmacsNativeLoadPath = args.addEmacsNativeLoadPath or true;
82
83 postInstall = ''
84 # Besides adding the output directory to the native load path, make sure
85 # the current package's elisp files are in the load path, otherwise
86 # (require 'file-b) from file-a.el in the same package will fail.
87 mkdir -p $out/share/emacs/native-lisp
88 addEmacsVars "$out"
89
90 # package-activate-all is used to activate packages. In other builder
91 # helpers, package-initialize is used for this purpose because
92 # package-activate-all is not available before Emacs 27.
93 find $out/share/emacs -type f -name '*.el' -not -name ".dir-locals.el" -print0 \
94 | xargs --verbose -0 -I {} -n 1 -P $NIX_BUILD_CORES sh -c \
95 "emacs \
96 --batch \
97 -f package-activate-all \
98 --eval '(setq native-comp-eln-load-path (cdr native-comp-eln-load-path))' \
99 --eval '(let ((default-directory \"$out/share/emacs/site-lisp\")) (normal-top-level-add-subdirs-to-load-path))' \
100 --eval '(setq large-file-warning-threshold nil)' \
101 --eval '(setq byte-compile-error-on-warn ${
102 if finalAttrs.turnCompilationWarningToError then "t" else "nil"
103 })' \
104 -f batch-native-compile {} \
105 || exit ${if finalAttrs.ignoreCompilationError then "0" else "\\$?"}"
106 ''
107 + postInstall;
108 };
109
110}