substitute: Improve functional decomposition.
[guix.git] / guix / build / rpath.scm
blob75a1fef5ef8549bda1df839cc85f9d2680e0084d
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013 Ludovic Courtès <ludo@gnu.org>
3 ;;;
4 ;;; This file is part of GNU Guix.
5 ;;;
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
10 ;;;
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;;; GNU General Public License for more details.
15 ;;;
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
19 (define-module (guix build rpath)
20   #:use-module (ice-9 popen)
21   #:use-module (ice-9 rdelim)
22   #:export (%patchelf
23             file-rpath
24             augment-rpath))
26 ;;; Commentary:
27 ;;;
28 ;;; Tools to manipulate the RPATH and RUNPATH of ELF binaries.  Currently they
29 ;;; rely on PatchELF.
30 ;;;
31 ;;; Code:
33 (define %patchelf
34   ;; The `patchelf' command.
35   (make-parameter "patchelf"))
37 (define %not-colon
38   (char-set-complement (char-set #\:)))
40 (define (file-rpath file)
41   "Return the RPATH (or RUNPATH) of FILE as a list of directory names, or #f
42 on failure."
43   (let* ((p (open-pipe* OPEN_READ (%patchelf) "--print-rpath" file))
44          (l (read-line p)))
45     (and (zero? (close-pipe p))
46          (string-tokenize l %not-colon))))
48 (define (augment-rpath file dir)
49   "Add DIR to the front of the RPATH and RUNPATH of FILE.  Return the new
50 RPATH as a list, or #f on failure."
51   (let* ((rpath  (or (file-rpath file) '()))
52          (rpath* (cons dir rpath)))
53     (format #t "~a: changing RPATH from ~s to ~s~%"
54             file rpath rpath*)
55     (and (zero? (system* (%patchelf) "--set-rpath"
56                          (string-join rpath* ":") file))
57          rpath*)))
59 ;;; rpath.scm ends here