aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2013-04-28 23:05:57 +0200
committerLudovic Courtès <ludo@gnu.org>2013-04-28 23:19:03 +0200
commit5924080dccae93fa725bf77df5f7a1e9a8756101 (patch)
treedd3526262b122787d33082f69829e314de9bd485
parent2bcfb9e065ac6abb6abf7ac9a263ba3c4d70124f (diff)
downloadguix-5924080dccae93fa725bf77df5f7a1e9a8756101.tar.gz
guix-5924080dccae93fa725bf77df5f7a1e9a8756101.zip
guix package: Add `--search-paths' & co.
* guix/scripts/package.scm (search-path-environment-variables, display-search-paths): New procedures. (show-help, %options): Add `--search-paths'. (guix-package)[process-actions]: Call `display-search-paths' once the profile is ready. [process-query]: Honor `search-paths'.
-rw-r--r--doc/guix.texi22
-rw-r--r--guix/scripts/package.scm66
-rw-r--r--tests/guix-package.sh8
3 files changed, 94 insertions, 2 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index e23eab0f81..d571de95a0 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -517,8 +517,13 @@ Thus, when installing MPC, the MPFR and GMP libraries also get installed
in the profile; removing MPC also removes MPFR and GMP---unless they had
also been explicitly installed independently.
+Besides, packages sometime rely on the definition of environment
+variables for their search paths (see explanation of
+@code{--search-paths} below.) Any missing or possibly incorrect
+environment variable definitions are reported here.
+
@c XXX: keep me up-to-date
-Besides, when installing a GNU package, the tool reports the
+Finally, when installing a GNU package, the tool reports the
availability of a newer upstream version. In the future, it may provide
the option of installing directly from the upstream version, even if
that version is not yet in the distribution.
@@ -566,6 +571,21 @@ Installing, removing, or upgrading packages from a generation that has
been rolled back to overwrites previous future generations. Thus, the
history of a profile's generations is always linear.
+@item --search-paths
+@cindex search paths
+Report environment variable definitions, in Bash syntax, that may be
+needed in order to use the set of installed packages. These environment
+variables are used to specify @dfn{search paths} for files used by some
+of the installed packages.
+
+For example, GCC needs the @code{CPATH} and @code{LIBRARY_PATH}
+environment variables to be defined so it can look for headers and
+libraries in the user's profile (@pxref{Environment Variables,,, gcc,
+Using the GNU Compiler Collection (GCC)}). If GCC and, say, the C
+library are installed in the profile, then @code{--search-paths} will
+suggest setting these variables to @code{@var{profile}/include} and
+@code{@var{profile}/lib}, respectively.
+
@item --profile=@var{profile}
@itemx -p @var{profile}
Use @var{profile} instead of the user's default profile.
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index c5656efc14..560b673618 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -330,6 +330,53 @@ but ~a is available upstream~%")
((getaddrinfo-error ftp-error) #f)
(else (apply throw key args))))))
+(define* (search-path-environment-variables packages profile
+ #:optional (getenv getenv))
+ "Return environment variable definitions that may be needed for the use of
+PACKAGES in PROFILE. Use GETENV to determine the current settings and report
+only settings not already effective."
+
+ ;; The search path info is not stored in the manifest. Thus, we infer the
+ ;; search paths from same-named packages found in the distro.
+
+ (define package-in-manifest->package
+ (match-lambda
+ ((name version _ ...)
+ (match (append (find-packages-by-name name version)
+ (find-packages-by-name name))
+ ((p _ ...) p)
+ (_ #f)))))
+
+ (define search-path-definition
+ (match-lambda
+ (($ <search-path-specification> variable directories separator)
+ (let ((values (or (and=> (getenv variable)
+ (cut string-tokenize* <> separator))
+ '()))
+ (directories (filter file-exists?
+ (map (cut string-append profile
+ "/" <>)
+ directories))))
+ (if (every (cut member <> values) directories)
+ #f
+ (format #f "export ~a=\"~a\""
+ variable
+ (string-join directories separator)))))))
+
+ (let* ((packages (filter-map package-in-manifest->package packages))
+ (search-paths (delete-duplicates
+ (append-map package-native-search-paths
+ packages))))
+ (filter-map search-path-definition search-paths)))
+
+(define (display-search-paths packages profile)
+ "Display the search path environment variables that may need to be set for
+PACKAGES, in the context of PROFILE."
+ (let ((settings (search-path-environment-variables packages profile)))
+ (unless (null? settings)
+ (format #t (_ "The following environment variable definitions may be needed:~%"))
+ (format #t "~{ ~a~%~}" settings))))
+
;;;
;;; Command-line options.
@@ -354,6 +401,8 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
-u, --upgrade[=REGEXP] upgrade all the installed packages matching REGEXP"))
(display (_ "
--roll-back roll back to the previous generation"))
+ (display (_ "
+ --search-paths display needed environment variable definitions"))
(newline)
(display (_ "
-p, --profile=PROFILE use PROFILE instead of the user's default profile"))
@@ -408,6 +457,9 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
(option '("roll-back") #f #f
(lambda (opt name arg result)
(alist-cons 'roll-back? #t result)))
+ (option '("search-paths") #f #f
+ (lambda (opt name arg result)
+ (cons `(query search-paths) result)))
(option '(#\p "profile") #t #f
(lambda (opt name arg result)
(alist-cons 'profile arg
@@ -728,7 +780,9 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
(build-derivations (%store) (list prof-drv)))
(begin
(switch-symlinks name prof)
- (switch-symlinks profile name))))))))))
+ (switch-symlinks profile name)
+ (display-search-paths packages
+ profile))))))))))
(define (process-query opts)
;; Process any query specified by OPTS. Return #t when a query was
@@ -776,6 +830,16 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
(for-each (cute package->recutils <> (current-output-port))
(find-packages-by-description regexp))
#t))
+
+ (('search-paths)
+ (let* ((manifest (profile-manifest profile))
+ (packages (manifest-packages manifest))
+ (settings (search-path-environment-variables packages
+ profile
+ (const #f))))
+ (format #t "~{~a~%~}" settings)
+ #t))
+
(_ #f))))
(let ((opts (parse-options)))
diff --git a/tests/guix-package.sh b/tests/guix-package.sh
index 7b101aa501..5a514a0dc0 100644
--- a/tests/guix-package.sh
+++ b/tests/guix-package.sh
@@ -47,6 +47,10 @@ test -L "$profile" && test -L "$profile-1-link"
! test -f "$profile-2-link"
test -f "$profile/bin/guile"
+# No search path env. var. here.
+guix package --search-paths -p "$profile"
+test "`guix package --search-paths -p "$profile" | wc -l`" = 0
+
# Check whether we have network access.
if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
then
@@ -119,6 +123,10 @@ then
rm "$profile-1-link"
guix package --bootstrap -p "$profile" --roll-back
test "`readlink_base "$profile"`" = "$profile-0-link"
+
+ # Make sure LIBRARY_PATH gets listed by `--search-paths'.
+ guix package --bootstrap -p "$profile" -i guile-bootstrap -i gcc-bootstrap
+ guix package --search-paths -p "$profile" | grep LIBRARY_PATH
fi
# Make sure the `:' syntax works.