I'm making an effort to clean up our Emacs packaging and use autogenerated packages whenever possible.
This is an incomplete list of things I want to achieve:
emacsPackages
& rename emacsPackagesNg
-> emacsPackages
https://github.com/NixOS/nixpkgs/pull/66301Here's a weird one for you: I added org-jira
to my config using emacsWithPackages
, including org
(which should pull from the Org repo). It is byte-compiled using melpaBuild
, as are all packages in melpa-packages.nix
.
Unfortunately, at runtime, org-jira
breaks, because it's byte-compiled against the version of Org that is shipped with Emacs, and not the one I am bundling in the generated site-lisp
. This is the issue showing the error, and the resolution (delete .elc files so it is recompiled when loaded): https://github.com/ahungry/org-jira/issues/163
So, to work around this, I override org-jira
and explicitly add org
to packageRequires
in order to get it to load a recent Org and not the builtin version.
My questions, then, are:
org
in their Package-Requires
? It is built-in, after all, but I suspect the Emacs packaging infrastructure assumes byte-compilation at runtime, and not the per-package byte-compilation stage performed by Nix.packageRequires
in case they are also published to an ELPA repo, in order to avoid errors as a result of byte-compilation?emacsWithPackages
builder itself, so it has a full site-lisp
to resolve references during compilation?IMHO:
- Should these packages be declaring
org
in theirPackage-Requires
? It is built-in, after all, but I suspect the Emacs packaging infrastructure assumes byte-compilation at runtime, and not the per-package byte-compilation stage performed by Nix.
Ideally, yes. (E.g. note that Haskell's Cabal packages do explicitly list versions of GHC builtin libraries they use.) In practice, making all of them obey this would be a lot of effort.
- Do we need to manually add builtin libraries to
packageRequires
in case they are also published to an ELPA repo, in order to avoid errors as a result of byte-compilation?
I would rather not, too much effort.
- Could we implicitly add certain builtin libraries from the resolved package set to all packages, in case they are loaded during byte-compilation?
Yes, ideally, there should be a emacsBuiltin
attrset in emacsPackages
(of a lowest priority for fixpointing) all pointing to current emacs
, all of which can then be added as requisites to most packages by default. In such a setup we will, at most, need to manually override org
and the rest of builtin packages present in other package sets so that they won't depend on themselves when fixpointing.
- Is what we are doing correct at all? Should we defer byte-compilation to the
emacsWithPackages
builder itself, so it has a fullsite-lisp
to resolve references during compilation?
That's an option that will solve your issue, but it will not solve the underlying issue. IMHO, broken byte-compilation is just a tip of an iceberg here. E.g., say one package hardcodes a path to binary/script from its dependency while being make
ed.
My two cents:
I am fairly happy with my nix-doom-emacs derivation.
There are two challenges packaging doom in its current state:
Ran into an issue similar to https://github.com/NixOS/nixpkgs/issues/66303#issuecomment-520575515 while testing Emacs 27.0.90. In this case, some package is pulling in seq
from ELPA and byte-compiling against it instead of the built-in seq
feature. This results in an infinite recursion at startup, because seq-subseq
used to delegate to cl-subseq
, but now cl-subseq
calls the former.
In this case, I don't want seq
to be pulled in from ELPA, so there would need to be some mechanism to prefer built-in packages if available.
Hello,
I am currently developing a Nix-based framework for testing Emacs packages, which uses Steve Purcell's nix-emacs-ci for backported previous versions of Emacs. It also uses emacs-overlay for a fresh set of packages required by a package under test.
In some situations, however, it fails to run tests on older versions of Emacs, and this seems to be about built-in packages of Emacs. For example, lsp-dart
fails on Emacs 25.2 with the following error due to missing define-symbol-prop
function:
Debugger entered--Lisp error: (void-function define-symbol-prop)
define-symbol-prop(lsp-range--pcase-macroexpander edebug-form-spec nil)
byte-code("300301302303#300304305301#303207" [define-symbol-prop lsp-range--pcase-macroexpander edebug-form-spec nil lsp-range pcase-macroexpander] 5)
require(lsp-mode)
eval-buffer(#nil "/run/user/1000/lsp-dart-ert5uy/lsp-dart-utils.el" nil t) ; Reading at buffer position 822
load-with-code-conversion("/run/user/1000/lsp-dart-ert5uy/lsp-dart-utils.el" "/run/user/1000/lsp-dart-ert5uy/lsp-dart-utils.el" nil t)
require(lsp-dart-utils)
eval-buffer(#nil "/run/user/1000/lsp-dart-ert5uy/test/lsp-dart-utils-test.el" nil t) ; Reading at buffer position 784
lsp-mode
uses pcase-defmacro
macro, which had already existed in Emacs 25.2 but changed to call define-symbol-prop
function in Emacs 26, which had not existed before. I suppose Emacs packages in the Nix repo are built with builtin packages contained in the latest version of Emacs (26.3 at present), which can cause issues in old versions of Emacs. Is this view correct?
What would be a proper solution to run latest packages on older versions of Emacs? Is it necessary to override every package depending on such built-in packages, as suggested in https://github.com/NixOS/nixpkgs/issues/66303#issuecomment-520575515? Or should I even create a different variant of package set for each version of Emacs? Would wrapping macro expansions with eval-and-compile
or something would prevent the missing function error? Thank you in advance.
@tadfisher I just ran into the same problem. Did you ever resolve your case with cl-subseq
and seq-subseq
calling each other?
Most helpful comment
My two cents:
I am fairly happy with my nix-doom-emacs derivation.
There are two challenges packaging doom in its current state: