Hi,
On 11/8/21 15:19, Foo Chuan Wei wrote:
* Part of the build process relies on programs written in Standard ML.
* The part written in Standard ML uses a function from the SML Basis
Library: `OS.Process.system`.
* `OS.Process.system` will always use /bin/sh. This is hardcoded. I
cannot change it. If I change it, the behavior of `OS.Process.system`
would probably be wrong in the final product (the sml compiler).
A similar issue came up for Racket, which has a family of functions like
`process` and `system` that execute commands using `sh`.[0]
Maybe this kind of function is common enough in programming language
implementations that it should be documented in the Guix manual's
packaging guidelines? For example, even libc has a `system` function
specified to use "/bin/sh" (I haven't looked at how Guix handles it).
Part of the issue with Guix is that, even if you somehow arranged for
"/bin/sh" to exist in the build environment, Guix users will likely also
want to run the SML/NJ compiler and compiled SML/NJ programs in
environments where "/bin/sh" doesn't exist. For Racket, thanks to some
discussion with Jack Hill,[1] I added a patch that uses a Guix-specific
C preprocessor macro to intercept attempts to execute "/bin/sh" in
librktio (Racket's cross-platform IO library) and substitute the store
path to Guix's `bash-minimal`. The current patch is at [2].
(A subtlety I'd forgotten is that, in addition to functions like
`system` that are specified to use `sh`, Racket's build process was also
calling functions like `system*`, which are more like `execve`, with
"/bin/sh" as an argument. Since that approach is recommended for
portability and robustness, the patch intercepts those attempts, too.)
The approach was especially defensible for Racket because the Racket
Reference merely specifies that the functions will use some `sh`, not
that it will be any particular `sh` or will be located at any particular
path. From a quick look at the SML Basis Library reference[3], it
specifies that `OS.Process.system` uses "the operating system's default
shell", though it does go on to say that, "on Unix systems" (but
apparently not Mac OS?), the default shell is '/bin/sh'". Since Guix
doesn't really have a "default shell" in general, I think using the an
explicit package input might make sense for SML/NJ's
`OS.Process.system`, too.
[0]:
https://docs.racket-lang.org/reference/subprocess.html#%28def._%28%28lib._racket%2Fsystem..rkt%29._process%29%29
[1]: https://issues.guix.gnu.org/47180
[2]:
https://git.savannah.gnu.org/gitweb/?p=guix.git;a=blob;f=gnu/packages/patches/racket-minimal-sh-via-rktio.patch;h=6bc2ee8331f046959fd493f8e1604e682ddc4a0d;hb=HEAD
[3]:
https://smlfamily.github.io/Basis/os-process.html#SIG:OS_PROCESS.system:VAL