summaryrefslogtreecommitdiff
path: root/guix/build/gnu-build-system.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/build/gnu-build-system.scm')
-rw-r--r--guix/build/gnu-build-system.scm173
1 files changed, 123 insertions, 50 deletions
diff --git a/guix/build/gnu-build-system.scm b/guix/build/gnu-build-system.scm
index 17fa7afd8d..2880168273 100644
--- a/guix/build/gnu-build-system.scm
+++ b/guix/build/gnu-build-system.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -20,6 +20,7 @@
#:use-module (guix build utils)
#:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
#:use-module (ice-9 format)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
@@ -72,19 +73,23 @@
input-directories)))
(for-each (match-lambda
- ((env-var (directories ...) separator)
- (set-path-environment-variable env-var directories
+ ((env-var (files ...) separator type pattern)
+ (set-path-environment-variable env-var files
input-directories
- #:separator separator)))
+ #:separator separator
+ #:type type
+ #:pattern pattern)))
search-paths)
(when native-search-paths
;; Search paths for native inputs, when cross building.
(for-each (match-lambda
- ((env-var (directories ...) separator)
- (set-path-environment-variable env-var directories
+ ((env-var (files ...) separator type pattern)
+ (set-path-environment-variable env-var files
native-input-directories
- #:separator separator)))
+ #:separator separator
+ #:type type
+ #:pattern pattern)))
native-search-paths))
#t)
@@ -110,29 +115,15 @@ working directory."
(define* (patch-usr-bin-file #:key native-inputs inputs
(patch-/usr/bin/file? #t)
#:allow-other-keys)
- "Patch occurrences of /usr/bin/file in configure, if present."
+ "Patch occurrences of \"/usr/bin/file\" in all the executable 'configure'
+files found in the source tree. This works around Libtool's Autoconf macros,
+which generates invocations of \"/usr/bin/file\" that are used to determine
+things like the ABI being used."
(when patch-/usr/bin/file?
- (let ((file "configure")
- (file-command (or (and=> (assoc-ref (or native-inputs inputs) "file")
- (cut string-append <> "/bin/file"))
- (which "file"))))
- (cond ((not (file-exists? file))
- (format (current-error-port)
- "patch-usr-bin-file: warning: `~a' not found~%"
- file))
- ((not file-command)
- (format (current-error-port)
- "patch-usr-bin-file: warning: `file' not found in PATH~%"))
- (else
- (let ((st (stat file)))
- (substitute* file
- (("/usr/bin/file")
- (begin
- (format (current-error-port)
- "patch-usr-bin-file: ~a: changing `~a' to `~a'~%"
- file "/usr/bin/file" file-command)
- file-command)))
- (set-file-time file st))))))
+ (for-each (lambda (file)
+ (when (executable-file? file)
+ (patch-/usr/bin/file file)))
+ (find-files "." "^configure$")))
#t)
(define* (patch-source-shebangs #:key source #:allow-other-keys)
@@ -236,18 +227,11 @@ makefiles."
(string-append srcdir "/configure")
flags))))
-(define %parallel-job-count
- ;; String to be passed next to GNU Make's `-j' argument.
- (match (getenv "NIX_BUILD_CORES")
- (#f "1")
- ("0" (number->string (current-processor-count)))
- (x x)))
-
(define* (build #:key (make-flags '()) (parallel-build? #t)
#:allow-other-keys)
(zero? (apply system* "make"
`(,@(if parallel-build?
- `("-j" ,%parallel-job-count)
+ `("-j" ,(number->string (parallel-job-count)))
'())
,@make-flags))))
@@ -257,7 +241,7 @@ makefiles."
(if tests?
(zero? (apply system* "make" test-target
`(,@(if parallel-tests?
- `("-j" ,%parallel-job-count)
+ `("-j" ,(number->string (parallel-job-count)))
'())
,@make-flags)))
(begin
@@ -267,7 +251,7 @@ makefiles."
(define* (install #:key (make-flags '()) #:allow-other-keys)
(zero? (apply system* "make" "install" make-flags)))
-(define* (patch-shebangs #:key outputs (patch-shebangs? #t)
+(define* (patch-shebangs #:key inputs outputs (patch-shebangs? #t)
#:allow-other-keys)
(define (list-of-files dir)
(map (cut string-append dir "/" <>)
@@ -276,20 +260,26 @@ makefiles."
(eq? 'regular (stat:type s)))))
'())))
- (define bindirs
- (append-map (match-lambda
- ((_ . dir)
- (list (string-append dir "/bin")
- (string-append dir "/sbin"))))
- outputs))
+ (define bin-directories
+ (match-lambda
+ ((_ . dir)
+ (list (string-append dir "/bin")
+ (string-append dir "/sbin")))))
+
+ (define output-bindirs
+ (append-map bin-directories outputs))
+
+ (define input-bindirs
+ ;; Shebangs should refer to binaries of the target system---i.e., from
+ ;; "inputs", not from "native-inputs".
+ (append-map bin-directories inputs))
(when patch-shebangs?
- (let ((path (append bindirs
- (search-path-as-string->list (getenv "PATH")))))
+ (let ((path (append output-bindirs input-bindirs)))
(for-each (lambda (dir)
(let ((files (list-of-files dir)))
(for-each (cut patch-shebang <> path) files)))
- bindirs)))
+ output-bindirs)))
#t)
(define* (strip #:key target outputs (strip-binaries? #t)
@@ -350,7 +340,9 @@ makefiles."
debug-output objcopy-command))
(file-system-fold (const #t)
(lambda (path stat result) ; leaf
- (and (or (not debug-output)
+ (and (file-exists? path) ;discard dangling symlinks
+ (or (elf-file? path) (ar-file? path))
+ (or (not debug-output)
(make-debug-file path))
(zero? (apply system* strip-command
(append strip-flags (list path))))
@@ -377,6 +369,85 @@ makefiles."
strip-directories)))
outputs))))
+(define* (validate-documentation-location #:key outputs
+ #:allow-other-keys)
+ "Documentation should go to 'share/info' and 'share/man', not just 'info/'
+and 'man/'. This phase moves directories to the right place if needed."
+ (define (validate-sub-directory output sub-directory)
+ (let ((directory (string-append output "/" sub-directory)))
+ (when (directory-exists? directory)
+ (let ((target (string-append output "/share/" sub-directory)))
+ (format #t "moving '~a' to '~a'~%" directory target)
+ (mkdir-p (dirname target))
+ (rename-file directory target)))))
+
+ (define (validate-output output)
+ (for-each (cut validate-sub-directory output <>)
+ '("man" "info")))
+
+ (match outputs
+ (((names . directories) ...)
+ (for-each validate-output directories)))
+ #t)
+
+(define* (compress-documentation #:key outputs
+ (compress-documentation? #t)
+ (documentation-compressor "gzip")
+ (documentation-compressor-flags
+ '("--best" "--no-name"))
+ (compressed-documentation-extension ".gz")
+ #:allow-other-keys)
+ "When COMPRESS-DOCUMENTATION? is true, compress man pages and Info files
+found in OUTPUTS using DOCUMENTATION-COMPRESSOR, called with
+DOCUMENTATION-COMPRESSOR-FLAGS."
+ (define (retarget-symlink link)
+ (let ((target (readlink link)))
+ (delete-file link)
+ (symlink (string-append target compressed-documentation-extension)
+ link)))
+
+ (define (has-links? file)
+ ;; Return #t if FILE has hard links.
+ (> (stat:nlink (lstat file)) 1))
+
+ (define (maybe-compress-directory directory regexp)
+ (or (not (directory-exists? directory))
+ (match (find-files directory regexp)
+ (() ;nothing to compress
+ #t)
+ ((files ...) ;one or more files
+ (format #t
+ "compressing documentation in '~a' with ~s and flags ~s~%"
+ directory documentation-compressor
+ documentation-compressor-flags)
+ (call-with-values
+ (lambda ()
+ (partition symbolic-link? files))
+ (lambda (symlinks regular-files)
+ ;; Compress the non-symlink files, and adjust symlinks to refer
+ ;; to the compressed files. Leave files that have hard links
+ ;; unchanged ('gzip' would refuse to compress them anyway.)
+ (and (zero? (apply system* documentation-compressor
+ (append documentation-compressor-flags
+ (remove has-links? regular-files))))
+ (every retarget-symlink
+ (filter (cut string-match regexp <>)
+ symlinks)))))))))
+
+ (define (maybe-compress output)
+ (and (maybe-compress-directory (string-append output "/share/man")
+ "\\.[0-9]+$")
+ (maybe-compress-directory (string-append output "/share/info")
+ "\\.info(-[0-9]+)?$")))
+
+ (if compress-documentation?
+ (match outputs
+ (((names . directories) ...)
+ (every maybe-compress directories)))
+ (begin
+ (format #t "not compressing documentation~%")
+ #t)))
+
(define %standard-phases
;; Standard build phases, as a list of symbol/procedure pairs.
(let-syntax ((phases (syntax-rules ()
@@ -385,7 +456,9 @@ makefiles."
patch-usr-bin-file
patch-source-shebangs configure patch-generated-file-shebangs
build check install
- patch-shebangs strip)))
+ patch-shebangs strip
+ validate-documentation-location
+ compress-documentation)))
(define* (gnu-build #:key (source #f) (outputs #f) (inputs #f)