summaryrefslogtreecommitdiff
path: root/guix/build/gnu-build-system.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2020-11-27 08:55:54 +0100
committerLudovic Courtès <ludo@gnu.org>2020-12-01 21:30:28 +0100
commitf85efa86e7690d9181946351631e02b1c20958c9 (patch)
treee0d1c48b183457a414c4df807846ae3c8bf8b51a /guix/build/gnu-build-system.scm
parent52564e99862dc80fa801efd45dbeee6a7478a694 (diff)
build-system/gnu: Add 'make-dynamic-linker-cache' phase.
* guix/build/gnu-build-system.scm (make-dynamic-linker-cache): New procedure. (%standard-phases): Add it. * guix/build-system/gnu.scm (gnu-build, gnu-cross-build): Add #:make-dynamic-linker-cache? and honor it.
Diffstat (limited to 'guix/build/gnu-build-system.scm')
-rw-r--r--guix/build/gnu-build-system.scm68
1 files changed, 68 insertions, 0 deletions
diff --git a/guix/build/gnu-build-system.scm b/guix/build/gnu-build-system.scm
index 8fa11f4ea9..5f08b9d6ac 100644
--- a/guix/build/gnu-build-system.scm
+++ b/guix/build/gnu-build-system.scm
@@ -712,6 +712,73 @@ which cannot be found~%"
(which binary) rest)))))))))
outputs))
+(define* (make-dynamic-linker-cache #:key outputs
+ (make-dynamic-linker-cache? #t)
+ #:allow-other-keys)
+ "Create a dynamic linker cache under 'etc/ld.so.cache' in each of the
+OUTPUTS. This reduces application startup time by avoiding the 'stat' storm
+that traversing all the RUNPATH entries entails."
+ (define (make-cache-for-output directory)
+ (define bin-directories
+ (filter-map (lambda (sub-directory)
+ (let ((directory (string-append directory "/"
+ sub-directory)))
+ (and (directory-exists? directory)
+ directory)))
+ '("bin" "sbin" "libexec")))
+
+ (define programs
+ ;; Programs that can benefit from the ld.so cache.
+ (append-map (lambda (directory)
+ (if (directory-exists? directory)
+ (find-files directory
+ (lambda (file stat)
+ (and (executable-file? file)
+ (elf-file? file))))
+ '()))
+ bin-directories))
+
+ (define library-path
+ ;; Directories containing libraries that PROGRAMS depend on,
+ ;; recursively.
+ (delete-duplicates
+ (append-map (lambda (program)
+ (map dirname (file-needed/recursive program)))
+ programs)))
+
+ (define cache-file
+ (string-append directory "/etc/ld.so.cache"))
+
+ (define ld.so.conf
+ (string-append (or (getenv "TMPDIR") "/tmp")
+ "/ld.so.conf"))
+
+ (unless (null? library-path)
+ (mkdir-p (dirname cache-file))
+ (guard (c ((invoke-error? c)
+ ;; Do not treat 'ldconfig' failure as an error.
+ (format (current-error-port)
+ "warning: 'ldconfig' failed:~%")
+ (report-invoke-error c (current-error-port))))
+ ;; Create a config file to tell 'ldconfig' where to look for the
+ ;; libraries that PROGRAMS need.
+ (call-with-output-file ld.so.conf
+ (lambda (port)
+ (for-each (lambda (directory)
+ (display directory port)
+ (newline port))
+ library-path)))
+
+ (invoke "ldconfig" "-f" ld.so.conf "-C" cache-file)
+ (format #t "created '~a' from ~a library search path entries~%"
+ cache-file (length library-path)))))
+
+ (if make-dynamic-linker-cache?
+ (match outputs
+ (((_ . directories) ...)
+ (for-each make-cache-for-output directories)))
+ (format #t "ld.so cache not built~%")))
+
(define %license-file-regexp
;; Regexp matching license files.
"^(COPYING.*|LICEN[CS]E.*|[Ll]icen[cs]e.*|Copy[Rr]ight(\\.(txt|md))?)$")
@@ -791,6 +858,7 @@ which cannot be found~%"
validate-documentation-location
delete-info-dir-file
patch-dot-desktop-files
+ make-dynamic-linker-cache
install-license-files
reset-gzip-timestamps
compress-documentation)))