gremlin: Add support for the expansion of $ORIGIN in RUNPATH.
* guix/build/gremlin.scm (expand-variable, expand-origin): New procedures. (validate-needed-in-runpath): Map 'expand-origin' to the RUNPATH field of DYNINFO. * tests/gremlin.scm ("expand-origin"): New test.
This commit is contained in:
parent
a635ed5ccb
commit
cd91504df2
|
@ -39,6 +39,7 @@
|
|||
elf-dynamic-info-needed
|
||||
elf-dynamic-info-rpath
|
||||
elf-dynamic-info-runpath
|
||||
expand-origin
|
||||
|
||||
validate-needed-in-runpath))
|
||||
|
||||
|
@ -236,6 +237,30 @@ value of DT_NEEDED entries is a string.)"
|
|||
(string-prefix? libc-lib lib))
|
||||
%libc-libraries))
|
||||
|
||||
(define (expand-variable str variable value)
|
||||
"Replace occurrences of '$VARIABLE' or '${VARIABLE}' in STR with VALUE."
|
||||
(define variables
|
||||
(list (string-append "$" variable)
|
||||
(string-append "${" variable "}")))
|
||||
|
||||
(let loop ((thing variables)
|
||||
(str str))
|
||||
(match thing
|
||||
(()
|
||||
str)
|
||||
((head tail ...)
|
||||
(let ((index (string-contains str head))
|
||||
(len (string-length head)))
|
||||
(loop (if index variables tail)
|
||||
(if index
|
||||
(string-replace str value
|
||||
index (+ index len))
|
||||
str)))))))
|
||||
|
||||
(define (expand-origin str directory)
|
||||
"Replace occurrences of '$ORIGIN' in STR with DIRECTORY."
|
||||
(expand-variable str "ORIGIN" directory))
|
||||
|
||||
(define* (validate-needed-in-runpath file
|
||||
#:key (always-found? libc-library?))
|
||||
"Return #t if all the libraries listed as FILE's 'DT_NEEDED' entries are
|
||||
|
@ -254,17 +279,18 @@ exceeds total size~%"
|
|||
|
||||
(let* ((elf (call-with-input-file file
|
||||
(compose parse-elf get-bytevector-all)))
|
||||
(expand (cute expand-origin <> (dirname file)))
|
||||
(dyninfo (elf-dynamic-info elf)))
|
||||
(when dyninfo
|
||||
(let* ((runpath (filter store-file-name?
|
||||
(elf-dynamic-info-runpath dyninfo)))
|
||||
(bogus (remove store-file-name?
|
||||
(elf-dynamic-info-runpath dyninfo)))
|
||||
;; XXX: In theory we should also expand $PLATFORM and $LIB, but these
|
||||
;; appear to be really unused.
|
||||
(let* ((expanded (map expand (elf-dynamic-info-runpath dyninfo)))
|
||||
(runpath (filter store-file-name? expanded))
|
||||
(bogus (remove store-file-name? expanded))
|
||||
(needed (remove always-found?
|
||||
(elf-dynamic-info-needed dyninfo)))
|
||||
(not-found (remove (cut search-path runpath <>)
|
||||
needed)))
|
||||
;; XXX: $ORIGIN is not supported.
|
||||
(unless (null? bogus)
|
||||
(format (current-error-port)
|
||||
"~a: warning: RUNPATH contains bogus entries: ~s~%"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#:use-module (guix build utils)
|
||||
#:use-module (guix build gremlin)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (srfi srfi-64)
|
||||
#:use-module (rnrs io ports)
|
||||
#:use-module (ice-9 match))
|
||||
|
@ -51,6 +52,17 @@
|
|||
(string-take lib (string-contains lib ".so")))
|
||||
(elf-dynamic-info-needed dyninfo))))))
|
||||
|
||||
(test-equal "expand-origin"
|
||||
'("OOO/../lib"
|
||||
"OOO"
|
||||
"../OOO/bar/OOO/baz"
|
||||
"ORIGIN/foo")
|
||||
(map (cut expand-origin <> "OOO")
|
||||
'("$ORIGIN/../lib"
|
||||
"${ORIGIN}"
|
||||
"../${ORIGIN}/bar/$ORIGIN/baz"
|
||||
"ORIGIN/foo")))
|
||||
|
||||
(test-end "gremlin")
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue