guix build: Add '--rounds'.
* guix/scripts/build.scm (show-build-options-help) (%standard-build-options): Add --rounds. (set-build-options-from-command-line): Honor it. * doc/guix.texi (Invoking guix build): Document it. * doc/contributing.texi (Submitting Patches): Mention it.
This commit is contained in:
parent
2fba87ac7c
commit
5b74fe065b
3 changed files with 44 additions and 5 deletions
|
@ -279,15 +279,31 @@ not affected by the change; @code{guix refresh --list-dependent
|
||||||
@var{package}} will help you do that (@pxref{Invoking guix refresh}).
|
@var{package}} will help you do that (@pxref{Invoking guix refresh}).
|
||||||
|
|
||||||
@item
|
@item
|
||||||
|
@cindex determinism, of build processes
|
||||||
|
@cindex reproducible builds, checking
|
||||||
Check whether the package's build process is deterministic. This
|
Check whether the package's build process is deterministic. This
|
||||||
typically means checking whether an independent build of the package
|
typically means checking whether an independent build of the package
|
||||||
yields the exact same result that you obtained, bit for bit.
|
yields the exact same result that you obtained, bit for bit.
|
||||||
|
|
||||||
A simple way to do that is with @command{guix challenge}
|
A simple way to do that is by building the same package several times in
|
||||||
(@pxref{Invoking guix challenge}). You may run it once the package has
|
a row on your machine (@pxref{Invoking guix build}):
|
||||||
been committed and built by @code{hydra.gnu.org} to check whether it
|
|
||||||
obtains the same result as you did. Better yet: Find another machine
|
@example
|
||||||
that can build it and run @command{guix publish}.
|
guix build --rounds=2 my-package
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This is enough to catch a class of common non-determinism issues, such
|
||||||
|
as timestamps or randomly-generated output in the build result.
|
||||||
|
|
||||||
|
Another option is to use @command{guix challenge} (@pxref{Invoking guix
|
||||||
|
challenge}). You may run it once the package has been committed and
|
||||||
|
built by @code{hydra.gnu.org} to check whether it obtains the same
|
||||||
|
result as you did. Better yet: Find another machine that can build it
|
||||||
|
and run @command{guix publish}. Since the remote build machine is
|
||||||
|
likely different from yours, this can catch non-determinism issues
|
||||||
|
related to the hardware---e.g., use of different instruction set
|
||||||
|
extensions---or to the operating system kernel---e.g., reliance on
|
||||||
|
@code{uname} or @file{/proc} files.
|
||||||
|
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
|
|
|
@ -3876,6 +3876,20 @@ Do not use substitutes for build products. That is, always build things
|
||||||
locally instead of allowing downloads of pre-built binaries
|
locally instead of allowing downloads of pre-built binaries
|
||||||
(@pxref{Substitutes}).
|
(@pxref{Substitutes}).
|
||||||
|
|
||||||
|
@item --rounds=@var{n}
|
||||||
|
Build each derivation @var{n} times in a row, and raise an error if
|
||||||
|
consecutive build results are not bit-for-bit identical.
|
||||||
|
|
||||||
|
This is a useful way to detect non-deterministic builds processes.
|
||||||
|
Non-deterministic build processes are a problem because they make it
|
||||||
|
practically impossible for users to @emph{verify} whether third-party
|
||||||
|
binaries are genuine. @xref{Invoking guix challenge}, for more.
|
||||||
|
|
||||||
|
Note that, currently, the differing build results are not kept around,
|
||||||
|
so you will have to manually investigate in case of an error---e.g., by
|
||||||
|
stashing one of the build results with @code{guix archive --export},
|
||||||
|
then rebuilding, and finally comparing the two results.
|
||||||
|
|
||||||
@item --no-build-hook
|
@item --no-build-hook
|
||||||
Do not attempt to offload builds @i{via} the daemon's ``build hook''
|
Do not attempt to offload builds @i{via} the daemon's ``build hook''
|
||||||
(@pxref{Daemon Offload Setup}). That is, always build things locally
|
(@pxref{Daemon Offload Setup}). That is, always build things locally
|
||||||
|
|
|
@ -170,6 +170,8 @@ options handled by 'set-build-options-from-command-line', and listed in
|
||||||
--timeout=SECONDS mark the build as failed after SECONDS of activity"))
|
--timeout=SECONDS mark the build as failed after SECONDS of activity"))
|
||||||
(display (_ "
|
(display (_ "
|
||||||
--verbosity=LEVEL use the given verbosity LEVEL"))
|
--verbosity=LEVEL use the given verbosity LEVEL"))
|
||||||
|
(display (_ "
|
||||||
|
--rounds=N build N times in a row to detect non-determinism"))
|
||||||
(display (_ "
|
(display (_ "
|
||||||
-c, --cores=N allow the use of up to N CPU cores for the build"))
|
-c, --cores=N allow the use of up to N CPU cores for the build"))
|
||||||
(display (_ "
|
(display (_ "
|
||||||
|
@ -181,6 +183,7 @@ options handled by 'set-build-options-from-command-line', and listed in
|
||||||
;; TODO: Add more options.
|
;; TODO: Add more options.
|
||||||
(set-build-options store
|
(set-build-options store
|
||||||
#:keep-failed? (assoc-ref opts 'keep-failed?)
|
#:keep-failed? (assoc-ref opts 'keep-failed?)
|
||||||
|
#:rounds (assoc-ref opts 'rounds)
|
||||||
#:build-cores (or (assoc-ref opts 'cores) 0)
|
#:build-cores (or (assoc-ref opts 'cores) 0)
|
||||||
#:max-build-jobs (or (assoc-ref opts 'max-jobs) 1)
|
#:max-build-jobs (or (assoc-ref opts 'max-jobs) 1)
|
||||||
#:fallback? (assoc-ref opts 'fallback?)
|
#:fallback? (assoc-ref opts 'fallback?)
|
||||||
|
@ -210,6 +213,12 @@ options handled by 'set-build-options-from-command-line', and listed in
|
||||||
(apply values
|
(apply values
|
||||||
(alist-cons 'keep-failed? #t result)
|
(alist-cons 'keep-failed? #t result)
|
||||||
rest)))
|
rest)))
|
||||||
|
(option '("rounds") #t #f
|
||||||
|
(lambda (opt name arg result . rest)
|
||||||
|
(apply values
|
||||||
|
(alist-cons 'rounds (string->number* arg)
|
||||||
|
result)
|
||||||
|
rest)))
|
||||||
(option '("fallback") #f #f
|
(option '("fallback") #f #f
|
||||||
(lambda (opt name arg result . rest)
|
(lambda (opt name arg result . rest)
|
||||||
(apply values
|
(apply values
|
||||||
|
|
Reference in a new issue