From 20fea816b93f31f6b079aa752c0a2ec681649cd0 Mon Sep 17 00:00:00 2001
I observed the problem when tried to run 'guix refresh' from local git checkout:
$ strace -f ./pre-inst-env guix refresh -u re2c |& fgrep re2c.scm
[pid 3014757] openat(AT_FDCWD, "/usr/share/guile/site/3.0/gnu/packages/re2c.scm.qilB0R",
O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
Attempt to /usr/share happens because local directory override has too low priority:
$ ./pre-inst-env guile -c '(display (search-path %load-path "gnu/packages/re2c.scm")) (newline) (display %load-path) (newline)'
/usr/share/guile/site/3.0/gnu/packages/re2c.scm
/usr/share/guile/site/3.0 \
/home/slyfox/dev/git/guix \
/home/slyfox/dev/git/guix)
It happens because ./guile ignores GUILE_LOAD_PATH / GUILE_LOAD_COMPILED_PATH
The change drops 'GUILE_LOAD_PATH' environment variable handling. Instead
we bake the constant with into 'guile' binary by distinguishing 'store/guile'
and 'inplace/guile'. And we bake '%guix-is-inplace' in 'inplace/guix' and
in '/usr/bin/guix'. While at it also move 'guix-daemon' to
'inplace/guix-daemon' to make it clear it is used locally by tests.
* .gitignore: Ignore new 'store' and 'inplace' directories, ignore
two new 'guile-launcher' object files.
* Makefile.am: Move 'scripts/guix' to 'inplace/guix'. Move './guile'
to 'inplace/guile'. Add 'store/guile' that differes from 'inplace/guile'
by absence of '-DGUIX_INPLACE_GUILE=1' define.
* build-aux/pre-inst-env.in: Don't add '$abs_top_builddir' to the
'PATH'. Add only '$abs_top_builddir/inplace' to the 'PATH'. Drop
'GUIX_UNINSTALLED' environment variable.
* build-aux/test-env.in: Update to new 'inplace/guix-daemon' location.
* doc/local.mk: Update to new 'inplace/guix-daemon' location.
* gnu/packages/aux-files/guile-launcher.c (main): Use compile-time
* nix/local.mk: Move 'guix-daemon' to 'inplace/guix-daemon'.
'GUIX_INPLACE_GUILE' define to distinguish 'guile' binary used inplace
* scripts/guix.in: Drop 'GUIX_UNINSTALLED' environment variable
handling in favour of new '%guix-is-inplace' constant.
Makefile.am | 29 +++++++++++++++++--------
build-aux/pre-inst-env.in | 12 ++++------
build-aux/test-env.in | 4 ++--
gnu/packages/aux-files/guile-launcher.c | 26 ++++++++++++++++------
nix/local.mk | 14 ++++++------
scripts/guix.in | 6 +++--
8 files changed, 61 insertions(+), 37 deletions(-)
Toggle diff (261 lines)
diff --git a/.gitignore b/.gitignore
index 88fe24586d..5a7dfa1f31 100644
-/gnu/packages/aux-files/guile-guile-launcher.o
+/gnu/packages/aux-files/inplace_guile-guile-launcher.o
+/gnu/packages/aux-files/store_guile-guile-launcher.o
diff --git a/Makefile.am b/Makefile.am
index 5542aa1c56..0666c7b7c2 100644
MSGMERGE_UPDATE = @MSGMERGE@ --update
-bin_SCRIPTS = scripts/guix
+bin_SCRIPTS = inplace/guix
# Handle substitution of fully-expanded Autoconf variables.
-e 's,[@]GUILE[@],$(GUILE),g' \
-e 's,[@]guilemoduledir[@],$(guilemoduledir),g' \
-e 's,[@]guileobjectdir[@],$(guileobjectdir),g' \
+ -e 's,[@]guix_is_inplace[@],t,g' \
-e 's,[@]abs_top_builddir[@],$(abs_top_builddir),g' \
-e 's,[@]localedir[@],$(localedir),g'
-scripts/guix: scripts/guix.in Makefile
+inplace/guix: scripts/guix.in Makefile
$(AM_V_at)$(MKDIR_P) "$(@D)"
- $(AM_V_GEN)$(do_subst) < "$(srcdir)/$@.in" > "$@-t"
+ $(AM_V_GEN)$(do_subst) < "$(srcdir)/$<" > "$@-t"
$(AM_V_at)chmod a+x,a-w "$@-t" && mv -f "$@-t" "$@"
# This is our variant of the 'guile' executable, one that doesn't complain
-pkglibexec_PROGRAMS = guile
-guile_SOURCES = gnu/packages/aux-files/guile-launcher.c
-guile_LDADD = $(GUILE_LIBS)
-guile_CFLAGS = $(GUILE_CFLAGS)
+# about locales. Intended to be executed from store.
+pkglibexec_PROGRAMS = store/guile
+store_guile_SOURCES = gnu/packages/aux-files/guile-launcher.c
+store_guile_LDADD = $(GUILE_LIBS)
+store_guile_CFLAGS = $(GUILE_CFLAGS)
+# This is similar to pkglibexec_PROGRAMS with an exception of honoring local
+# - GUILE_LOAD_PATH / GUILE_LOAD_COMPILED_PATH to allow './pre-inst-env guix refresh'
+# and friends access to inplace sources: http://issues.guix.gnu.org/48434.
+noinst_PROGRAMS = inplace/guile
+inplace_guile_SOURCES = gnu/packages/aux-files/guile-launcher.c
+inplace_guile_LDADD = $(GUILE_LIBS)
+inplace_guile_CFLAGS = $(GUILE_CFLAGS) -DGUIX_INPLACE_GUILE=1
# Have the 'guix' command refer to our 'guile'.
$(SED) -i "$(DESTDIR)$(bindir)/guix" \
- -e 's,^#![[:graph:]]\+,#!$(pkglibexecdir)/guile,g'
+ -e 's,^#![[:graph:]]\+,#!$(pkglibexecdir)/guile,g' \
+ -e 's,define %guix-is-inplace #t,define %guix-is-inplace #f,g'
nodist_noinst_SCRIPTS = \
diff --git a/build-aux/pre-inst-env.in b/build-aux/pre-inst-env.in
index cd90a06cbc..d4e03a92fb 100644
--- a/build-aux/pre-inst-env.in
+++ b/build-aux/pre-inst-env.in
@@ -39,17 +39,13 @@ export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH
# Define $PATH so that `guix' and friends are easily found.
-PATH="$abs_top_builddir/scripts:$abs_top_builddir:$PATH"
+PATH="$abs_top_builddir/inplace:$PATH"
# The daemon invokes 'guix'; tell it which one to use.
-GUIX="$abs_top_builddir/scripts/guix"
+# Use inpalce `guix' to honor local GUILE_LOAD_PATH / GUILE_LOAD_COMPILED_PATH:
+# http://issues.guix.gnu.org/48434
+GUIX="$abs_top_builddir/inplace/guix"
-# Define $GUIX_UNINSTALLED to prevent `guix' from
-# prepending @guilemoduledir@ to the Guile load paths.
diff --git a/build-aux/test-env.in b/build-aux/test-env.in
index 7efc43206c..b41662393d 100644
--- a/build-aux/test-env.in
+++ b/build-aux/test-env.in
@@ -39,7 +39,7 @@ case "$1" in
-if [ -x "@abs_top_builddir@/guix-daemon" ]
+if [ -x "@abs_top_builddir@/inplace/guix-daemon" ]
NIX_STORE_DIR="@GUIX_TEST_ROOT@/store"
# Launch the daemon without chroot support because is may be
# unavailable, for instance if we're not running as root.
"@abs_top_builddir@/pre-inst-env" \
- "@abs_top_builddir@/guix-daemon" --disable-chroot \
+ "@abs_top_builddir@/inplace/guix-daemon" --disable-chroot \
--substitute-urls="$GUIX_BINARY_SUBSTITUTE_URL" &
diff --git a/doc/local.mk b/doc/local.mk
index 8340b75a87..6068a2cd2b 100644
@@ -251,7 +251,7 @@ if !CROSS_COMPILING
dist_man1_MANS += $(srcdir)/%D%/guix-daemon.1
-$(srcdir)/%D%/guix-daemon.1: guix-daemon$(EXEEXT)
+$(srcdir)/%D%/guix-daemon.1: inplace/guix-daemon$(EXEEXT)
-$(AM_V_HELP2MAN)$(gen_man) --output="$@" `basename "$@" .1`
diff --git a/gnu/packages/aux-files/guile-launcher.c b/gnu/packages/aux-files/guile-launcher.c
index 47ba069de1..3dbd738573 100644
--- a/gnu/packages/aux-files/guile-launcher.c
+++ b/gnu/packages/aux-files/guile-launcher.c
@@ -66,6 +66,12 @@ inner_main (void *unused, int argc, char **argv)
main (int argc, char **argv)
+#if defined(GUIX_INPLACE_GUILE)
+ int run_guile_from_store = 0;
+ int run_guile_from_store = 1;
/* Try to install the current locale; remain silent if it fails. */
if (setlocale (LC_ALL, "") == NULL)
/* The 'guix pull'-provided 'guix' includes at least en_US.utf8 so use
@@ -73,14 +79,20 @@ main (int argc, char **argv)
which is always preferable over the C locale. */
setlocale (LC_ALL, "en_US.utf8");
- str = getenv ("GUILE_LOAD_PATH");
- load_path = str != NULL ? strdup (str) : NULL;
- str = getenv ("GUILE_LOAD_COMPILED_PATH");
- load_compiled_path = str ? strdup (str) : NULL;
- unsetenv ("GUILE_LOAD_PATH");
- unsetenv ("GUILE_LOAD_COMPILED_PATH");
+ /* Allow ./pre-inst-env to inject local paths. That way local sources
+ are preferred for most operations. */
+ if (run_guile_from_store)
+ str = getenv ("GUILE_LOAD_PATH");
+ load_path = str != NULL ? strdup (str) : NULL;
+ str = getenv ("GUILE_LOAD_COMPILED_PATH");
+ load_compiled_path = str ? strdup (str) : NULL;
+ unsetenv ("GUILE_LOAD_PATH");
+ unsetenv ("GUILE_LOAD_COMPILED_PATH");
/* XXX: Do not let GMP allocate via libgc as this can lead to memory
corruption in GnuTLS/Nettle since Nettle also uses GMP:
diff --git a/nix/local.mk b/nix/local.mk
index 7c438ea78c..1d7705b1e5 100644
@@ -111,33 +111,33 @@ libstore_a_CPPFLAGS = \
libstore_a_CXXFLAGS = $(AM_CXXFLAGS) \
$(SQLITE3_CFLAGS) $(LIBGCRYPT_CFLAGS)
-bin_PROGRAMS = guix-daemon
+bin_PROGRAMS = inplace/guix-daemon
+inplace_guix_daemon_SOURCES = \
%D%/nix-daemon/nix-daemon.cc \
%D%/nix-daemon/guix-daemon.cc
-guix_daemon_CPPFLAGS = \
+inplace_guix_daemon_CPPFLAGS = \
-DLOCALEDIR=\"$(localedir)\" \
-I$(top_srcdir)/%D%/libstore
+inplace_guix_daemon_LDADD = \
libstore.a libutil.a libformat.a -lz \
$(SQLITE3_LIBS) $(LIBGCRYPT_LIBS)
+inplace_guix_daemon_headers = \
-guix_daemon_LDADD += -lbz2
+inplace_guix_daemon_LDADD += -lbz2
$(libformat_headers) $(libutil_headers) $(libstore_headers) \
+ $(inplace_guix_daemon_headers)
%D%/libstore/schema.sql.hh: guix/store/schema.sql
$(AM_V_GEN)$(GUILE) --no-auto-compile -c \
diff --git a/scripts/guix.in b/scripts/guix.in
index e0194d6ea2..a9fc29baa4 100644
-#!@abs_top_builddir@/guile \
+#!@abs_top_builddir@/inplace/guile \
--no-auto-compile -e main -s
;;; GNU Guix --- Functional package management for GNU
(push! "@guilemoduledir@" %load-path)
(push! "@guileobjectdir@" %load-compiled-path))
+(define %guix-is-inplace #@guix_is_inplace@)
(define* (main #:optional (args (command-line)))
- (unless (getenv "GUIX_UNINSTALLED")
+ (unless %guix-is-inplace
(let ((guix-main (module-ref (resolve-interface '(guix ui))