On 28 Nov 2024, at 19:10, Joseph Mingrone wrote:
Hello Robert,
Your description of what we are trying to accomplish is accurate. In short, we aim to:
- Use existing binaries when they are installed as OS packages. - Allow things to work as expected when those binaries are not installed, i.e., write binaries to the user's cache.
Your suggestion to write configuration files along with the packages to control output translation seems like a good approach. That is, when a user installs the cl-alexandria-sbcl package, we could write ${PREFIX}/etc/common-lisp/asdf-output-translations.conf.d/10-cl-alexandria-sbcl.conf. Without that package installed, I believe the default behaviour - writing to the user's cache - works. I'm working on implementing this approach but have encountered hurdles:
- Custom Configuration Directory
Our packages should only write under ${PREIX} (typically /usr/local/). Is it possible to tell ASDF to read from /usr/local/etc/common-lisp/asdf-output-translations.conf.d instead of /etc/common-lisp/asdf-output-translations.conf.d? Ideally, we could do this from our asdf-init.lisp. I notice that #:system-output-translations-pathname is exported. Could it be used for this purpose?
That's a function binding, so no, it cannot. I think you *could* change the function definition of `system-config-pathnames` to change *all* ASDF configuration locations from `/etc/` to `/usr/local/etc/`. I do not know enough about how FreeBSD works to know if this is OK for your use case. I'm afraid that I don't understand how XDG works, either: that was Faré's addition.
The API does not look to me to be able to set a special configuration directory for only a specific kind of configuration (such as only for output translations and not for source-finding).
- Configuration Error
I manually created a test configuration file at /etc/common-lisp/asdf-output-translations.conf.d/10-asdf-sbcl.conf, with this DSL:
% cat /etc/common-lisp/asdf-output-translations.conf.d/10-asdf-sbcl.conf (:output-translations :inherit-configuration ("/usr/local/lib/common-lisp/asdf/**/" "/usr/local/lib/common-lisp/asdf/sbclfasl/**/"))
However, ASDF reports an error:
% sbcl This is SBCL 2.4.10, an implementation of ANSI Common Lisp. More information about SBCL is available at http://www.sbcl.org/ .
SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. ;;; loading #P"/usr/local/lib/common-lisp/asdf/sbclfasl/build/asdf.fasl"
- (asdf:load-system :foo)
debugger invoked on a ASDF/OUTPUT-TRANSLATIONS:INVALID-OUTPUT-TRANSLATION in thread #<THREAD tid=103125 "main thread" RUNNING {1103F50093}>: Invalid asdf output-translation (:OUTPUT-TRANSLATIONS :INHERIT-CONFIGURATION ("/usr/local/lib/common-lisp/asdf/**/" "/usr/local/lib/common-lisp/asdf/sbclfasl/**/")) in #P"/etc/common-lisp/asdf-output-translations.conf.d/10-asdf-sbcl.conf" (will be skipped)
Do you know what's wrong with this DSL?
I do not. Do you have a backtrace? I suspect the problem is the use of "**", but I'm not sure. The manual states that
``` DIRECTORY-DESIGNATOR := NIL | ; As source: skip this entry. As destination: same as source T | ; as source matches anything, as destination ; maps pathname to itself. ABSOLUTE-COMPONENT-DESIGNATOR ; same as in the source-registry language ```
And going to the page for the source registry DSL:
``` ABSOLUTE-COMPONENT-DESIGNATOR := (ABSOLUTE-COMPONENT-DESIGNATOR RELATIVE-COMPONENT-DESIGNATOR ...) | STRING | ;; namestring (better be absolute or bust, directory assumed where ;; applicable). In output-translations, directory is assumed and ;; **/*.*.* added if it's last. On MCL, a MacOSX-style POSIX ;; namestring (for MacOS9 style, use #p"..."); Note that none of the ;; above applies to strings used in *central-registry*, which ;; doesn't use this DSL: they are processed as normal namestrings. ;; however, you can compute what you put in the *central-registry* ;; based on the results of say ;; (asdf::resolve-location "/Users/fare/cl/cl-foo/") PATHNAME | ;; pathname (better be an absolute path, or bust) ;; In output-translations, unless followed by relative components, ;; it better have appropriate wildcards, as in **/*.*.* :HOME | ; designates the user-homedir-pathname ~/ :USER-CACHE | ; designates the default location for the user cache :HERE | ;; designates the location of the configuration file ;; (or *default-pathname-defaults*, if invoked interactively) :ROOT ;; magic, for output-translations source only: paths that are relative ;; to the root of the source host and device ```
Possibly you need a trailing `*.*.*`?
Also, as I look at this, do you want your new output translations to shadow old ones? In that case you should put `:inherit-configuration` last instead of first.
- Distinguishing Lisp Implementations
This approach will only work if we can distinguish the running Lisp implementation. The manual mentions, "You may use #+features to customize the configuration file." Can we use something like #+sbcl in the .conf files to conditionally set up the output translations for SBCL?
Honestly, I don't know. But when I look at the source for `parse-output-translations-string`, it looks like it's a string parser, and does not use `read`, in which case reader macros would not work.
But TBH I cannot see how the
How about starting up a lisp with `process-output-translations` and `parse-output-translations-string` traced and posting the results here. Note that this is one of the things I don't like about the way that ASDF uses configuration files: it's hard to load ASDF and configure it for debugging *before* it sees its configuration files. You could actually edit the ASDF source to inject the tracing (or `format` statements), of course. (I have been meaning to add some switch to startup so that one can debug its initialization, but have not had the time.)
Thank you for your time and insight.
Kind regards, Joe