summaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-04-17 13:38:12 +0200
committerLudovic Courtès <ludo@gnu.org>2018-05-07 11:21:36 +0200
commitb178fc236908ad2da86734ea8e01abd3ff8981da (patch)
tree0cb5cb7f5e243fbd49f57cc87268e38cd6fdbf8e /guix
parentad4835fe018a4a0c1955385c819fed7ec4a841d5 (diff)
downloadgnu-guix-b178fc236908ad2da86734ea8e01abd3ff8981da.tar
gnu-guix-b178fc236908ad2da86734ea8e01abd3ff8981da.tar.gz
gremlin: Add 'strip-runpath'.
* guix/build/gremlin.scm (strip-runpath): New procedure. * tests/gremlin.scm (c-compiler): New variable. ("strip-runpath"): New test.
Diffstat (limited to 'guix')
-rw-r--r--guix/build/gremlin.scm46
1 files changed, 45 insertions, 1 deletions
diff --git a/guix/build/gremlin.scm b/guix/build/gremlin.scm
index 78d1333117..e8ea66dfb3 100644
--- a/guix/build/gremlin.scm
+++ b/guix/build/gremlin.scm
@@ -41,7 +41,8 @@
elf-dynamic-info-runpath
expand-origin
- validate-needed-in-runpath))
+ validate-needed-in-runpath
+ strip-runpath))
;;; Commentary:
;;;
@@ -320,4 +321,47 @@ be found in RUNPATH ~s~%"
;; (format (current-error-port) "~a is OK~%" file))
(null? not-found))))))
+(define (strip-runpath file)
+ "Remove from the DT_RUNPATH of FILE any entries that are not necessary
+according to DT_NEEDED."
+ (define (minimal-runpath needed runpath)
+ (filter (lambda (directory)
+ (and (string-prefix? "/" directory)
+ (any (lambda (lib)
+ (file-exists? (string-append directory "/" lib)))
+ needed)))
+ runpath))
+
+ (define port
+ (open-file file "r+b"))
+
+ (catch #t
+ (lambda ()
+ (let* ((elf (parse-elf (get-bytevector-all port)))
+ (entries (dynamic-entries elf (dynamic-link-segment elf)))
+ (needed (filter-map (lambda (entry)
+ (and (= (dynamic-entry-type entry)
+ DT_NEEDED)
+ (dynamic-entry-value entry)))
+ entries))
+ (runpath (find (lambda (entry)
+ (= DT_RUNPATH (dynamic-entry-type entry)))
+ entries))
+ (old (search-path->list
+ (dynamic-entry-value runpath)))
+ (new (minimal-runpath needed old)))
+ (unless (equal? old new)
+ (format (current-error-port)
+ "~a: stripping RUNPATH to ~s (removed ~s)~%"
+ file new
+ (lset-difference string=? old new))
+ (seek port (dynamic-entry-offset runpath) SEEK_SET)
+ (put-bytevector port (string->utf8 (string-join new ":")))
+ (put-u8 port 0))
+ (close-port port)
+ new))
+ (lambda (key . args)
+ (false-if-exception (close-port port))
+ (apply throw key args))))
+
;;; gremlin.scm ends here