* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. [not found] <87ft3ysen7.fsf@gmail.com> @ 2020-12-22 8:51 ` Leo Prikler 2020-12-22 18:09 ` Maxim Cournoyer 0 siblings, 1 reply; 8+ messages in thread From: Leo Prikler @ 2020-12-22 8:51 UTC (permalink / raw) To: Maxim Cournoyer; +Cc: 45316 Hello Maxim, As someone, who lobbied for the current status quo, I have some thoughts to share. Am Montag, den 21.12.2020, 22:28 -0500 schrieb Maxim Cournoyer: > The Emacs packages built with the Emacs built system used to be > installed in a sub-directory under the share/emacs/guix.d/ directory, > but this was changed in commit > 65a7dd2950ca13a8b942b2836260a2192351b271 > shortly after having accommodated the site-start.el machinery to > enable > loading packages from any profile (via the EMACSLOADPATH search path > specification). Won't this reintroduce <https://bugs.gnu.org/38309> then? > While this change allowed to expose simply and directly the packages > found in EMACSLOADPATH, it does introduce the risk of file name > collisions when multiple Emacs packages are joined in the same > profile, > especially with Emacs packages increasing in complexity (e.g., using > more than a single .el file!) and expecting to have both their > sources > and resources extracted under their own nested directory rather than > as > a flat collection (ELPA, MELPA). > One recent example I stumbled on was attempting to use the > emacs-yasnippet-snippets package along with emacs-elpy; both wanted > to > install a 'snippets' directory to share/emacs/site-lisp/snippets, > collided and resulted in problems that prove difficult to understand. I believe that to be a problem in those packages. Data should not be installed into share/emacs/site-lisp, but share/emacs/etc. See for instance also emacs-telega, which – while not quite adhering to the above – installs its data in share/emacs/{telega-contrib,telega-data}. Regardless of what you intend to do with site-lisp otherwise, data files should *not*, I repeat *not* be installed there. I do believe standardizing share/emacs/etc is the way to go, however. > This is what motivated this patch series, where the site-start.el > auxiliary code used for package discovery is extended to support > packages installed in their own directory under a 'share/emacs/guix' > installation prefix, via Emacs' own package library! > > The emacs-build-system is updated for this new installation prefix, > as > well as existing packages and documentation. Parting with a directly > usable EMACSLOADPATH means that site-start.el *must* run for packages > to > appear in the load-path; that means for running a test suite, the -Q > or > --quick Emacs options cannot be used, since it implies --no-site- > file. Having no usable EMACSLOADPATH sounds like a dealbreaker to me. Could one be restored by using direct subdirectories to share/emacs/site-lisp or would that merely be a cosmetic change? > + Avoid inter-package file name collisions. Note: This regards data, which should not be stored in site-lisp to begin with. You don't get any benefits doing this for code, because Emacs has no strong module system. > + Better integration with user installed packages via M-x > package-install. The Guix-installed packages are listed in M-x > package-list as 'external'. That does sounds like a genuine pro to me. > - Slightly more complex loader (although much of it is offloaded to > package.el), thus slightly slower (see the comparison below). That should be bearable. > - Requires to ensure every package's test suite doesn't make use of > -Q. That not so much. Note, that test cases are not the only use for -Q! > In my opinion the benefits outweighs the cons by a comfortable > margin, > especially with the boring work of adapting the package collection > already done. > > To test the performance of the new approach, the following manifest > file > was used to test the rebuild of the ~900 Emacs packages making use of > the Emacs build system: > > A simple benchmark testing the performance of the activation of the > hundreds of Emacs packages was then run using: > > --8<---------------cut here---------------start------------->8--- > $ ./pre-inst-env guix environment --pure -m emacs-packages- > manifest.scm \ > --ad-hoc emacs > [env]$ /run/setuid-programs/sudo /bin/sh -c 'echo 3 > > /proc/sys/vm/drop_caches' > [env]$ emacs --batch --no-site-file \ > --eval="(progn (require 'guix-emacs) \ > (require 'benchmark) \ > (message \"(total gc-count gc-time) = %s\" \ > (benchmark-run 1 (guix-emacs-autoload- > packages))))" > --8<---------------cut here---------------end--------------->8--- > > On the master branch: > > --8<---------------cut here---------------start------------->8--- > [...] > Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f- > profile/share/emacs/site-lisp/zotxt-autoloads... > Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f- > profile/share/emacs/site-lisp/zoutline-autoloads... > Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f- > profile/share/emacs/site-lisp/ztree-autoloads... > (total gc-count gc-time) = (25.242400751 13 0.189669369) > --8<---------------cut here---------------end--------------->8--- > > Or about 0.65 s on a warm cache. > > On a branch with these changes: > > --8<---------------cut here---------------start------------->8--- > Error loading autoloads: (file-missing Cannot open load file No such > file or directory kotl/kotl-autoloads) > Error loading autoloads: (file-missing Cannot open load file No such > file or directory helm-easymenu) > Error loading autoloads: (file-missing Cannot open load file No such > file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr- > profile/share/emacs/site-lisp/guix/flycheck-cpplint-0.1- > 1.1d8a090/flycheck-cpplint-autoloads) > Error loading autoloads: (file-missing Cannot open load file No such > file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr- > profile/share/emacs/site-lisp/guix/evil-anzu-0.03/evil-anzu- > autoloads) > Error loading autoloads: (file-missing Cannot open load file No such > file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr- > profile/share/emacs/site-lisp/guix/erc-image-0-3.82fb387/erc-image- > autoloads) > ad-handle-definition: `ido-completing-read' got redefined > Error loading autoloads: (file-missing Cannot open load file No such > file or directory tex-site) > (total gc-count gc-time) = (26.175704339 47 0.783184412) > --8<---------------cut here---------------end--------------->8--- > > Or about 3 seconds on a warm cache. Looking at these, total does not seem to have changed much, but gc- count and gc-time more than tripled. Any idea on how to mitigate this or do we have to live with that? > There a 6 errors that would need to be looked into, but I these look > like actual packaging problems rather than new issues. The > previously > used way to load the autoloads, '(load f 'noerror)' would have masked > them. Regardless of how we handle site-lisp going forward, please do look into those issues and perhaps file them against the individual packages if they also cause (other) trouble using the current setup. Regards, Leo ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. 2020-12-22 8:51 ` bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix Leo Prikler @ 2020-12-22 18:09 ` Maxim Cournoyer 2020-12-22 19:10 ` Leo Prikler 0 siblings, 1 reply; 8+ messages in thread From: Maxim Cournoyer @ 2020-12-22 18:09 UTC (permalink / raw) To: Leo Prikler; +Cc: 45316 Hi Leo, Leo Prikler <leo.prikler@student.tugraz.at> writes: > Hello Maxim, > > As someone, who lobbied for the current status quo, I have some > thoughts to share. I'm happy you're commenting :-). > Am Montag, den 21.12.2020, 22:28 -0500 schrieb Maxim Cournoyer: >> The Emacs packages built with the Emacs built system used to be >> installed in a sub-directory under the share/emacs/guix.d/ directory, >> but this was changed in commit >> 65a7dd2950ca13a8b942b2836260a2192351b271 >> shortly after having accommodated the site-start.el machinery to >> enable >> loading packages from any profile (via the EMACSLOADPATH search path >> specification). > Won't this reintroduce <https://bugs.gnu.org/38309> then? This bug was caused by the EMACSLOADPATH environment variable being too long. This was because the original search path specification was recursively adding any directories under site-lisp/ so that package installed under a guix.d sub-directory could were directly added to the load path. In the current situation, the EMACSLOADPATH contains only the site-lisp/ directory of any profile, plus the versioned lisp/ directory of the installed Emacs package. This patch series doesn't change that, so no, that bug wouldn't be reintroduced. >> While this change allowed to expose simply and directly the packages >> found in EMACSLOADPATH, it does introduce the risk of file name >> collisions when multiple Emacs packages are joined in the same >> profile, >> especially with Emacs packages increasing in complexity (e.g., using >> more than a single .el file!) and expecting to have both their >> sources >> and resources extracted under their own nested directory rather than >> as >> a flat collection (ELPA, MELPA). > >> One recent example I stumbled on was attempting to use the >> emacs-yasnippet-snippets package along with emacs-elpy; both wanted >> to >> install a 'snippets' directory to share/emacs/site-lisp/snippets, >> collided and resulted in problems that prove difficult to understand. > I believe that to be a problem in those packages. Data should not be > installed into share/emacs/site-lisp, but share/emacs/etc. See for > instance also emacs-telega, which – while not quite adhering to the > above – installs its data in share/emacs/{telega-contrib,telega-data}. > > Regardless of what you intend to do with site-lisp otherwise, data > files should *not*, I repeat *not* be installed there. I do believe > standardizing share/emacs/etc is the way to go, however. While I agree that it would be more elegant the way you propose, that's not the way Emacs packages have been standardized. So going against the single "content directory" (c.f. info "(elisp) Packaging Basics") would break many Elisp library assumptions about where there files are, causing more friction (thus work) to adapt them in Guix. The content directory of an Elisp package can contain any kind of files (code, images, etc.), according to info "(elisp) Multi-file Packages". >> This is what motivated this patch series, where the site-start.el >> auxiliary code used for package discovery is extended to support >> packages installed in their own directory under a 'share/emacs/guix' >> installation prefix, via Emacs' own package library! >> >> The emacs-build-system is updated for this new installation prefix, >> as >> well as existing packages and documentation. Parting with a directly >> usable EMACSLOADPATH means that site-start.el *must* run for packages >> to >> appear in the load-path; that means for running a test suite, the -Q >> or >> --quick Emacs options cannot be used, since it implies --no-site- >> file. > Having no usable EMACSLOADPATH sounds like a dealbreaker to me. Could > one be restored by using direct subdirectories to share/emacs/site-lisp > or would that merely be a cosmetic change? We have two schemes to accommodate for our Emacs packages: 1. Those installed via their own mean, e.g. make install, using the gnu-build-system for example. These would still typically install their packages directly under site-lisp, possibly multiple files (that could still collide). 2. Those installed via the emacs-build-system. With the proposed changes, those now go to site-lisp/guix/. The 'guix' sub-directory makes it unambiguous that anything found under is to be loaded by package.el; the `package-directory-list' variable can be pointed to it to have the Emacs' package library discover these self-contained packages. >> + Avoid inter-package file name collisions. > Note: This regards data, which should not be stored in site-lisp to > begin with. You don't get any benefits doing this for code, because > Emacs has no strong module system. True. >> + Better integration with user installed packages via M-x >> package-install. The Guix-installed packages are listed in M-x >> package-list as 'external'. > That does sounds like a genuine pro to me. >> - Slightly more complex loader (although much of it is offloaded to >> package.el), thus slightly slower (see the comparison below). > That should be bearable. >> - Requires to ensure every package's test suite doesn't make use of >> -Q. > That not so much. Note, that test cases are not the only use for -Q! Currently if you use -Q, the Elisp libraries are in the load-path, but not loaded (you need manually do M-x load-library before you can use it), or call M-x guix-emacs-autoload-packages to load their autoloads. For programs, this mean (require 'some-library) works, but M-x some-library-autoloaded-function doesn't. After this change, if you use -Q the new style Emacs packages are not visible at all until you activate them with 'M-x load-library guix-emacs' then 'M-x guix-package-initialize', or (require 'guix-emacs) then (guix-package-initialize), programmatically. I don't see this as a problem. -Q is simply an alias for "--no-init-file" "--no-site-lisp" "--no-splash" "--no-x-resources" "--no-site-file". >> In my opinion the benefits outweighs the cons by a comfortable >> margin, >> especially with the boring work of adapting the package collection >> already done. >> >> To test the performance of the new approach, the following manifest >> file >> was used to test the rebuild of the ~900 Emacs packages making use of >> the Emacs build system: >> >> A simple benchmark testing the performance of the activation of the >> hundreds of Emacs packages was then run using: >> >> --8<---------------cut here---------------start------------->8--- >> $ ./pre-inst-env guix environment --pure -m emacs-packages- >> manifest.scm \ >> --ad-hoc emacs >> [env]$ /run/setuid-programs/sudo /bin/sh -c 'echo 3 > >> /proc/sys/vm/drop_caches' >> [env]$ emacs --batch --no-site-file \ >> --eval="(progn (require 'guix-emacs) \ >> (require 'benchmark) \ >> (message \"(total gc-count gc-time) = %s\" \ >> (benchmark-run 1 (guix-emacs-autoload- >> packages))))" >> --8<---------------cut here---------------end--------------->8--- >> >> On the master branch: >> >> --8<---------------cut here---------------start------------->8--- >> [...] >> Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f- >> profile/share/emacs/site-lisp/zotxt-autoloads... >> Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f- >> profile/share/emacs/site-lisp/zoutline-autoloads... >> Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f- >> profile/share/emacs/site-lisp/ztree-autoloads... >> (total gc-count gc-time) = (25.242400751 13 0.189669369) >> --8<---------------cut here---------------end--------------->8--- >> >> Or about 0.65 s on a warm cache. >> >> On a branch with these changes: >> >> --8<---------------cut here---------------start------------->8--- >> Error loading autoloads: (file-missing Cannot open load file No such >> file or directory kotl/kotl-autoloads) >> Error loading autoloads: (file-missing Cannot open load file No such >> file or directory helm-easymenu) >> Error loading autoloads: (file-missing Cannot open load file No such >> file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr- >> profile/share/emacs/site-lisp/guix/flycheck-cpplint-0.1- >> 1.1d8a090/flycheck-cpplint-autoloads) >> Error loading autoloads: (file-missing Cannot open load file No such >> file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr- >> profile/share/emacs/site-lisp/guix/evil-anzu-0.03/evil-anzu- >> autoloads) >> Error loading autoloads: (file-missing Cannot open load file No such >> file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr- >> profile/share/emacs/site-lisp/guix/erc-image-0-3.82fb387/erc-image- >> autoloads) >> ad-handle-definition: `ido-completing-read' got redefined >> Error loading autoloads: (file-missing Cannot open load file No such >> file or directory tex-site) >> (total gc-count gc-time) = (26.175704339 47 0.783184412) >> --8<---------------cut here---------------end--------------->8--- >> >> Or about 3 seconds on a warm cache. > Looking at these, total does not seem to have changed much, but gc- > count and gc-time more than tripled. Any idea on how to mitigate this > or do we have to live with that? I don't know enough about Elisp to offer a guess. We'd have to profile it. When put in perspective, that's 3 seconds to refresh about 900 packages. I'm guessing most users must have less than 100 Emacs packages in their collections (I have about 35). I think the current performance is good enough to not worry optimizing it at this stage. In any case, performance optimizations would need to be made to Emacs' package.el. >> There a 6 errors that would need to be looked into, but I these look >> like actual packaging problems rather than new issues. The >> previously >> used way to load the autoloads, '(load f 'noerror)' would have masked >> them. > Regardless of how we handle site-lisp going forward, please do look > into those issues and perhaps file them against the individual packages > if they also cause (other) trouble using the current setup. I'll try having a look, thanks for the reminder. Thank you for commenting! Maxim ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. 2020-12-22 18:09 ` Maxim Cournoyer @ 2020-12-22 19:10 ` Leo Prikler 2020-12-26 5:01 ` Maxim Cournoyer 0 siblings, 1 reply; 8+ messages in thread From: Leo Prikler @ 2020-12-22 19:10 UTC (permalink / raw) To: Maxim Cournoyer; +Cc: 45316 Hi Maxim, Am Dienstag, den 22.12.2020, 13:09 -0500 schrieb Maxim Cournoyer: > Hi Leo, > > Leo Prikler <leo.prikler@student.tugraz.at> writes: > > > Hello Maxim, > > > > As someone, who lobbied for the current status quo, I have some > > thoughts to share. > > I'm happy you're commenting :-). > > > Am Montag, den 21.12.2020, 22:28 -0500 schrieb Maxim Cournoyer: > > > The Emacs packages built with the Emacs built system used to be > > > installed in a sub-directory under the share/emacs/guix.d/ > > > directory, > > > but this was changed in commit > > > 65a7dd2950ca13a8b942b2836260a2192351b271 > > > shortly after having accommodated the site-start.el machinery to > > > enable > > > loading packages from any profile (via the EMACSLOADPATH search > > > path > > > specification). > > Won't this reintroduce <https://bugs.gnu.org/38309> then? > > This bug was caused by the EMACSLOADPATH environment variable being > too > long. This was because the original search path specification was > recursively adding any directories under site-lisp/ so that package > installed under a guix.d sub-directory could were directly added to > the > load path. > > In the current situation, the EMACSLOADPATH contains only the site- > lisp/ > directory of any profile, plus the versioned lisp/ directory of the > installed Emacs package. This patch series doesn't change that, so > no, > that bug wouldn't be reintroduced. Which is also the reason why our startup code changes and people have to accommodate to that, right? > > > While this change allowed to expose simply and directly the > > > packages > > > found in EMACSLOADPATH, it does introduce the risk of file name > > > collisions when multiple Emacs packages are joined in the same > > > profile, > > > especially with Emacs packages increasing in complexity (e.g., > > > using > > > more than a single .el file!) and expecting to have both their > > > sources > > > and resources extracted under their own nested directory rather > > > than > > > as > > > a flat collection (ELPA, MELPA). > > > One recent example I stumbled on was attempting to use the > > > emacs-yasnippet-snippets package along with emacs-elpy; both > > > wanted > > > to > > > install a 'snippets' directory to share/emacs/site-lisp/snippets, > > > collided and resulted in problems that prove difficult to > > > understand. > > I believe that to be a problem in those packages. Data should not > > be > > installed into share/emacs/site-lisp, but share/emacs/etc. See for > > instance also emacs-telega, which – while not quite adhering to the > > above – installs its data in share/emacs/{telega-contrib,telega- > > data}. > > > > Regardless of what you intend to do with site-lisp otherwise, data > > files should *not*, I repeat *not* be installed there. I do > > believe > > standardizing share/emacs/etc is the way to go, however. > > While I agree that it would be more elegant the way you propose, > that's > not the way Emacs packages have been standardized. So going against > the > single "content directory" (c.f. info "(elisp) Packaging Basics") > would > break many Elisp library assumptions about where there files are, > causing more friction (thus work) to adapt them in Guix. The content > directory of an Elisp package can contain any kind of files (code, > images, etc.), according to info "(elisp) Multi-file Packages". I suppose said manual is perhaps slightly outdated. > A package is either a “simple package” or a “multi-file package”. A > simple package is stored in a package archive as a single Emacs Lisp > file, while a multi-file package is stored as a tar file (containing > multiple Lisp files, and possibly non-Lisp files such as a manual). When was the last time, you've installed a tar to site-lisp? I also feel as though the expected contents are limited very much to README, COPYING and the like: --8<---------------cut here--------------begin-------------->8--- $ find ~/.guix-profile/share/emacs/27.1/lisp/ -type f \ -not -name '*.el' \ -and -not -name '*.elc' \ -and -not -name '*.el.gz' ~/.guix-profile/share/emacs/27.1/lisp/term/README ~/.guix-profile/share/emacs/27.1/lisp/COPYING ~/.guix-profile/share/emacs/27.1/lisp/README --8<---------------cut here---------------end--------------->8--- Perhaps we should ask Emacs folks how they feel about separating code and data, but bugs have already been caused here and elsewhere by stuffing them together. (I believe yasnippet was once already the culprit at some point before it got reorganized.) In the meantime, yes, doing so might cause extra work, but 1) it only affects a subset of packages, and 2) of this subset, we can prioritize those, that do exhibit this behaviour. > > > This is what motivated this patch series, where the site-start.el > > > auxiliary code used for package discovery is extended to support > > > packages installed in their own directory under a > > > 'share/emacs/guix' > > > installation prefix, via Emacs' own package library! > > > > > > The emacs-build-system is updated for this new installation > > > prefix, > > > as > > > well as existing packages and documentation. Parting with a > > > directly > > > usable EMACSLOADPATH means that site-start.el *must* run for > > > packages > > > to > > > appear in the load-path; that means for running a test suite, the > > > -Q > > > or > > > --quick Emacs options cannot be used, since it implies --no-site- > > > file. > > Having no usable EMACSLOADPATH sounds like a dealbreaker to > > me. Could > > one be restored by using direct subdirectories to share/emacs/site- > > lisp > > or would that merely be a cosmetic change? > > We have two schemes to accommodate for our Emacs packages: > > 1. Those installed via their own mean, e.g. make install, using the > gnu-build-system for example. These would still typically install > their > packages directly under site-lisp, possibly multiple files (that > could > still collide). Why? Seems inconsistent, does it not? > 2. Those installed via the emacs-build-system. With the proposed > changes, those now go to site-lisp/guix/. The 'guix' sub-directory > makes it unambiguous that anything found under is to be loaded by > package.el; the `package-directory-list' variable can be pointed to > it > to have the Emacs' package library discover these self-contained > packages. I think you've lost me here. Basically, instead of being able to `(require 'my-package)` you first need to load my-package through package.el and then can `(require 'my-package)`? I am not sure, what the benefit of that would be, if any. > Currently if you use -Q, the Elisp libraries are in the load-path, > but > not loaded (you need manually do M-x load-library before you can use > it), or call M-x guix-emacs-autoload-packages to load their > autoloads. > For programs, this mean (require 'some-library) works, but M-x > some-library-autoloaded-function doesn't. > > After this change, if you use -Q the new style Emacs packages are not > visible at all until you activate them with 'M-x load-library > guix-emacs' then 'M-x guix-package-initialize', or (require 'guix- > emacs) > then (guix-package-initialize), programmatically. I do think, that there are legitimate reasons to not require a full initialization here, particularly for the use in batch scripts, but I'm not quite sure how much work we currently put into making sure that everything is available. > I don't see this as a problem. -Q is simply an alias for > "--no-init-file" "--no-site-lisp" "--no-splash" "--no-x-resources" > "--no-site-file". But not "--no-load-path" "--no-nothing" ;) Being able to load the same libraries as without is vital for debugging and scripts. (Granted, some distros probably break with --no-site- lisp, but that's nothing to strive for imo.) > [...] > When put in perspective, that's 3 seconds to refresh about 900 > packages. I'm guessing most users must have less than 100 Emacs > packages in their collections (I have about 35). I think the current > performance is good enough to not worry optimizing it at this stage. Point taken, I don't have that many either. I was merely interested, given that I rarely dive that deep into runtime statistics of Elisp code. Regards, Leo ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. 2020-12-22 19:10 ` Leo Prikler @ 2020-12-26 5:01 ` Maxim Cournoyer 2020-12-26 10:56 ` Leo Prikler 0 siblings, 1 reply; 8+ messages in thread From: Maxim Cournoyer @ 2020-12-26 5:01 UTC (permalink / raw) To: Leo Prikler; +Cc: 45316 Hi Leo! Leo Prikler <leo.prikler@student.tugraz.at> writes: > Hi Maxim, > > Am Dienstag, den 22.12.2020, 13:09 -0500 schrieb Maxim Cournoyer: >> Hi Leo, >> >> Leo Prikler <leo.prikler@student.tugraz.at> writes: >> >> > Hello Maxim, >> > >> > As someone, who lobbied for the current status quo, I have some >> > thoughts to share. >> >> I'm happy you're commenting :-). >> >> > Am Montag, den 21.12.2020, 22:28 -0500 schrieb Maxim Cournoyer: >> > > The Emacs packages built with the Emacs built system used to be >> > > installed in a sub-directory under the share/emacs/guix.d/ >> > > directory, >> > > but this was changed in commit >> > > 65a7dd2950ca13a8b942b2836260a2192351b271 >> > > shortly after having accommodated the site-start.el machinery to >> > > enable >> > > loading packages from any profile (via the EMACSLOADPATH search >> > > path >> > > specification). >> > Won't this reintroduce <https://bugs.gnu.org/38309> then? >> >> This bug was caused by the EMACSLOADPATH environment variable being >> too >> long. This was because the original search path specification was >> recursively adding any directories under site-lisp/ so that package >> installed under a guix.d sub-directory could were directly added to >> the >> load path. >> >> In the current situation, the EMACSLOADPATH contains only the site- >> lisp/ >> directory of any profile, plus the versioned lisp/ directory of the >> installed Emacs package. This patch series doesn't change that, so >> no, >> that bug wouldn't be reintroduced. > Which is also the reason why our startup code changes and people have > to accommodate to that, right? Yes. The startup code is now responsible to activate packages found not directly in the EMACSLOADPATH (share/emacs/site-lisp), but in sub-directories under share/emacs/site-lisp/guix. >> > > While this change allowed to expose simply and directly the >> > > packages >> > > found in EMACSLOADPATH, it does introduce the risk of file name >> > > collisions when multiple Emacs packages are joined in the same >> > > profile, >> > > especially with Emacs packages increasing in complexity (e.g., >> > > using >> > > more than a single .el file!) and expecting to have both their >> > > sources >> > > and resources extracted under their own nested directory rather >> > > than >> > > as >> > > a flat collection (ELPA, MELPA). >> > > One recent example I stumbled on was attempting to use the >> > > emacs-yasnippet-snippets package along with emacs-elpy; both >> > > wanted >> > > to >> > > install a 'snippets' directory to share/emacs/site-lisp/snippets, >> > > collided and resulted in problems that prove difficult to >> > > understand. >> > I believe that to be a problem in those packages. Data should not >> > be >> > installed into share/emacs/site-lisp, but share/emacs/etc. See for >> > instance also emacs-telega, which – while not quite adhering to the >> > above – installs its data in share/emacs/{telega-contrib,telega- >> > data}. >> > >> > Regardless of what you intend to do with site-lisp otherwise, data >> > files should *not*, I repeat *not* be installed there. I do >> > believe >> > standardizing share/emacs/etc is the way to go, however. >> >> While I agree that it would be more elegant the way you propose, >> that's >> not the way Emacs packages have been standardized. So going against >> the >> sin--8<---------------cut here---------------start------------->8--- --8<---------------cut here---------------start------------->8--- gle "content directory" (c.f. info "(elisp) Packaging Basics") >> would >> break many Elisp library assumptions about where there files are, >> causing more friction (thus work) to adapt them in Guix. The content >> directory of an Elisp package can contain any kind of files (code, >> images, etc.), according to info "(elisp) Multi-file Packages". > > I suppose said manual is perhaps slightly outdated. The doc/package.texi file of the Emacs git repository is actively maintained, although cited contents above hasn't changed much for the last 8 years. In any case if you look into package.el, you'll see that package contents are fetched as a single archived, and its content installed to a single directory. >> A package is either a “simple package” or a “multi-file package”. A >> simple package is stored in a package archive as a single Emacs Lisp >> file, while a multi-file package is stored as a tar file (containing >> multiple Lisp files, and possibly non-Lisp files such as a manual). > When was the last time, you've installed a tar to site-lisp? I also > feel as though the expected contents are limited very much to README, > COPYING and the like: > > $ find ~/.guix-profile/share/emacs/27.1/lisp/ -type f \ > -not -name '*.el' \ > -and -not -name '*.elc' \ > -and -not -name '*.el.gz' > ~/.guix-profile/share/emacs/27.1/lisp/term/README > ~/.guix-profile/share/emacs/27.1/lisp/COPYING > ~/.guix-profile/share/emacs/27.1/lisp/README The lisp/ directory is for "the standard Lisp files that come with Emacs" (from info "(elisp)Library Search"). I don't think we can draw much comparison between these and user-installable packages from ELPA or MELPA. Also, just to be clear, the tar is not installed as-is; it is extracted and its contents are installed in the "content directory". Citing again '(elisp) Multi-file Packages': Prior to installation, a multi-file package is stored in a package archive as a tar file. The tar file must be named ‘NAME-VERSION.tar’, where NAME is the package name and VERSION is the version number. Its contents, once extracted, must all appear in a directory named ‘NAME-VERSION’, the “content directory” (*note Packaging Basics::). Files may also extract into subdirectories of the content directory. One of the files in the content directory must be named ‘NAME-pkg.el’. It must contain a single Lisp form, consisting of a call to the function ‘define-package’, described below. This defines the package’s attributes: version, brief description, and requirements. For example, if we distribute version 1.3 of the superfrobnicator as a multi-file package, the tar file would be ‘superfrobnicator-1.3.tar’. Its contents would extract into the directory ‘superfrobnicator-1.3’, and one of these would be the file ‘superfrobnicator-pkg.el’. If you want to have a clearer idea of how packages from ELPA and the likes are installed, you can have a peek into the 'package.el' file shipped with Emacs (spoiler: it's basically just extracting the contents of the package archive to a single directory -- see the `package-unpack' procedure). Here's an experiment I've done with a profile containing the whole of our current emacs-build-system based packages, with this current change, that checks for collision at the top level of a package installation directory: --8<---------------cut here---------------end--------------->8--- $ ./pre-inst-env guix package -p /tmp/nnew-emacs -m emacs-packages-manifest.scm $ find -L /tmp/nnew-emacs/share/emacs/site-lisp/guix -maxdepth 2 -mindepth 2 -not -regex '.*\.elc?$' \ | awk -F '/' '{ if ($9 in packages) \ {printf("%s directory of %s package collides with that of package %s\n", $9, $8, packages[$9])} \ else {packages[$9] = $8} }' doc directory of modus-operandi-theme-1.0.2 package collides with that of package racket-mode-0.0.2-6.5eb31a2 tools directory of unidecode-0.2-1.5502ada package collides with that of package company-cabal-0.3.0-1.62112a7 snippets directory of minitest-0.8.0-1.1aadb78 package collides with that of package elpy-1.35.0 test directory of realgud-1.5.1 package collides with that of package flycheck-haskell-0.8-2.32ddff8 snippets directory of yasnippet-snippets-0.23 package collides with that of package elpy-1.35.0 snippets directory of haskell-snippets-0.1.0-0.07b0f46 package collides with that of package elpy-1.35.0 snippets directory of rspec-1.11-1.66ea7cc package collides with that of package elpy-1.35.0 doc directory of modus-themes-1.0.2 package collides with that of package racket-mode-0.0.2-6.5eb31a2 data directory of emojify-1.2 package collides with that of package unidecode-0.2-1.5502ada test directory of systemd-mode-1.6 package collides with that of package flycheck-haskell-0.8-2.32ddff8 lib directory of slime-2.26.1 package collides with that of package robe-0.8.2 contrib directory of sly-1.0.0-7.68561f1 package collides with that of package slime-2.26.1 lib directory of sly-1.0.0-7.68561f1 package collides with that of package robe-0.8.2 doc directory of modus-vivendi-theme-1.0.2 package collides with that of package racket-mode-0.0.2-6.5eb31a2 doc directory of evil-1.14.0 package collides with that of package racket-mode-0.0.2-6.5eb31a2 data directory of all-the-icons-4.0.1 package collides with that of package unidecode-0.2-1.5502ada snippets directory of feature-mode-20190801-1.11ae167 package collides with that of package elpy-1.35.0 --8<---------------cut here---------------end--------------->8--- So 17 Emacs packages in Guix currently conflict, and Guix seems to be silent about it when building a profile with them via 'guix package -p' (a bug?). > Perhaps we should ask Emacs folks how they feel about separating code > and data, but bugs have already been caused here and elsewhere by > stuffing them together. (I believe yasnippet was once already the > culprit at some point before it got reorganized.) In the meantime, > yes, doing so might cause extra work, but > 1) it only affects a subset of packages, and > 2) of this subset, we can prioritize those, that do exhibit this > behaviour. The above does output does show that's it's a subset of the packages that are affected. [...] >> We have two schemes to accommodate for our Emacs packages: >> >> 1. Those installed via their own mean, e.g. make install, using the >> gnu-build-system for example. These would still typically install >> their >> packages directly under site-lisp, possibly multiple files (that >> could >> still collide). > Why? Seems inconsistent, does it not? They can be adapted in time; until then it's easy to accommodate both. >> 2. Those installed via the emacs-build-system. With the proposed >> changes, those now go to site-lisp/guix/. The 'guix' sub-directory >> makes it unambiguous that anything found under is to be loaded by >> package.el; the `package-directory-list' variable can be pointed to >> it >> to have the Emacs' package library discover these self-contained >> packages. > I think you've lost me here. Basically, instead of being able to > `(require 'my-package)` you first need to load my-package through > package.el and then can `(require 'my-package)`? I am not sure, what > the benefit of that would be, if any. Only if you've specified --no-site-start, which would disable user-installed package discovery. This is the drawback of the trade-off, not the benefit :-). >> Currently if you use -Q, the Elisp libraries are in the load-path, >> but >> not loaded (you need manually do M-x load-library before you can use >> it), or call M-x guix-emacs-autoload-packages to load their >> autoloads. >> For programs, this mean (require 'some-library) works, but M-x >> some-library-autoloaded-function doesn't. >> >> After this change, if you use -Q the new style Emacs packages are not >> visible at all until you activate them with 'M-x load-library >> guix-emacs' then 'M-x guix-package-initialize', or (require 'guix- >> emacs) >> then (guix-package-initialize), programmatically. > I do think, that there are legitimate reasons to not require a full > initialization here, particularly for the use in batch scripts, but I'm > not quite sure how much work we currently put into making sure that > everything is available. That's a fair point, although I'm not concerned about the overhead of loading compiled autoloads files. >> I don't see this as a problem. -Q is simply an alias for >> "--no-init-file" "--no-site-lisp" "--no-splash" "--no-x-resources" >> "--no-site-file". > But not "--no-load-path" "--no-nothing" ;) One could argue that the spirit of -Q is to give an Emacs as minimal as possible (that's what the Emacs manual has to say about it, and the implicit --no-site-lisp has the meaning of "no user installed packages"). > Being able to load the same libraries as without is vital for debugging > and scripts. (Granted, some distros probably break with --no-site- > lisp, but that's nothing to strive for imo.) I think you meant --no-site-file here. There's not much magic; if you allow it to run, user installed packages are added to the load path and autoloaded; if you don't you don't then you only get Emacs standard libraries. Nothing else happens in the site-start.el file in Guix proposed here. Scripting works well enough that our 900'ish packages can be rebuilt with the change, many of which come with a test suite. Thanks for having me think harder about if this is really desirable/needed. For me the main plus is that we'd be adhering to the current standards used for Emacs packaging: everything is unpacked into a single directory owned by that package, so as long as we include any needed resources in the #:include argument of the emacs-build-system, it works as upstream intended it, with no need to patch variables or anything. I expect this situation to worsen as Emacs packages tend to get more complicated, and I don't feel strongly enough about it to go arguing about Emacs packaging standards on the Emacs mailing list :-). On the minus side it makes the startup slightly more expensive in terms of pure scripting, and requires the users to be mindful that site-start.el evaluation is needed for the user installed packages to be activated. Further thoughts? Thanks again, Maxim ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. 2020-12-26 5:01 ` Maxim Cournoyer @ 2020-12-26 10:56 ` Leo Prikler 2020-12-27 4:44 ` Maxim Cournoyer 0 siblings, 1 reply; 8+ messages in thread From: Leo Prikler @ 2020-12-26 10:56 UTC (permalink / raw) To: Maxim Cournoyer; +Cc: 45316 Hi Maxim, Am Samstag, den 26.12.2020, 00:01 -0500 schrieb Maxim Cournoyer: > > > > > While this change allowed to expose simply and directly the > > > > > packages > > > > > found in EMACSLOADPATH, it does introduce the risk of file > > > > > name > > > > > collisions when multiple Emacs packages are joined in the > > > > > same > > > > > profile, > > > > > especially with Emacs packages increasing in complexity > > > > > (e.g., > > > > > using > > > > > more than a single .el file!) and expecting to have both > > > > > their > > > > > sources > > > > > and resources extracted under their own nested directory > > > > > rather > > > > > than > > > > > as > > > > > a flat collection (ELPA, MELPA). > > > > > One recent example I stumbled on was attempting to use the > > > > > emacs-yasnippet-snippets package along with emacs-elpy; both > > > > > wanted > > > > > to > > > > > install a 'snippets' directory to share/emacs/site- > > > > > lisp/snippets, > > > > > collided and resulted in problems that prove difficult to > > > > > understand. > > > > I believe that to be a problem in those packages. Data should > > > > not > > > > be > > > > installed into share/emacs/site-lisp, but share/emacs/etc. See > > > > for > > > > instance also emacs-telega, which – while not quite adhering to > > > > the > > > > above – installs its data in share/emacs/{telega- > > > > contrib,telega- > > > > data}. > > > > > > > > Regardless of what you intend to do with site-lisp otherwise, > > > > data > > > > files should *not*, I repeat *not* be installed there. I do > > > > believe > > > > standardizing share/emacs/etc is the way to go, however. > > > > > > While I agree that it would be more elegant the way you propose, > > > that's > > > not the way Emacs packages have been standardized. So going > > > against > > > the > > > sin--8<---------------cut here---------------start------------- > > > >8--- > --8<---------------cut here---------------start------------->8--- > gle "content directory" (c.f. info "(elisp) Packaging Basics") > > > would > > > break many Elisp library assumptions about where there files are, > > > causing more friction (thus work) to adapt them in Guix. The > > > content > > > directory of an Elisp package can contain any kind of files > > > (code, > > > images, etc.), according to info "(elisp) Multi-file Packages". > > > > I suppose said manual is perhaps slightly outdated. > > The doc/package.texi file of the Emacs git repository is actively > maintained, although cited contents above hasn't changed much for the > last 8 years. In any case if you look into package.el, you'll see > that > package contents are fetched as a single archived, and its content > installed to a single directory. > > > > A package is either a “simple package” or a “multi-file > > > package”. A > > > simple package is stored in a package archive as a single Emacs > > > Lisp > > > file, while a multi-file package is stored as a tar file > > > (containing > > > multiple Lisp files, and possibly non-Lisp files such as a > > > manual). > > When was the last time, you've installed a tar to site-lisp? I > > also > > feel as though the expected contents are limited very much to > > README, > > COPYING and the like: > > > > $ find ~/.guix-profile/share/emacs/27.1/lisp/ -type f \ > > -not -name '*.el' \ > > -and -not -name '*.elc' \ > > -and -not -name '*.el.gz' > > ~/.guix-profile/share/emacs/27.1/lisp/term/README > > ~/.guix-profile/share/emacs/27.1/lisp/COPYING > > ~/.guix-profile/share/emacs/27.1/lisp/README > > The lisp/ directory is for "the standard Lisp files that come with > Emacs" (from info "(elisp)Library Search"). I don't think we can > draw > much comparison between these and user-installable packages from ELPA > or > MELPA. Fair enough, perhaps I read too much into that. > Also, just to be clear, the tar is not installed as-is; it is > extracted > and its contents are installed in the "content directory". Citing > again > '(elisp) Multi-file Packages': > > Prior to installation, a multi-file package is stored in a > package > archive as a tar file. The tar file must be named ‘NAME- > VERSION.tar’, > where NAME is the package name and VERSION is the version > number. Its > contents, once extracted, must all appear in a directory named > ‘NAME-VERSION’, the “content directory” (*note Packaging > Basics::). > Files may also extract into subdirectories of the content > directory. > > One of the files in the content directory must be named > ‘NAME-pkg.el’. It must contain a single Lisp form, consisting of > a call > to the function ‘define-package’, described below. This defines > the > package’s attributes: version, brief description, and > requirements. > > For example, if we distribute version 1.3 of the > superfrobnicator as > a multi-file package, the tar file would be ‘superfrobnicator- > 1.3.tar’. > Its contents would extract into the directory ‘superfrobnicator- > 1.3’, > and one of these would be the file ‘superfrobnicator-pkg.el’. > > If you want to have a clearer idea of how packages from ELPA and the > likes are installed, you can have a peek into the 'package.el' file > shipped with Emacs (spoiler: it's basically just extracting the > contents > of the package archive to a single directory -- see the `package- > unpack' > procedure). If we follow that to the letter, should we not install those packages directly to site-lisp/$PACKAGE-$VERSION? Why the guix directory? Also, if we do go that route, I think we should install a subdirs.el through a profile hook, that adds all these package directories to the load path. See also '(elisp) Startup Summary'. Alternatively, we can let subdirs.el defer to guix-emacs.el, but that'd be very cheeky. Either way, we should definitely make -Q work. > Here's an experiment I've done with a profile containing the whole of > our current emacs-build-system based packages, with this current > change, > that checks for collision at the top level of a package installation > directory: > > --8<---------------cut here---------------end--------------->8--- > $ ./pre-inst-env guix package -p /tmp/nnew-emacs -m emacs-packages- > manifest.scm > > $ find -L /tmp/nnew-emacs/share/emacs/site-lisp/guix -maxdepth 2 > -mindepth 2 -not -regex '.*\.elc?$' \ > | awk -F '/' '{ if ($9 in packages) \ > {printf("%s directory of %s package collides with that of > package %s\n", $9, $8, packages[$9])} \ > else {packages[$9] = $8} }' > > doc directory of modus-operandi-theme-1.0.2 package collides with > that of package racket-mode-0.0.2-6.5eb31a2 > tools directory of unidecode-0.2-1.5502ada package collides with that > of package company-cabal-0.3.0-1.62112a7 > snippets directory of minitest-0.8.0-1.1aadb78 package collides with > that of package elpy-1.35.0 > test directory of realgud-1.5.1 package collides with that of package > flycheck-haskell-0.8-2.32ddff8 > snippets directory of yasnippet-snippets-0.23 package collides with > that of package elpy-1.35.0 > snippets directory of haskell-snippets-0.1.0-0.07b0f46 package > collides with that of package elpy-1.35.0 > snippets directory of rspec-1.11-1.66ea7cc package collides with that > of package elpy-1.35.0 > doc directory of modus-themes-1.0.2 package collides with that of > package racket-mode-0.0.2-6.5eb31a2 > data directory of emojify-1.2 package collides with that of package > unidecode-0.2-1.5502ada > test directory of systemd-mode-1.6 package collides with that of > package flycheck-haskell-0.8-2.32ddff8 > lib directory of slime-2.26.1 package collides with that of package > robe-0.8.2 > contrib directory of sly-1.0.0-7.68561f1 package collides with that > of package slime-2.26.1 > lib directory of sly-1.0.0-7.68561f1 package collides with that of > package robe-0.8.2 > doc directory of modus-vivendi-theme-1.0.2 package collides with that > of package racket-mode-0.0.2-6.5eb31a2 > doc directory of evil-1.14.0 package collides with that of package > racket-mode-0.0.2-6.5eb31a2 > data directory of all-the-icons-4.0.1 package collides with that of > package unidecode-0.2-1.5502ada > snippets directory of feature-mode-20190801-1.11ae167 package > collides with that of package elpy-1.35.0 > --8<---------------cut here---------------end--------------->8--- > > So 17 Emacs packages in Guix currently conflict, and Guix seems to be > silent about it when building a profile with them via 'guix package > -p' > (a bug?). It's a bug in those packages; not in Guix. The whole idea of Guix is, that such directories are merged. Now collisions within files in those directories are a different topic – only one can be chosen there and IIRC there should also be a way to make them errors. > > Perhaps we should ask Emacs folks how they feel about separating > > code > > and data, but bugs have already been caused here and elsewhere by > > stuffing them together. (I believe yasnippet was once already the > > culprit at some point before it got reorganized.) In the meantime, > > yes, doing so might cause extra work, but > > 1) it only affects a subset of packages, and > > 2) of this subset, we can prioritize those, that do exhibit this > > behaviour. > > The above does output does show that's it's a subset of the packages > that are affected. > > [...] > > > > We have two schemes to accommodate for our Emacs packages: > > > > > > 1. Those installed via their own mean, e.g. make install, using > > > the > > > gnu-build-system for example. These would still typically > > > install > > > their > > > packages directly under site-lisp, possibly multiple files (that > > > could > > > still collide). > > Why? Seems inconsistent, does it not? > > They can be adapted in time; until then it's easy to accommodate > both. I think we should aim for consistency here, but let's adapt them in follow-up commits. > > > 2. Those installed via the emacs-build-system. With the proposed > > > changes, those now go to site-lisp/guix/. The 'guix' sub- > > > directory > > > makes it unambiguous that anything found under is to be loaded by > > > package.el; the `package-directory-list' variable can be pointed > > > to > > > it > > > to have the Emacs' package library discover these self-contained > > > packages. > > I think you've lost me here. Basically, instead of being able to > > `(require 'my-package)` you first need to load my-package through > > package.el and then can `(require 'my-package)`? I am not sure, > > what > > the benefit of that would be, if any. > > Only if you've specified --no-site-start, which would disable > user-installed package discovery. This is the drawback of the > trade-off, not the benefit :-). It wasn't worded like one. The word unambiguous typically has a positive connotation in my mind. And package discovery should function regardless of site-start. > > > Currently if you use -Q, the Elisp libraries are in the load- > > > path, > > > but > > > not loaded (you need manually do M-x load-library before you can > > > use > > > it), or call M-x guix-emacs-autoload-packages to load their > > > autoloads. > > > For programs, this mean (require 'some-library) works, but M-x > > > some-library-autoloaded-function doesn't. > > > > > > After this change, if you use -Q the new style Emacs packages are > > > not > > > visible at all until you activate them with 'M-x load-library > > > guix-emacs' then 'M-x guix-package-initialize', or (require > > > 'guix- > > > emacs) > > > then (guix-package-initialize), programmatically. > > I do think, that there are legitimate reasons to not require a full > > initialization here, particularly for the use in batch scripts, but > > I'm > > not quite sure how much work we currently put into making sure that > > everything is available. > > That's a fair point, although I'm not concerned about the overhead of > loading compiled autoloads files. > > > > I don't see this as a problem. -Q is simply an alias for > > > "--no-init-file" "--no-site-lisp" "--no-splash" "--no-x- > > > resources" > > > "--no-site-file". > > But not "--no-load-path" "--no-nothing" ;) > > One could argue that the spirit of -Q is to give an Emacs as minimal > as > possible (that's what the Emacs manual has to say about it, and the > implicit --no-site-lisp has the meaning of "no user installed > packages"). Well then the spirit of -Q is lost. > > Being able to load the same libraries as without is vital for > > debugging > > and scripts. (Granted, some distros probably break with --no-site- > > lisp, but that's nothing to strive for imo.) > > [...] > > Thanks for having me think harder about if this is really > desirable/needed. For me the main plus is that we'd be adhering to > the > current standards used for Emacs packaging: everything is unpacked > into > a single directory owned by that package, so as long as we include > any > needed resources in the #:include argument of the emacs-build-system, > it > works as upstream intended it, with no need to patch variables or > anything. I expect this situation to worsen as Emacs packages tend > to > get more complicated, and I don't feel strongly enough about it to go > arguing about Emacs packaging standards on the Emacs mailing list :- > ). I agree, that adhering to the standards sounds nice, but this patch makes it seem as if we're still cooking our own soup. I believe we'd need to adhere to them harder than that in order for it to be an upgrade of the status quo. > On the minus side it makes the startup slightly more expensive in > terms > of pure scripting, and requires the users to be mindful that > site-start.el evaluation is needed for the user installed packages to > be > activated. > > Further thoughts? I think I've already laid that out above, but we really ought to have site-lisp/$PACKAGE-$VERSION and a working subdirs.el. If we do it like that, I don't think the multi-directory layout should cause us too many troubles. As far as the build system is concerned, we would probably need to set up an environment similar to what will be found in the end. Imagine this: - environment-variables - $PACKAGE-$VERSION/ - $PACKAGE-$VERSION-inputs/ - subdirs.el - $INPUT1/ - $INPUT2/ - ... Regards, Leo ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. 2020-12-26 10:56 ` Leo Prikler @ 2020-12-27 4:44 ` Maxim Cournoyer 2020-12-27 8:46 ` Leo Prikler 0 siblings, 1 reply; 8+ messages in thread From: Maxim Cournoyer @ 2020-12-27 4:44 UTC (permalink / raw) To: Leo Prikler; +Cc: 45316 Hi Leo, Leo Prikler <leo.prikler@student.tugraz.at> writes: [...] >> If you want to have a clearer idea of how packages from ELPA and the >> likes are installed, you can have a peek into the 'package.el' file >> shipped with Emacs (spoiler: it's basically just extracting the >> contents >> of the package archive to a single directory -- see the `package- >> unpack' >> procedure). > If we follow that to the letter, should we not install those packages > directly to site-lisp/$PACKAGE-$VERSION? Why the guix directory? I used to wonder the same, but after getting familiar with the 'package' Emacs library, it defaults (per the default value of the `package-directory-list' variable) to such a layout: directory-on-load-path/prefix/name-version/ where 'prefix' defaults to 'elpa'. It seems a good idea to have the ELPA-style packages live by themselves, separated from the 'classic' packages that are installed directly to the load path, to avoid the package.el loader getting confused or scanning entries it wouldn't know how to load anyway. That said, it's shouldn't be strictly required, as old style packages or resource directories would be lacking a *-pkg.el file and would be disregarded, and it should be possible to install the package directories directly to the load path if we wanted to. > Also, if we do go that route, I think we should install a subdirs.el > through a profile hook, that adds all these package directories to the > load path. See also '(elisp) Startup Summary'. Alternatively, we can > let subdirs.el defer to guix-emacs.el, but that'd be very cheeky. > Either way, we should definitely make -Q work. If we use a subdirs.el file, it could add the ELPA-style packages more simply if they are under the guix sub-directory (guix/*). Otherwise we'd have to filter the resource directories that potentially find their ways to the load path for old style packages. Our custom subdirs.el file could be shipped with our Emacs packages, installed in their output at share/emacs/site-lisp/subdirs.el. When a profile union would be created this subdirs.el would automatically be made available. >> Here's an experiment I've done with a profile containing the whole of >> our current emacs-build-system based packages, with this current >> change, >> that checks for collision at the top level of a package installation >> directory: >> >> --8<---------------cut here---------------end--------------->8--- >> $ ./pre-inst-env guix package -p /tmp/nnew-emacs -m emacs-packages- >> manifest.scm >> >> $ find -L /tmp/nnew-emacs/share/emacs/site-lisp/guix -maxdepth 2 >> -mindepth 2 -not -regex '.*\.elc?$' \ >> | awk -F '/' '{ if ($9 in packages) \ >> {printf("%s directory of %s package collides with that of >> package %s\n", $9, $8, packages[$9])} \ >> else {packages[$9] = $8} }' >> >> doc directory of modus-operandi-theme-1.0.2 package collides with >> that of package racket-mode-0.0.2-6.5eb31a2 >> tools directory of unidecode-0.2-1.5502ada package collides with that >> of package company-cabal-0.3.0-1.62112a7 >> snippets directory of minitest-0.8.0-1.1aadb78 package collides with >> that of package elpy-1.35.0 >> test directory of realgud-1.5.1 package collides with that of package >> flycheck-haskell-0.8-2.32ddff8 >> snippets directory of yasnippet-snippets-0.23 package collides with >> that of package elpy-1.35.0 >> snippets directory of haskell-snippets-0.1.0-0.07b0f46 package >> collides with that of package elpy-1.35.0 >> snippets directory of rspec-1.11-1.66ea7cc package collides with that >> of package elpy-1.35.0 >> doc directory of modus-themes-1.0.2 package collides with that of >> package racket-mode-0.0.2-6.5eb31a2 >> data directory of emojify-1.2 package collides with that of package >> unidecode-0.2-1.5502ada >> test directory of systemd-mode-1.6 package collides with that of >> package flycheck-haskell-0.8-2.32ddff8 >> lib directory of slime-2.26.1 package collides with that of package >> robe-0.8.2 >> contrib directory of sly-1.0.0-7.68561f1 package collides with that >> of package slime-2.26.1 >> lib directory of sly-1.0.0-7.68561f1 package collides with that of >> package robe-0.8.2 >> doc directory of modus-vivendi-theme-1.0.2 package collides with that >> of package racket-mode-0.0.2-6.5eb31a2 >> doc directory of evil-1.14.0 package collides with that of package >> racket-mode-0.0.2-6.5eb31a2 >> data directory of all-the-icons-4.0.1 package collides with that of >> package unidecode-0.2-1.5502ada >> snippets directory of feature-mode-20190801-1.11ae167 package >> collides with that of package elpy-1.35.0 >> --8<---------------cut here---------------end--------------->8--- >> >> So 17 Emacs packages in Guix currently conflict, and Guix seems to be >> silent about it when building a profile with them via 'guix package >> -p' >> (a bug?). > It's a bug in those packages; not in Guix. I used to think the same, but after reading the Elisp reference manual mentioning how Emacs packages to be installed with package.el are expected to live in their own distinct directory with their own resources; we can't really say that's it's a bug in the packages: they just weren't designed to be merged in a flat directory with other Elisp packages. Users installing these packages manually can simply add their top level directory to their load path, else use package.el to install them. > The whole idea of Guix is, that such directories are merged. Now > collisions within files in those directories are a different topic – > only one can be chosen there and IIRC there should also be a way to > make them errors. I'll investigate this separately. [...] >> > > We have two schemes to accommodate for our Emacs packages: >> > > >> > > 1. Those installed via their own mean, e.g. make install, using >> > > the >> > > gnu-build-system for example. These would still typically >> > > install >> > > their >> > > packages directly under site-lisp, possibly multiple files (that >> > > could >> > > still collide). >> > Why? Seems inconsistent, does it not? >> >> They can be adapted in time; until then it's easy to accommodate >> both. > I think we should aim for consistency here, but let's adapt them in > follow-up commits. Agreed. >> > > 2. Those installed via the emacs-build-system. With the proposed >> > > changes, those now go to site-lisp/guix/. The 'guix' sub- >> > > directory >> > > makes it unambiguous that anything found under is to be loaded by >> > > package.el; the `package-directory-list' variable can be pointed >> > > to >> > > it >> > > to have the Emacs' package library discover these self-contained >> > > packages. >> > I think you've lost me here. Basically, instead of being able to >> > `(require 'my-package)` you first need to load my-package through >> > package.el and then can `(require 'my-package)`? I am not sure, >> > what >> > the benefit of that would be, if any. >> >> Only if you've specified --no-site-start, which would disable >> user-installed package discovery. This is the drawback of the >> trade-off, not the benefit :-). > It wasn't worded like one. The word unambiguous typically has a > positive connotation in my mind. And package discovery should function > regardless of site-start. The word unambiguous was used to describe that using the sub-directory guix/ would mean anything under it would be strictly packages to be loaded with package.el and nothing else. [...] >> > Being able to load the same libraries as without is vital for >> > debugging >> > and scripts. (Granted, some distros probably break with --no-site- >> > lisp, but that's nothing to strive for imo.) >> >> [...] >> >> Thanks for having me think harder about if this is really >> desirable/needed. For me the main plus is that we'd be adhering to >> the >> current standards used for Emacs packaging: everything is unpacked >> into >> a single directory owned by that package, so as long as we include >> any >> needed resources in the #:include argument of the emacs-build-system, >> it >> works as upstream intended it, with no need to patch variables or >> anything. I expect this situation to worsen as Emacs packages tend >> to >> get more complicated, and I don't feel strongly enough about it to go >> arguing about Emacs packaging standards on the Emacs mailing list :- >> ). > I agree, that adhering to the standards sounds nice, but this patch > makes it seem as if we're still cooking our own soup. I believe we'd > need to adhere to them harder than that in order for it to be an > upgrade of the status quo. I understand this may feel a hack; because for all I know, it is ;-). I'll try improving it with the subdirs.el discussed above. [...] > I think I've already laid that out above, but we really ought to have > site-lisp/$PACKAGE-$VERSION and a working subdirs.el. If we do it like > that, I don't think the multi-directory layout should cause us too many > troubles. > > As far as the build system is concerned, we would probably need to set > up an environment similar to what will be found in the end. > Imagine this: > > - environment-variables > - $PACKAGE-$VERSION/ > - $PACKAGE-$VERSION-inputs/ > - subdirs.el > - $INPUT1/ > - $INPUT2/ In the build environment, there is no profile so each package add their individual site-lisp/ to the load path (EMACSLOADPATH). With my proposed idea to add subdirs.el to Emacs itself, there'd be nothing to do here. Thanks again for this discussion; I'll work on a revised patch. Until then, happy new year! Maxim ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. 2020-12-27 4:44 ` Maxim Cournoyer @ 2020-12-27 8:46 ` Leo Prikler 0 siblings, 0 replies; 8+ messages in thread From: Leo Prikler @ 2020-12-27 8:46 UTC (permalink / raw) To: Maxim Cournoyer; +Cc: 45316 Hi Maxim, Am Samstag, den 26.12.2020, 23:44 -0500 schrieb Maxim Cournoyer: > Hi Leo, > > Leo Prikler <leo.prikler@student.tugraz.at> writes: > > [...] > > > > If you want to have a clearer idea of how packages from ELPA and > > > the > > > likes are installed, you can have a peek into the 'package.el' > > > file > > > shipped with Emacs (spoiler: it's basically just extracting the > > > contents > > > of the package archive to a single directory -- see the `package- > > > unpack' > > > procedure). > > If we follow that to the letter, should we not install those > > packages > > directly to site-lisp/$PACKAGE-$VERSION? Why the guix directory? > > I used to wonder the same, but after getting familiar with the > 'package' > Emacs library, it defaults (per the default value of the > `package-directory-list' variable) to such a layout: > > directory-on-load-path/prefix/name-version/ > > where 'prefix' defaults to 'elpa'. It seems a good idea to have the > ELPA-style packages live by themselves, separated from the 'classic' > packages that are installed directly to the load path, to avoid the > package.el loader getting confused or scanning entries it wouldn't > know > how to load anyway. > > That said, it's shouldn't be strictly required, as old style packages > or > resource directories would be lacking a *-pkg.el file and would be > disregarded, and it should be possible to install the package > directories directly to the load path if we wanted to. I don't really know how to feel about faking elpa. Also, I don't think that 'classic' means 'not supported by package.el'. There are other reasons to use e.g. gnu-build-system over emacs-build-system and packages might ship a *-pkg.el even if they do build using a Makefile. It's also trivial to provide one if they don't and Guix has the facilities to do so. > > Also, if we do go that route, I think we should install a > > subdirs.el > > through a profile hook, that adds all these package directories to > > the > > load path. See also '(elisp) Startup Summary'. Alternatively, we > > can > > let subdirs.el defer to guix-emacs.el, but that'd be very cheeky. > > Either way, we should definitely make -Q work. > > If we use a subdirs.el file, it could add the ELPA-style packages > more > simply if they are under the guix sub-directory (guix/*). Otherwise > we'd have to filter the resource directories that potentially find > their > ways to the load path for old style packages. Our custom subdirs.el > file could be shipped with our Emacs packages, installed in their > output > at share/emacs/site-lisp/subdirs.el. When a profile union would be > created this subdirs.el would automatically be made available. IOW if we don't use guix/*, we would have to at once fix all our packages, that don't adhere to this standard. Sounds like a bit of trouble, but also like it'd improve consistency. > > > Here's an experiment I've done with a profile containing the > > > whole of > > > our current emacs-build-system based packages, with this current > > > change, > > > that checks for collision at the top level of a package > > > installation > > > directory: > > > > > > --8<---------------cut here---------------end--------------->8--- > > > $ ./pre-inst-env guix package -p /tmp/nnew-emacs -m emacs- > > > packages- > > > manifest.scm > > > > > > $ find -L /tmp/nnew-emacs/share/emacs/site-lisp/guix -maxdepth 2 > > > -mindepth 2 -not -regex '.*\.elc?$' \ > > > | awk -F '/' '{ if ($9 in packages) \ > > > {printf("%s directory of %s package collides with > > > that of > > > package %s\n", $9, $8, packages[$9])} \ > > > else {packages[$9] = $8} }' > > > > > > doc directory of modus-operandi-theme-1.0.2 package collides with > > > that of package racket-mode-0.0.2-6.5eb31a2 > > > tools directory of unidecode-0.2-1.5502ada package collides with > > > that > > > of package company-cabal-0.3.0-1.62112a7 > > > snippets directory of minitest-0.8.0-1.1aadb78 package collides > > > with > > > that of package elpy-1.35.0 > > > test directory of realgud-1.5.1 package collides with that of > > > package > > > flycheck-haskell-0.8-2.32ddff8 > > > snippets directory of yasnippet-snippets-0.23 package collides > > > with > > > that of package elpy-1.35.0 > > > snippets directory of haskell-snippets-0.1.0-0.07b0f46 package > > > collides with that of package elpy-1.35.0 > > > snippets directory of rspec-1.11-1.66ea7cc package collides with > > > that > > > of package elpy-1.35.0 > > > doc directory of modus-themes-1.0.2 package collides with that of > > > package racket-mode-0.0.2-6.5eb31a2 > > > data directory of emojify-1.2 package collides with that of > > > package > > > unidecode-0.2-1.5502ada > > > test directory of systemd-mode-1.6 package collides with that of > > > package flycheck-haskell-0.8-2.32ddff8 > > > lib directory of slime-2.26.1 package collides with that of > > > package > > > robe-0.8.2 > > > contrib directory of sly-1.0.0-7.68561f1 package collides with > > > that > > > of package slime-2.26.1 > > > lib directory of sly-1.0.0-7.68561f1 package collides with that > > > of > > > package robe-0.8.2 > > > doc directory of modus-vivendi-theme-1.0.2 package collides with > > > that > > > of package racket-mode-0.0.2-6.5eb31a2 > > > doc directory of evil-1.14.0 package collides with that of > > > package > > > racket-mode-0.0.2-6.5eb31a2 > > > data directory of all-the-icons-4.0.1 package collides with that > > > of > > > package unidecode-0.2-1.5502ada > > > snippets directory of feature-mode-20190801-1.11ae167 package > > > collides with that of package elpy-1.35.0 > > > --8<---------------cut here---------------end--------------->8--- > > > > > > So 17 Emacs packages in Guix currently conflict, and Guix seems > > > to be > > > silent about it when building a profile with them via 'guix > > > package > > > -p' > > > (a bug?). > > It's a bug in those packages; not in Guix. > > I used to think the same, but after reading the Elisp reference > manual > mentioning how Emacs packages to be installed with package.el are > expected to live in their own distinct directory with their own > resources; we can't really say that's it's a bug in the packages: > they > just weren't designed to be merged in a flat directory with other > Elisp > packages. Users installing these packages manually can simply add > their > top level directory to their load path, else use package.el to > install > them. Idk, feels like a mixed bag to me. Especially yasnippet will actually be broken by going to this new layout. The user will be expected to have $GUIX_PROFILE/share/emacs/site-lisp/yasnippet-snippets- $VERSION/snippets in their yas-snippets-dir. My really old setup assumes, they'd be stored in $GUIX_PROFILE/share/emacs/yasnippet- snippets/ instead, because I forgot it moved to site-lisp/snippets. Now what do you think happens on version upgrades? I think, this is another argument to separate code and data even if we do go the route of using subdirectories to store code. > > I think I've already laid that out above, but we really ought to > > have > > site-lisp/$PACKAGE-$VERSION and a working subdirs.el. If we do it > > like > > that, I don't think the multi-directory layout should cause us too > > many > > troubles. > > > > As far as the build system is concerned, we would probably need to > > set > > up an environment similar to what will be found in the end. > > Imagine this: > > > > - environment-variables > > - $PACKAGE-$VERSION/ > > - $PACKAGE-$VERSION-inputs/ > > - subdirs.el > > - $INPUT1/ > > - $INPUT2/ > > In the build environment, there is no profile so each package add > their > individual site-lisp/ to the load path (EMACSLOADPATH). With my > proposed idea to add subdirs.el to Emacs itself, there'd be nothing > to > do here. Yes there would. Exactly because there is no union-build, those packages would not not have subdirs.el, so it's dubious as to whether they'd be properly expanded. > Thanks again for this discussion; I'll work on a revised > patch. Until > then, happy new year! Happy new year to you too and happy hacking 🙂 Leo ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix. @ 2020-12-18 22:00 Maxim Cournoyer 0 siblings, 0 replies; 8+ messages in thread From: Maxim Cournoyer @ 2020-12-18 22:00 UTC (permalink / raw) To: 45316 [-- Attachment #1: Type: text/plain, Size: 2631 bytes --] Hello Guix! tl;dr: The Emacs build system and site-start.el loader are modified so that Emacs packages are installed in their own distinct installation directory. The Emacs packages built with the Emacs built system used to be installed in a sub-directory under the share/emacs/guix.d/ directory, but this was changed in commit 65a7dd2950ca13a8b942b2836260a2192351b271 shortly after having accommodated the site-start.el machinery to enable loading packages from any profile (via the EMACSLOADPATH search path specification). While this change allowed to expose simply and directly the packages found in EMACSLOADPATH, it does introduce the risk of file name collisions when multiple Emacs packages are joined in the same profile, especially with Emacs packages increasing in complexity (e.g., using more than a single .el file!) and expecting to have both their sources and resources extracted under their own nested directory rather than as a flat collection (ELPA, MELPA). One recent example I stumbled on was attempting to use the emacs-yasnippet-snippets package along with emacs-elpy; both wanted to install a 'snippets' directory to share/emacs/site-lisp/snippets, collided and resulted in problems that prove difficult to understand. This is what motivated this patch series, where the site-start.el auxiliary code used for package discovery is extended to support packages installed in their own directory under a 'share/emacs/guix' installation prefix, via Emacs' own package library! The emacs-build-system is updated for this new installation prefix, as well as existing packages and documentation. Parting with a directly usable EMACSLOADPATH means that site-start.el *must* run for packages to appear in the load-path; that means for running a test suite, the -Q or --quick Emacs options cannot be used, since it implies --no-site-file. Benefits of using this approach: + Avoid inter-package file name collisions. + Better integration with user installed packages via M-x package-install. The Guix-installed packages are listed in M-x package-list as 'external'. Cons include: - Slightly more complex loader (although much of it is offloaded to package.el), thus slightly slower (see the comparison below). - Requires to ensure every package's test suite doesn't make use of -Q. In my opinion the benefits outweighs the cons by a comfortable margin, especially with the boring work of adapting the package collection already done. To test the performance of the new approach, the following manifest file was used to test the rebuild of the ~900 Emacs packages making use of the Emacs build system: [-- Attachment #2: emacs-packages-manifest.scm --] [-- Type: text/plain, Size: 806 bytes --] (use-modules (gnu packages) (guix build-system) (guix packages) (srfi srfi-1)) (define %broken-emacs-packages (map specification->package '("emacs-picpocket" ;tests fail "emacs-twittering-mode" ;build fails ;; Broken only on current master, without new changes. "emacs-md4rd" "emacs-el-patch" "emacs-flymake-shellcheck" ))) (define %emacs-packages (fold-packages (lambda (package lst) (if (eq? (build-system-name (package-build-system package)) 'emacs) (cons package lst) lst)) '())) (packages->manifest (lset-difference eqv? %emacs-packages %broken-emacs-packages)) [-- Attachment #3: Type: text/plain, Size: 2772 bytes --] A simple benchmark testing the performance of the activation of the hundreds of Emacs packages was then run using: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix environment --pure -m emacs-packages-manifest.scm \ --ad-hoc emacs [env]$ /run/setuid-programs/sudo /bin/sh -c 'echo 3 > /proc/sys/vm/drop_caches' [env]$ emacs --batch --no-site-file \ --eval="(progn (require 'guix-emacs) \ (require 'benchmark) \ (message \"(total gc-count gc-time) = %s\" \ (benchmark-run 1 (guix-emacs-autoload-packages))))" --8<---------------cut here---------------end--------------->8--- On the master branch: --8<---------------cut here---------------start------------->8--- [...] Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f-profile/share/emacs/site-lisp/zotxt-autoloads... Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f-profile/share/emacs/site-lisp/zoutline-autoloads... Loading /gnu/store/qajc70c7nqycs1301ram8s3x7k9ibg5f-profile/share/emacs/site-lisp/ztree-autoloads... (total gc-count gc-time) = (25.242400751 13 0.189669369) --8<---------------cut here---------------end--------------->8--- Or about 0.65 s on a warm cache. On a branch with these changes: --8<---------------cut here---------------start------------->8--- Error loading autoloads: (file-missing Cannot open load file No such file or directory kotl/kotl-autoloads) Error loading autoloads: (file-missing Cannot open load file No such file or directory helm-easymenu) Error loading autoloads: (file-missing Cannot open load file No such file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr-profile/share/emacs/site-lisp/guix/flycheck-cpplint-0.1-1.1d8a090/flycheck-cpplint-autoloads) Error loading autoloads: (file-missing Cannot open load file No such file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr-profile/share/emacs/site-lisp/guix/evil-anzu-0.03/evil-anzu-autoloads) Error loading autoloads: (file-missing Cannot open load file No such file or directory /gnu/store/ryh0rasi9frm98dkd3kbck6hya6hn2qr-profile/share/emacs/site-lisp/guix/erc-image-0-3.82fb387/erc-image-autoloads) ad-handle-definition: `ido-completing-read' got redefined Error loading autoloads: (file-missing Cannot open load file No such file or directory tex-site) (total gc-count gc-time) = (26.175704339 47 0.783184412) --8<---------------cut here---------------end--------------->8--- Or about 3 seconds on a warm cache. There a 6 errors that would need to be looked into, but I these look like actual packaging problems rather than new issues. The previously used way to load the autoloads, '(load f 'noerror)' would have masked them. Thanks, Maxim ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-12-27 8:47 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <87ft3ysen7.fsf@gmail.com> 2020-12-22 8:51 ` bug#45316: [PATCH]: Re-introduce Emacs packages specific installation prefix Leo Prikler 2020-12-22 18:09 ` Maxim Cournoyer 2020-12-22 19:10 ` Leo Prikler 2020-12-26 5:01 ` Maxim Cournoyer 2020-12-26 10:56 ` Leo Prikler 2020-12-27 4:44 ` Maxim Cournoyer 2020-12-27 8:46 ` Leo Prikler 2020-12-18 22:00 Maxim Cournoyer
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/guix.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).