guix build: Separate transformation options.

* guix/scripts/build.scm (%transformation-options): New variable.
(show-transformation-options-help): New procedure.
(show-help): Remove '--with-source' documentation and add
'show-transformation-options-help' call.
(%options): Remove "with-source" and append %TRANSFORMATION-OPTIONS.
* doc/guix.texi (Package Transformation Options): New node.  Document
'--with-source', moved from...
(Additional Build Options): ... here.
This commit is contained in:
Ludovic Courtès 2016-01-31 20:44:21 +01:00
parent ccd7158d2a
commit 88ad6deda6
2 changed files with 140 additions and 104 deletions

@ -3810,6 +3810,7 @@ described in the subsections below.
@menu
* Common Build Options:: Build options for most commands.
* Package Transformation Options:: Creating variants of packages.
* Additional Build Options:: Options specific to 'guix build'.
@end menu
@ -3939,6 +3940,56 @@ These options are parsed independently, and the result is appended to
the parsed command-line options.
@end defvr
@node Package Transformation Options
@subsection Package Transformation Options
@cindex package variants
Another set of command-line options supported by @command{guix build}
are @dfn{package transformation options}. These are options that allow,
from the command-line, to define @dfn{package variants}---for instance,
packages built from different source code. This is a convenient way to
create customized packages on the fly without having to type in the
definitions of package variants (@pxref{Defining Packages}).
@table @code
@item --with-source=@var{source}
Use @var{source} as the source of the corresponding package.
@var{source} must be a file name or a URL, as for @command{guix
download} (@pxref{Invoking guix download}).
The ``corresponding package'' is taken to be one specified on the
command line whose name matches the base of @var{source}---e.g., if
@var{source} is @code{/src/guile-2.0.10.tar.gz}, the corresponding
package is @code{guile}. Likewise, the version string is inferred from
@var{source}; in the previous example, it's @code{2.0.10}.
This option allows users to try out versions of packages other than the
one provided by the distribution. The example below downloads
@file{ed-1.7.tar.gz} from a GNU mirror and uses that as the source for
the @code{ed} package:
@example
guix build ed --with-source=mirror://gnu/ed/ed-1.7.tar.gz
@end example
As a developer, @code{--with-source} makes it easy to test release
candidates:
@example
guix build guile --with-source=../guile-2.0.9.219-e1bb7.tar.xz
@end example
@dots{} or to build from a checkout in a pristine environment:
@example
$ git clone git://git.sv.gnu.org/guix.git
$ guix build guix --with-source=./guix
@end example
@end table
@node Additional Build Options
@subsection Additional Build Options
@ -4047,40 +4098,6 @@ Cross-build for @var{triplet}, which must be a valid GNU triplet, such
as @code{"mips64el-linux-gnu"} (@pxref{Configuration Names, GNU
configuration triplets,, configure, GNU Configure and Build System}).
@item --with-source=@var{source}
Use @var{source} as the source of the corresponding package.
@var{source} must be a file name or a URL, as for @command{guix
download} (@pxref{Invoking guix download}).
The ``corresponding package'' is taken to be one specified on the
command line whose name matches the base of @var{source}---e.g., if
@var{source} is @code{/src/guile-2.0.10.tar.gz}, the corresponding
package is @code{guile}. Likewise, the version string is inferred from
@var{source}; in the previous example, it's @code{2.0.10}.
This option allows users to try out versions of packages other than the
one provided by the distribution. The example below downloads
@file{ed-1.7.tar.gz} from a GNU mirror and uses that as the source for
the @code{ed} package:
@example
guix build ed --with-source=mirror://gnu/ed/ed-1.7.tar.gz
@end example
As a developer, @code{--with-source} makes it easy to test release
candidates:
@example
guix build guile --with-source=../guile-2.0.9.219-e1bb7.tar.xz
@end example
@dots{} or to build from a checkout in a pristine environment:
@example
$ git clone git://git.sv.gnu.org/guix.git
$ guix build guix --with-source=./guix
@end example
@anchor{build-check}
@item --check
@cindex determinism, checking

@ -41,7 +41,10 @@
set-build-options-from-command-line
set-build-options-from-command-line*
show-build-options-help
%transformation-options
options->transformation
show-transformation-options-help
guix-build))
@ -140,6 +143,82 @@ the new package's version number from URI."
(source (download-to-store store uri
#:recursive? #t))))))
;;;
;;; Transformations.
;;;
(define (transform-package-source sources)
"Return a transformation procedure that replaces package sources with the
matching URIs given in SOURCES."
(define new-sources
(map (lambda (uri)
(cons (package-name->name+version (basename uri))
uri))
sources))
(lambda (store obj)
(let loop ((sources new-sources)
(result '()))
(match obj
((? package? p)
(let ((source (assoc-ref sources (package-name p))))
(if source
(package-with-source store p source)
p)))
(_
obj)))))
(define %transformations
;; Transformations that can be applied to things to build. The car is the
;; key used in the option alist, and the cdr is the transformation
;; procedure; it is called with two arguments: the store, and a list of
;; things to build.
`((with-source . ,transform-package-source)))
(define %transformation-options
;; The command-line interface to the above transformations.
(list (option '("with-source") #t #f
(lambda (opt name arg result . rest)
(apply values
(cons (alist-cons 'with-source arg result)
rest))))))
(define (show-transformation-options-help)
(display (_ "
--with-source=SOURCE
use SOURCE when building the corresponding package")))
(define (options->transformation opts)
"Return a procedure that, when passed an object to build (package,
derivation, etc.), applies the transformations specified by OPTS."
(define applicable
;; List of applicable transformations as symbol/procedure pairs.
(filter-map (match-lambda
((key . transform)
(match (filter-map (match-lambda
((k . arg)
(and (eq? k key) arg)))
opts)
(() #f)
(args (cons key (transform args))))))
%transformations))
(lambda (store obj)
(fold (match-lambda*
(((name . transform) obj)
(let ((new (transform store obj)))
(when (eq? new obj)
(warning (_ "transformation '~a' had no effect on ~a~%")
name
(if (package? obj)
(package-full-name obj)
obj)))
new)))
obj
applicable)))
;;;
;;; Standard command-line build options.
@ -320,9 +399,6 @@ Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
-s, --system=SYSTEM attempt to build for SYSTEM--e.g., \"i686-linux\""))
(display (_ "
--target=TRIPLET cross-build for TRIPLET--e.g., \"armel-linux-gnu\""))
(display (_ "
--with-source=SOURCE
use SOURCE when building the corresponding package"))
(display (_ "
--no-grafts do not graft packages"))
(display (_ "
@ -337,6 +413,8 @@ Build the given PACKAGE-OR-DERIVATION and return their output paths.\n"))
(newline)
(show-build-options-help)
(newline)
(show-transformation-options-help)
(newline)
(display (_ "
-h, --help display this help and exit"))
(display (_ "
@ -401,15 +479,13 @@ must be one of 'package', 'all', or 'transitive'~%")
(option '("log-file") #f #f
(lambda (opt name arg result)
(alist-cons 'log-file? #t result)))
(option '("with-source") #t #f
(lambda (opt name arg result)
(alist-cons 'with-source arg result)))
(option '("no-grafts") #f #f
(lambda (opt name arg result)
(alist-cons 'graft? #f
(alist-delete 'graft? result eq?))))
%standard-build-options))
(append %transformation-options
%standard-build-options)))
(define (options->things-to-build opts)
"Read the arguments from OPTS and return a list of high-level objects to
@ -488,63 +564,6 @@ build."
(map (cut transform store <>)
(options->things-to-build opts)))))
(define (transform-package-source sources)
"Return a transformation procedure that replaces package sources with the
matching URIs given in SOURCES."
(define new-sources
(map (lambda (uri)
(cons (package-name->name+version (basename uri))
uri))
sources))
(lambda (store obj)
(let loop ((sources new-sources)
(result '()))
(match obj
((? package? p)
(let ((source (assoc-ref sources (package-name p))))
(if source
(package-with-source store p source)
p)))
(_
obj)))))
(define %transformations
;; Transformations that can be applied to things to build. The car is the
;; key used in the option alist, and the cdr is the transformation
;; procedure; it is called with two arguments: the store, and a list of
;; things to build.
`((with-source . ,transform-package-source)))
(define (options->transformation opts)
"Return a procedure that, when passed an object to build (package,
derivation, etc.), applies the transformations specified by OPTS."
(define applicable
;; List of applicable transformations as symbol/procedure pairs.
(filter-map (match-lambda
((key . transform)
(match (filter-map (match-lambda
((k . arg)
(and (eq? k key) arg)))
opts)
(() #f)
(args (cons key (transform args))))))
%transformations))
(lambda (store obj)
(fold (match-lambda*
(((name . transform) obj)
(let ((new (transform store obj)))
(when (eq? new obj)
(warning (_ "transformation '~a' had no effect on ~a~%")
name
(if (package? obj)
(package-full-name obj)
obj)))
new)))
obj
applicable)))
(define (show-build-log store file urls)
"Show the build log for FILE, falling back to remote logs from URLS if
needed."