1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012 Ludovic Courtès <ludo@gnu.org>
4 ;;; This file is part of GNU Guix.
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.
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.
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-system gnu)
20 #:use-module (guix store)
21 #:use-module (guix utils)
22 #:use-module (guix derivations)
23 #:use-module (guix build-system)
24 #:use-module (guix packages)
25 #:use-module (srfi srfi-1)
26 #:use-module (srfi srfi-39)
27 #:use-module (ice-9 match)
30 package-with-explicit-inputs
31 package-with-extra-configure-variable
32 static-libgcc-package))
36 ;; Standard build procedure for packages using the GNU Build System or
37 ;; something compatible ("./configure && make && make install").
41 (define* (package-with-explicit-inputs p boot-inputs
43 (loc (current-source-location))
45 "Rewrite P, which is assumed to use GNU-BUILD-SYSTEM, to take
46 BOOT-INPUTS as explicit inputs instead of the implicit default, and
47 return it. Use GUILE to run the builder, or the distro's final Guile
49 (define rewritten-input
51 ((name (? package? p) sub-drv ...)
53 (package-with-explicit-inputs p boot-inputs #:guile guile)
57 (define boot-input-names
58 (map car boot-inputs))
60 (define (filtered-inputs inputs)
61 (fold alist-delete inputs boot-input-names))
64 (location (if (pair? loc) (source-properties->location loc) loc))
66 (let ((args (package-arguments p)))
70 #:implicit-inputs? #f ,@(args system)))
72 #:implicit-inputs? #f ,@args))))
73 (native-inputs (map rewritten-input
74 (filtered-inputs (package-native-inputs p))))
75 (propagated-inputs (map rewritten-input
77 (package-propagated-inputs p))))
78 (inputs `(,@boot-inputs
79 ,@(map rewritten-input
80 (filtered-inputs (package-inputs p)))))))
82 (define (package-with-extra-configure-variable p variable value)
83 "Return a version of P with VARIABLE=VALUE specified as an extra
84 `configure' flag. An example is LDFLAGS=-static. If P already has
85 configure flags for VARIABLE, the associated value is augmented."
87 (define (rewritten-inputs inputs)
89 ((name (? package? p) sub ...)
90 `(,name ,(loop p) ,@sub))
97 (let ((args (match (package-arguments p)
101 (substitute-keyword-arguments args
102 ((#:configure-flags flags)
103 (let* ((var= (string-append variable "="))
104 (len (string-length var=)))
105 `(cons ,(string-append var= value)
107 (if (string-prefix? ,var= flag)
109 ,(string-append var= value " ")
110 (substring flag ,len))
113 (inputs (rewritten-inputs (package-inputs p)))
114 (propagated-inputs (rewritten-inputs (package-propagated-inputs p))))))
116 (define (static-libgcc-package p)
117 "A version of P linked with `-static-gcc'."
118 (package-with-extra-configure-variable p "LDFLAGS" "-static-libgcc"))
122 ;; Store passed to STANDARD-INPUTS.
125 (define standard-inputs
128 "Return the list of implicit standard inputs used with the GNU Build
129 System: GCC, GNU Make, Bash, Coreutils, etc."
131 ((name pkg sub-drv ...)
132 (cons* name (package-derivation (%store) pkg system) sub-drv))
133 ((name (? derivation-path? path) sub-drv ...)
134 (cons* name path sub-drv))
136 (error "invalid standard input" z)))
138 ;; Resolve (distro packages base) lazily to hide circular dependency.
139 (let* ((distro (resolve-module '(distro packages base)))
140 (inputs (module-ref distro '%final-inputs)))
142 (append-map (match-lambda
143 ((name package _ ...)
144 (package-transitive-propagated-inputs package)))
147 (define* (gnu-build store name source inputs
149 (outputs '("out")) (configure-flags ''())
151 (patches ''()) (patch-flags ''("--batch" "-p1"))
153 (path-exclusions ''())
155 (parallel-build? #t) (parallel-tests? #t)
158 (strip-flags ''("--strip-debug"))
159 (strip-directories ''("lib" "lib64" "libexec"
161 (phases '%standard-phases)
162 (system (%current-system))
163 (implicit-inputs? #t) ; useful when bootstrapping
164 (imported-modules '((guix build gnu-build-system)
166 (modules '((guix build gnu-build-system)
167 (guix build utils))))
168 "Return a derivation called NAME that builds from tarball SOURCE, with
169 input derivation INPUTS, using the usual procedure of the GNU Build
170 System. The builder is run with GUILE, or with the distro's final Guile
171 package if GUILE is #f or omitted.
173 The builder is run in a context where MODULES are used; IMPORTED-MODULES
174 specifies modules not provided by Guile itself that must be imported in
175 the builder's environment, from the host. Note that we distinguish
176 between both, because for Guile's own modules like (ice-9 foo), we want
177 to use GUILE's own version of it, rather than import the user's one,
178 which could lead to gratuitous input divergence."
181 (use-modules ,@modules)
182 (gnu-build #:source ,(if (derivation-path? source)
183 (derivation-path->output-path source)
187 #:inputs %build-inputs
189 #:patch-flags ,patch-flags
191 #:configure-flags ,configure-flags
192 #:make-flags ,make-flags
193 #:out-of-source? ,out-of-source?
194 #:path-exclusions ,path-exclusions
196 #:parallel-build? ,parallel-build?
197 #:parallel-tests? ,parallel-tests?
198 #:patch-shebangs? ,patch-shebangs?
199 #:strip-binaries? ,strip-binaries?
200 #:strip-flags ,strip-flags
201 #:strip-directories ,strip-directories)))
203 (define guile-for-build
206 (package-derivation store guile system))
207 ((and (? string?) (? derivation-path?))
210 (let* ((distro (resolve-interface '(distro packages base)))
211 (guile (module-ref distro 'guile-final)))
212 (package-derivation store guile system)))))
214 (build-expression->derivation store name system
218 ,@(if implicit-inputs?
219 (parameterize ((%store store))
220 (standard-inputs system))
223 #:modules imported-modules
224 #:guile-for-build guile-for-build))
226 (define gnu-build-system
227 (build-system (name 'gnu)
229 "The GNU Build System—i.e., ./configure && make && make install")
230 (build gnu-build))) ; TODO: add `gnu-cross-build'