2013-01-05 10:08:07 -05:00
|
|
|
|
;;; GNU Guix --- Functional package management for GNU
|
2021-04-08 16:43:00 -04:00
|
|
|
|
;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
2018-03-16 03:03:25 -04:00
|
|
|
|
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
|
2019-10-07 11:55:03 -04:00
|
|
|
|
;;; Copyright © 2020 Brendan Tildesley <mail@brendan.scot>
|
build-systems/gnu: Allow unpacking/repacking more kind of files.
Before this change, only plain directories, tar or zip archives were supported
as the source of a package for the GNU build system; anything else would cause
the unpack phase to fail. Origins relying on snippets would suffer from the
same problem.
This change adds the support to use files of the following extensions: .gz,
.Z, .bz2, .lz, and .xz, even when they are not tarballs. Files of unknown
extensions are treated as uncompressed files and supported as well.
* guix/packages.scm (patch-and-repack): Only add the compressor utility to the
PATH when the file is compressed. Bind more inputs in the mlet, and use them
for decompressing single files. Adjust the decompression and compression
routines.
[decompression-type]: Remove nested variable.
* guix/build/utils.scm (compressor, tarball?): New procedures. Move
%xz-parallel-args to the new 'compression helpers' section.
* tests/packages.scm: Add tests. Add missing copyright year for Jan.
* guix/build/gnu-build-system.scm (first-subdirectory): Return #f when no
sub-directory was found.
(unpack): Support more file types, including uncompressed plain files.
2021-01-18 11:51:21 -05:00
|
|
|
|
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
2012-06-13 11:03:34 -04:00
|
|
|
|
;;;
|
2013-01-05 10:08:07 -05:00
|
|
|
|
;;; This file is part of GNU Guix.
|
2012-06-13 11:03:34 -04:00
|
|
|
|
;;;
|
2013-01-05 10:08:07 -05:00
|
|
|
|
;;; GNU Guix is free software; you can redistribute it and/or modify it
|
2012-06-13 11:03:34 -04:00
|
|
|
|
;;; under the terms of the GNU General Public License as published by
|
|
|
|
|
;;; the Free Software Foundation; either version 3 of the License, or (at
|
|
|
|
|
;;; your option) any later version.
|
|
|
|
|
;;;
|
2013-01-05 10:08:07 -05:00
|
|
|
|
;;; GNU Guix is distributed in the hope that it will be useful, but
|
2012-06-13 11:03:34 -04:00
|
|
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;;; GNU General Public License for more details.
|
|
|
|
|
;;;
|
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
2013-01-05 10:08:07 -05:00
|
|
|
|
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
2012-06-13 11:03:34 -04:00
|
|
|
|
|
|
|
|
|
(define-module (guix build gnu-build-system)
|
|
|
|
|
#:use-module (guix build utils)
|
2015-04-01 10:47:49 -04:00
|
|
|
|
#:use-module (guix build gremlin)
|
|
|
|
|
#:use-module (guix elf)
|
2012-06-13 11:03:34 -04:00
|
|
|
|
#:use-module (ice-9 ftw)
|
2012-06-16 10:56:47 -04:00
|
|
|
|
#:use-module (ice-9 match)
|
2014-12-01 09:46:26 -05:00
|
|
|
|
#:use-module (ice-9 regex)
|
2012-12-20 16:31:08 -05:00
|
|
|
|
#:use-module (ice-9 format)
|
2019-06-14 17:02:28 -04:00
|
|
|
|
#:use-module (ice-9 ftw)
|
2012-06-16 10:56:47 -04:00
|
|
|
|
#:use-module (srfi srfi-1)
|
2015-08-30 08:08:44 -04:00
|
|
|
|
#:use-module (srfi srfi-19)
|
2018-03-16 18:33:52 -04:00
|
|
|
|
#:use-module (srfi srfi-34)
|
|
|
|
|
#:use-module (srfi srfi-35)
|
2012-08-19 11:54:54 -04:00
|
|
|
|
#:use-module (srfi srfi-26)
|
2015-04-01 10:47:49 -04:00
|
|
|
|
#:use-module (rnrs io ports)
|
2012-06-16 10:56:47 -04:00
|
|
|
|
#:export (%standard-phases
|
2017-11-05 15:32:02 -05:00
|
|
|
|
%license-file-regexp
|
2021-04-08 16:43:00 -04:00
|
|
|
|
%bootstrap-scripts
|
2018-03-19 05:50:05 -04:00
|
|
|
|
dump-file-contents
|
2012-06-16 10:56:47 -04:00
|
|
|
|
gnu-build))
|
2012-06-13 11:03:34 -04:00
|
|
|
|
|
|
|
|
|
;; Commentary:
|
|
|
|
|
;;
|
|
|
|
|
;; Standard build procedure for packages using the GNU Build System or
|
|
|
|
|
;; something compatible ("./configure && make && make install"). This is the
|
|
|
|
|
;; builder-side code.
|
|
|
|
|
;;
|
|
|
|
|
;; Code:
|
|
|
|
|
|
2017-06-11 16:50:43 -04:00
|
|
|
|
(cond-expand
|
|
|
|
|
(guile-2.2
|
|
|
|
|
;; Guile 2.2.2 has a bug whereby 'time-monotonic' objects have seconds and
|
|
|
|
|
;; nanoseconds swapped (fixed in Guile commit 886ac3e). Work around it.
|
|
|
|
|
(define time-monotonic time-tai))
|
|
|
|
|
(else #t))
|
|
|
|
|
|
2016-01-05 09:49:48 -05:00
|
|
|
|
(define* (set-SOURCE-DATE-EPOCH #:rest _)
|
|
|
|
|
"Set the 'SOURCE_DATE_EPOCH' environment variable. This is used by tools
|
|
|
|
|
that incorporate timestamps as a way to tell them to use a fixed timestamp.
|
|
|
|
|
See https://reproducible-builds.org/specs/source-date-epoch/."
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(setenv "SOURCE_DATE_EPOCH" "1"))
|
2016-01-05 09:49:48 -05:00
|
|
|
|
|
2019-06-14 17:02:28 -04:00
|
|
|
|
(define (first-subdirectory directory)
|
build-systems/gnu: Allow unpacking/repacking more kind of files.
Before this change, only plain directories, tar or zip archives were supported
as the source of a package for the GNU build system; anything else would cause
the unpack phase to fail. Origins relying on snippets would suffer from the
same problem.
This change adds the support to use files of the following extensions: .gz,
.Z, .bz2, .lz, and .xz, even when they are not tarballs. Files of unknown
extensions are treated as uncompressed files and supported as well.
* guix/packages.scm (patch-and-repack): Only add the compressor utility to the
PATH when the file is compressed. Bind more inputs in the mlet, and use them
for decompressing single files. Adjust the decompression and compression
routines.
[decompression-type]: Remove nested variable.
* guix/build/utils.scm (compressor, tarball?): New procedures. Move
%xz-parallel-args to the new 'compression helpers' section.
* tests/packages.scm: Add tests. Add missing copyright year for Jan.
* guix/build/gnu-build-system.scm (first-subdirectory): Return #f when no
sub-directory was found.
(unpack): Support more file types, including uncompressed plain files.
2021-01-18 11:51:21 -05:00
|
|
|
|
"Return the file name of the first sub-directory of DIRECTORY or false, when
|
|
|
|
|
there are none."
|
2019-06-14 17:02:28 -04:00
|
|
|
|
(match (scandir directory
|
|
|
|
|
(lambda (file)
|
|
|
|
|
(and (not (member file '("." "..")))
|
|
|
|
|
(file-is-directory? (string-append directory "/"
|
|
|
|
|
file)))))
|
build-systems/gnu: Allow unpacking/repacking more kind of files.
Before this change, only plain directories, tar or zip archives were supported
as the source of a package for the GNU build system; anything else would cause
the unpack phase to fail. Origins relying on snippets would suffer from the
same problem.
This change adds the support to use files of the following extensions: .gz,
.Z, .bz2, .lz, and .xz, even when they are not tarballs. Files of unknown
extensions are treated as uncompressed files and supported as well.
* guix/packages.scm (patch-and-repack): Only add the compressor utility to the
PATH when the file is compressed. Bind more inputs in the mlet, and use them
for decompressing single files. Adjust the decompression and compression
routines.
[decompression-type]: Remove nested variable.
* guix/build/utils.scm (compressor, tarball?): New procedures. Move
%xz-parallel-args to the new 'compression helpers' section.
* tests/packages.scm: Add tests. Add missing copyright year for Jan.
* guix/build/gnu-build-system.scm (first-subdirectory): Return #f when no
sub-directory was found.
(unpack): Support more file types, including uncompressed plain files.
2021-01-18 11:51:21 -05:00
|
|
|
|
((first . _) first)
|
|
|
|
|
(_ #f)))
|
2012-06-13 11:03:34 -04:00
|
|
|
|
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(define* (set-paths #:key target inputs native-inputs
|
|
|
|
|
(search-paths '()) (native-search-paths '())
|
2012-08-31 19:14:31 -04:00
|
|
|
|
#:allow-other-keys)
|
2013-03-30 06:31:50 -04:00
|
|
|
|
(define input-directories
|
2020-12-04 22:35:37 -05:00
|
|
|
|
;; The "source" input can be a directory, but we don't want it for search
|
|
|
|
|
;; paths. See <https://issues.guix.gnu.org/44924>.
|
|
|
|
|
(match (alist-delete "source" inputs)
|
2013-03-30 06:31:50 -04:00
|
|
|
|
(((_ . dir) ...)
|
|
|
|
|
dir)))
|
2012-07-05 18:50:07 -04:00
|
|
|
|
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(define native-input-directories
|
|
|
|
|
(match native-inputs
|
|
|
|
|
(((_ . dir) ...)
|
|
|
|
|
dir)
|
|
|
|
|
(#f ; not cross compiling
|
|
|
|
|
'())))
|
|
|
|
|
|
2018-03-29 11:54:53 -04:00
|
|
|
|
;; Tell 'ld-wrapper' to disallow non-store libraries.
|
|
|
|
|
(setenv "GUIX_LD_WRAPPER_ALLOW_IMPURITIES" "no")
|
|
|
|
|
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
;; When cross building, $PATH must refer only to native (host) inputs since
|
|
|
|
|
;; target inputs are not executable.
|
2013-03-30 17:56:38 -04:00
|
|
|
|
(set-path-environment-variable "PATH" '("bin" "sbin")
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(append native-input-directories
|
|
|
|
|
(if target
|
|
|
|
|
'()
|
|
|
|
|
input-directories)))
|
2012-07-07 12:40:39 -04:00
|
|
|
|
|
2013-03-30 17:56:38 -04:00
|
|
|
|
(for-each (match-lambda
|
2014-12-27 16:55:34 -05:00
|
|
|
|
((env-var (files ...) separator type pattern)
|
2014-12-27 06:16:18 -05:00
|
|
|
|
(set-path-environment-variable env-var files
|
2013-03-30 17:56:38 -04:00
|
|
|
|
input-directories
|
2014-12-27 06:16:18 -05:00
|
|
|
|
#:separator separator
|
2014-12-27 16:55:34 -05:00
|
|
|
|
#:type type
|
|
|
|
|
#:pattern pattern)))
|
2013-03-30 17:56:38 -04:00
|
|
|
|
search-paths)
|
2012-09-06 16:58:43 -04:00
|
|
|
|
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(when native-search-paths
|
|
|
|
|
;; Search paths for native inputs, when cross building.
|
|
|
|
|
(for-each (match-lambda
|
2014-12-27 16:55:34 -05:00
|
|
|
|
((env-var (files ...) separator type pattern)
|
2014-12-27 06:16:18 -05:00
|
|
|
|
(set-path-environment-variable env-var files
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
native-input-directories
|
2014-12-27 06:16:18 -05:00
|
|
|
|
#:separator separator
|
2014-12-27 16:55:34 -05:00
|
|
|
|
#:type type
|
|
|
|
|
#:pattern pattern)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
native-search-paths)))
|
2012-06-13 11:03:34 -04:00
|
|
|
|
|
2015-02-26 17:36:55 -05:00
|
|
|
|
(define* (install-locale #:key
|
2015-10-03 14:12:59 -04:00
|
|
|
|
(locale "en_US.utf8")
|
2015-02-26 17:36:55 -05:00
|
|
|
|
(locale-category LC_ALL)
|
|
|
|
|
#:allow-other-keys)
|
|
|
|
|
"Try to install LOCALE; emit a warning if that fails. The main goal is to
|
|
|
|
|
use a UTF-8 locale so that Guile correctly interprets UTF-8 file names.
|
|
|
|
|
|
|
|
|
|
This phase must typically happen after 'set-paths' so that $LOCPATH has a
|
|
|
|
|
chance to be set."
|
|
|
|
|
(catch 'system-error
|
|
|
|
|
(lambda ()
|
|
|
|
|
(setlocale locale-category locale)
|
2015-02-27 08:54:00 -05:00
|
|
|
|
|
|
|
|
|
;; While we're at it, pass it to sub-processes.
|
|
|
|
|
(setenv (locale-category->string locale-category) locale)
|
|
|
|
|
|
|
|
|
|
(format (current-error-port) "using '~a' locale for category ~s~%"
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
locale (locale-category->string locale-category)))
|
2015-02-26 17:36:55 -05:00
|
|
|
|
(lambda args
|
|
|
|
|
;; This is known to fail for instance in early bootstrap where locales
|
|
|
|
|
;; are not available.
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
"warning: failed to install '~a' locale: ~a~%"
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
locale (strerror (system-error-errno args))))))
|
2015-02-26 17:36:55 -05:00
|
|
|
|
|
2012-06-16 10:56:47 -04:00
|
|
|
|
(define* (unpack #:key source #:allow-other-keys)
|
2014-02-21 18:34:49 -05:00
|
|
|
|
"Unpack SOURCE in the working directory, and change directory within the
|
|
|
|
|
source. When SOURCE is a directory, copy it in a sub-directory of the current
|
|
|
|
|
working directory."
|
|
|
|
|
(if (file-is-directory? source)
|
|
|
|
|
(begin
|
|
|
|
|
(mkdir "source")
|
|
|
|
|
(chdir "source")
|
2014-04-13 18:08:54 -04:00
|
|
|
|
|
|
|
|
|
;; Preserve timestamps (set to the Epoch) on the copied tree so that
|
|
|
|
|
;; things work deterministically.
|
|
|
|
|
(copy-recursively source "."
|
2021-02-04 16:15:21 -05:00
|
|
|
|
#:keep-mtime? #t)
|
|
|
|
|
;; Make the source checkout files writable, for convenience.
|
|
|
|
|
(for-each (lambda (f)
|
|
|
|
|
(false-if-exception (make-file-writable f)))
|
|
|
|
|
(find-files ".")))
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(begin
|
build-systems/gnu: Allow unpacking/repacking more kind of files.
Before this change, only plain directories, tar or zip archives were supported
as the source of a package for the GNU build system; anything else would cause
the unpack phase to fail. Origins relying on snippets would suffer from the
same problem.
This change adds the support to use files of the following extensions: .gz,
.Z, .bz2, .lz, and .xz, even when they are not tarballs. Files of unknown
extensions are treated as uncompressed files and supported as well.
* guix/packages.scm (patch-and-repack): Only add the compressor utility to the
PATH when the file is compressed. Bind more inputs in the mlet, and use them
for decompressing single files. Adjust the decompression and compression
routines.
[decompression-type]: Remove nested variable.
* guix/build/utils.scm (compressor, tarball?): New procedures. Move
%xz-parallel-args to the new 'compression helpers' section.
* tests/packages.scm: Add tests. Add missing copyright year for Jan.
* guix/build/gnu-build-system.scm (first-subdirectory): Return #f when no
sub-directory was found.
(unpack): Support more file types, including uncompressed plain files.
2021-01-18 11:51:21 -05:00
|
|
|
|
(cond
|
|
|
|
|
((string-suffix? ".zip" source)
|
|
|
|
|
(invoke "unzip" source))
|
|
|
|
|
((tarball? source)
|
|
|
|
|
(invoke "tar" "xvf" source))
|
|
|
|
|
(else
|
|
|
|
|
(let ((name (strip-store-file-name source))
|
|
|
|
|
(command (compressor source)))
|
|
|
|
|
(copy-file source name)
|
|
|
|
|
(when command
|
|
|
|
|
(invoke command "--decompress" name)))))
|
|
|
|
|
;; Attempt to change into child directory.
|
2021-02-04 16:15:21 -05:00
|
|
|
|
(and=> (first-subdirectory ".") chdir))))
|
2012-06-16 10:56:47 -04:00
|
|
|
|
|
2021-04-08 16:43:00 -04:00
|
|
|
|
(define %bootstrap-scripts
|
|
|
|
|
;; Typical names of Autotools "bootstrap" scripts.
|
|
|
|
|
'("bootstrap" "bootstrap.sh" "autogen.sh"))
|
|
|
|
|
|
|
|
|
|
(define* (bootstrap #:key (bootstrap-scripts %bootstrap-scripts)
|
2018-03-11 16:46:30 -04:00
|
|
|
|
#:allow-other-keys)
|
|
|
|
|
"If the code uses Autotools and \"configure\" is missing, run
|
|
|
|
|
\"autoreconf\". Otherwise do nothing."
|
|
|
|
|
;; Note: Run that right after 'unpack' so that the generated files are
|
|
|
|
|
;; visible when the 'patch-source-shebangs' phase runs.
|
2019-10-07 11:55:03 -04:00
|
|
|
|
(define (script-exists? file)
|
|
|
|
|
(and (file-exists? file)
|
|
|
|
|
(not (file-is-directory? file))))
|
|
|
|
|
|
|
|
|
|
(if (not (script-exists? "configure"))
|
2018-03-11 16:46:30 -04:00
|
|
|
|
|
|
|
|
|
;; First try one of the BOOTSTRAP-SCRIPTS. If none exists, and it's
|
|
|
|
|
;; clearly an Autoconf-based project, run 'autoreconf'. Otherwise, do
|
|
|
|
|
;; nothing (perhaps the user removed or overrode the 'configure' phase.)
|
2019-10-07 11:55:03 -04:00
|
|
|
|
(let ((script (find script-exists? bootstrap-scripts)))
|
2018-03-11 16:46:30 -04:00
|
|
|
|
;; GNU packages often invoke the 'git-version-gen' script from
|
|
|
|
|
;; 'configure.ac' so make sure it has a valid shebang.
|
|
|
|
|
(false-if-file-not-found
|
|
|
|
|
(patch-shebang "build-aux/git-version-gen"))
|
|
|
|
|
|
|
|
|
|
(if script
|
|
|
|
|
(let ((script (string-append "./" script)))
|
2020-02-16 11:45:37 -05:00
|
|
|
|
(setenv "NOCONFIGURE" "true")
|
2018-03-11 16:46:30 -04:00
|
|
|
|
(format #t "running '~a'~%" script)
|
|
|
|
|
(if (executable-file? script)
|
|
|
|
|
(begin
|
|
|
|
|
(patch-shebang script)
|
|
|
|
|
(invoke script))
|
2020-02-16 11:45:37 -05:00
|
|
|
|
(invoke "sh" script))
|
|
|
|
|
;; Let's clean up after ourselves.
|
|
|
|
|
(unsetenv "NOCONFIGURE"))
|
2018-03-11 16:46:30 -04:00
|
|
|
|
(if (or (file-exists? "configure.ac")
|
|
|
|
|
(file-exists? "configure.in"))
|
|
|
|
|
(invoke "autoreconf" "-vif")
|
|
|
|
|
(format #t "no 'configure.ac' or anything like that, \
|
|
|
|
|
doing nothing~%"))))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(format #t "GNU build system bootstrapping not needed~%")))
|
2018-03-11 16:46:30 -04:00
|
|
|
|
|
2014-08-21 11:30:08 -04:00
|
|
|
|
;; See <http://bugs.gnu.org/17840>.
|
|
|
|
|
(define* (patch-usr-bin-file #:key native-inputs inputs
|
|
|
|
|
(patch-/usr/bin/file? #t)
|
|
|
|
|
#:allow-other-keys)
|
2015-01-09 16:35:33 -05:00
|
|
|
|
"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."
|
2014-08-21 11:30:08 -04:00
|
|
|
|
(when patch-/usr/bin/file?
|
2015-01-09 16:35:33 -05:00
|
|
|
|
(for-each (lambda (file)
|
|
|
|
|
(when (executable-file? file)
|
|
|
|
|
(patch-/usr/bin/file file)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(find-files "." "^configure$"))))
|
2014-08-21 11:30:08 -04:00
|
|
|
|
|
2012-12-15 10:35:26 -05:00
|
|
|
|
(define* (patch-source-shebangs #:key source #:allow-other-keys)
|
2012-12-21 16:31:25 -05:00
|
|
|
|
"Patch shebangs in all source files; this includes non-executable
|
|
|
|
|
files such as `.in' templates. Most scripts honor $SHELL and
|
|
|
|
|
$CONFIG_SHELL, but some don't, such as `mkinstalldirs' or Automake's
|
|
|
|
|
`missing' script."
|
|
|
|
|
(for-each patch-shebang
|
2016-09-12 15:51:25 -04:00
|
|
|
|
(find-files "."
|
|
|
|
|
(lambda (file stat)
|
|
|
|
|
;; Filter out symlinks.
|
|
|
|
|
(eq? 'regular (stat:type stat)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
#:stat lstat)))
|
2012-12-21 16:31:25 -05:00
|
|
|
|
|
|
|
|
|
(define (patch-generated-file-shebangs . rest)
|
|
|
|
|
"Patch shebangs in generated files, including `SHELL' variables in
|
|
|
|
|
makefiles."
|
2016-09-12 15:51:25 -04:00
|
|
|
|
;; Patch executable regular files, some of which might have been generated
|
|
|
|
|
;; by `configure'.
|
2012-12-15 10:35:26 -05:00
|
|
|
|
(for-each patch-shebang
|
2016-09-12 15:51:25 -04:00
|
|
|
|
(find-files "."
|
|
|
|
|
(lambda (file stat)
|
|
|
|
|
(and (eq? 'regular (stat:type stat))
|
|
|
|
|
(not (zero? (logand (stat:mode stat) #o100)))))
|
|
|
|
|
#:stat lstat))
|
2012-12-15 10:35:26 -05:00
|
|
|
|
|
2012-12-21 16:31:25 -05:00
|
|
|
|
;; Patch `SHELL' in generated makefiles.
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(for-each patch-makefile-SHELL (find-files "." "^(GNU)?[mM]akefile$")))
|
2012-12-20 17:06:34 -05:00
|
|
|
|
|
2015-07-13 18:54:40 -04:00
|
|
|
|
(define* (configure #:key build target native-inputs inputs outputs
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(configure-flags '()) out-of-source?
|
2012-08-23 17:13:41 -04:00
|
|
|
|
#:allow-other-keys)
|
2013-01-09 18:08:40 -05:00
|
|
|
|
(define (package-name)
|
|
|
|
|
(let* ((out (assoc-ref outputs "out"))
|
|
|
|
|
(base (basename out))
|
|
|
|
|
(dash (string-rindex base #\-)))
|
|
|
|
|
;; XXX: We'd rather use `package-name->name+version' or similar.
|
2013-04-27 11:27:16 -04:00
|
|
|
|
(string-drop (if dash
|
|
|
|
|
(substring base 0 dash)
|
|
|
|
|
base)
|
|
|
|
|
(+ 1 (string-index base #\-)))))
|
2013-01-09 18:08:40 -05:00
|
|
|
|
|
2012-07-01 11:32:03 -04:00
|
|
|
|
(let* ((prefix (assoc-ref outputs "out"))
|
2013-01-01 10:52:27 -05:00
|
|
|
|
(bindir (assoc-ref outputs "bin"))
|
2012-07-01 11:32:03 -04:00
|
|
|
|
(libdir (assoc-ref outputs "lib"))
|
|
|
|
|
(includedir (assoc-ref outputs "include"))
|
2013-01-09 18:08:40 -05:00
|
|
|
|
(docdir (assoc-ref outputs "doc"))
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(bash (or (and=> (assoc-ref (or native-inputs inputs) "bash")
|
2012-12-13 17:38:32 -05:00
|
|
|
|
(cut string-append <> "/bin/bash"))
|
|
|
|
|
"/bin/sh"))
|
2013-12-17 14:33:26 -05:00
|
|
|
|
(flags `(,@(if target ; cross building
|
|
|
|
|
'("CC_FOR_BUILD=gcc")
|
|
|
|
|
'())
|
|
|
|
|
,(string-append "CONFIG_SHELL=" bash)
|
2012-12-13 17:38:32 -05:00
|
|
|
|
,(string-append "SHELL=" bash)
|
|
|
|
|
,(string-append "--prefix=" prefix)
|
2012-07-01 11:32:03 -04:00
|
|
|
|
"--enable-fast-install" ; when using Libtool
|
|
|
|
|
|
|
|
|
|
;; Produce multiple outputs when specific output names
|
|
|
|
|
;; are recognized.
|
2013-01-01 10:52:27 -05:00
|
|
|
|
,@(if bindir
|
|
|
|
|
(list (string-append "--bindir=" bindir "/bin"))
|
|
|
|
|
'())
|
2012-07-01 11:32:03 -04:00
|
|
|
|
,@(if libdir
|
2013-01-09 18:08:40 -05:00
|
|
|
|
(cons (string-append "--libdir=" libdir "/lib")
|
|
|
|
|
(if includedir
|
|
|
|
|
'()
|
|
|
|
|
(list
|
|
|
|
|
(string-append "--includedir="
|
|
|
|
|
libdir "/include"))))
|
2012-07-01 11:32:03 -04:00
|
|
|
|
'())
|
|
|
|
|
,@(if includedir
|
|
|
|
|
(list (string-append "--includedir="
|
|
|
|
|
includedir "/include"))
|
|
|
|
|
'())
|
2013-01-09 18:08:40 -05:00
|
|
|
|
,@(if docdir
|
|
|
|
|
(list (string-append "--docdir=" docdir
|
2014-02-10 15:35:30 -05:00
|
|
|
|
"/share/doc/" (package-name)))
|
2013-01-09 18:08:40 -05:00
|
|
|
|
'())
|
2015-07-13 18:54:40 -04:00
|
|
|
|
,@(if build
|
|
|
|
|
(list (string-append "--build=" build))
|
|
|
|
|
'())
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
,@(if target ; cross building
|
|
|
|
|
(list (string-append "--host=" target))
|
|
|
|
|
'())
|
2012-08-23 17:13:41 -04:00
|
|
|
|
,@configure-flags))
|
2012-08-30 17:30:42 -04:00
|
|
|
|
(abs-srcdir (getcwd))
|
|
|
|
|
(srcdir (if out-of-source?
|
|
|
|
|
(string-append "../" (basename abs-srcdir))
|
|
|
|
|
".")))
|
|
|
|
|
(format #t "source directory: ~s (relative from build: ~s)~%"
|
|
|
|
|
abs-srcdir srcdir)
|
2012-08-23 17:13:41 -04:00
|
|
|
|
(if out-of-source?
|
|
|
|
|
(begin
|
|
|
|
|
(mkdir "../build")
|
|
|
|
|
(chdir "../build")))
|
|
|
|
|
(format #t "build directory: ~s~%" (getcwd))
|
2012-07-01 11:32:03 -04:00
|
|
|
|
(format #t "configure flags: ~s~%" flags)
|
2012-08-30 17:30:42 -04:00
|
|
|
|
|
2012-12-13 17:38:32 -05:00
|
|
|
|
;; Use BASH to reduce reliance on /bin/sh since it may not always be
|
|
|
|
|
;; reliable (see
|
|
|
|
|
;; <http://thread.gmane.org/gmane.linux.distributions.nixos/9748>
|
|
|
|
|
;; for a summary of the situation.)
|
|
|
|
|
;;
|
2012-08-30 17:30:42 -04:00
|
|
|
|
;; Call `configure' with a relative path. Otherwise, GCC's build system
|
|
|
|
|
;; (for instance) records absolute source file names, which typically
|
|
|
|
|
;; contain the hash part of the `.drv' file, leading to a reference leak.
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(apply invoke bash
|
|
|
|
|
(string-append srcdir "/configure")
|
|
|
|
|
flags)))
|
2012-06-13 11:03:34 -04:00
|
|
|
|
|
2012-07-07 10:49:23 -04:00
|
|
|
|
(define* (build #:key (make-flags '()) (parallel-build? #t)
|
|
|
|
|
#:allow-other-keys)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(apply invoke "make"
|
|
|
|
|
`(,@(if parallel-build?
|
|
|
|
|
`("-j" ,(number->string (parallel-job-count)))
|
|
|
|
|
'())
|
|
|
|
|
,@make-flags)))
|
2012-06-16 10:56:47 -04:00
|
|
|
|
|
2018-03-19 05:50:05 -04:00
|
|
|
|
(define* (dump-file-contents directory file-regexp
|
|
|
|
|
#:optional (port (current-error-port)))
|
|
|
|
|
"Dump to PORT the contents of files in DIRECTORY that match FILE-REGEXP."
|
|
|
|
|
(define (dump file)
|
|
|
|
|
(let ((prefix (string-append "\n--- " file " ")))
|
|
|
|
|
(display (if (< (string-length prefix) 78)
|
2018-03-20 12:01:41 -04:00
|
|
|
|
(string-pad-right prefix 78 #\-)
|
2018-03-19 05:50:05 -04:00
|
|
|
|
prefix)
|
|
|
|
|
port)
|
|
|
|
|
(display "\n\n" port)
|
|
|
|
|
(call-with-input-file file
|
|
|
|
|
(lambda (log)
|
|
|
|
|
(dump-port log port)))
|
|
|
|
|
(display "\n" port)))
|
|
|
|
|
|
|
|
|
|
(for-each dump (find-files directory file-regexp)))
|
|
|
|
|
|
|
|
|
|
(define %test-suite-log-regexp
|
|
|
|
|
;; Name of test suite log files as commonly found in GNU-based build systems
|
|
|
|
|
;; and CMake.
|
|
|
|
|
"^(test-?suite\\.log|LastTestFailed\\.log)$")
|
|
|
|
|
|
2013-06-22 10:15:23 -04:00
|
|
|
|
(define* (check #:key target (make-flags '()) (tests? (not target))
|
|
|
|
|
(test-target "check") (parallel-tests? #t)
|
2018-03-19 05:50:05 -04:00
|
|
|
|
(test-suite-log-regexp %test-suite-log-regexp)
|
2012-07-01 11:32:03 -04:00
|
|
|
|
#:allow-other-keys)
|
|
|
|
|
(if tests?
|
2018-03-19 05:50:05 -04:00
|
|
|
|
(guard (c ((invoke-error? c)
|
|
|
|
|
;; Dump the test suite log to facilitate debugging.
|
|
|
|
|
(display "\nTest suite failed, dumping logs.\n"
|
|
|
|
|
(current-error-port))
|
|
|
|
|
(dump-file-contents "." test-suite-log-regexp)
|
|
|
|
|
(raise c)))
|
|
|
|
|
(apply invoke "make" test-target
|
|
|
|
|
`(,@(if parallel-tests?
|
|
|
|
|
`("-j" ,(number->string (parallel-job-count)))
|
|
|
|
|
'())
|
|
|
|
|
,@make-flags)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(format #t "test suite not run~%")))
|
2012-06-16 10:56:47 -04:00
|
|
|
|
|
|
|
|
|
(define* (install #:key (make-flags '()) #:allow-other-keys)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(apply invoke "make" "install" make-flags))
|
2012-06-16 10:56:47 -04:00
|
|
|
|
|
2015-01-04 12:16:16 -05:00
|
|
|
|
(define* (patch-shebangs #:key inputs outputs (patch-shebangs? #t)
|
2012-08-19 11:54:54 -04:00
|
|
|
|
#:allow-other-keys)
|
|
|
|
|
(define (list-of-files dir)
|
|
|
|
|
(map (cut string-append dir "/" <>)
|
|
|
|
|
(or (scandir dir (lambda (f)
|
2016-02-06 09:59:51 -05:00
|
|
|
|
(let ((s (lstat (string-append dir "/" f))))
|
2012-08-19 11:54:54 -04:00
|
|
|
|
(eq? 'regular (stat:type s)))))
|
|
|
|
|
'())))
|
|
|
|
|
|
2015-01-04 12:16:16 -05:00
|
|
|
|
(define bin-directories
|
|
|
|
|
(match-lambda
|
|
|
|
|
((_ . dir)
|
|
|
|
|
(list (string-append dir "/bin")
|
2021-06-30 09:10:28 -04:00
|
|
|
|
(string-append dir "/sbin")
|
|
|
|
|
(string-append dir "/libexec")))))
|
2015-01-04 12:16:16 -05:00
|
|
|
|
|
|
|
|
|
(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))
|
2012-08-19 11:54:54 -04:00
|
|
|
|
|
2012-08-31 17:58:21 -04:00
|
|
|
|
(when patch-shebangs?
|
2015-01-04 12:16:16 -05:00
|
|
|
|
(let ((path (append output-bindirs input-bindirs)))
|
2012-08-31 17:58:21 -04:00
|
|
|
|
(for-each (lambda (dir)
|
|
|
|
|
(let ((files (list-of-files dir)))
|
|
|
|
|
(for-each (cut patch-shebang <> path) files)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
output-bindirs))))
|
2012-08-19 11:54:54 -04:00
|
|
|
|
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(define* (strip #:key target outputs (strip-binaries? #t)
|
|
|
|
|
(strip-command (if target
|
|
|
|
|
(string-append target "-strip")
|
|
|
|
|
"strip"))
|
2013-07-03 17:53:31 -04:00
|
|
|
|
(objcopy-command (if target
|
|
|
|
|
(string-append target "-objcopy")
|
|
|
|
|
"objcopy"))
|
2020-07-26 19:38:50 -04:00
|
|
|
|
(strip-flags '("--strip-unneeded"
|
2015-12-31 18:49:05 -05:00
|
|
|
|
"--enable-deterministic-archives"))
|
2012-08-31 11:04:53 -04:00
|
|
|
|
(strip-directories '("lib" "lib64" "libexec"
|
|
|
|
|
"bin" "sbin"))
|
|
|
|
|
#:allow-other-keys)
|
2013-07-03 17:53:31 -04:00
|
|
|
|
(define debug-output
|
|
|
|
|
;; If an output is called "debug", then that's where debugging information
|
|
|
|
|
;; will be stored instead of being discarded.
|
|
|
|
|
(assoc-ref outputs "debug"))
|
|
|
|
|
|
|
|
|
|
(define debug-file-extension
|
|
|
|
|
;; File name extension for debugging information.
|
|
|
|
|
".debug")
|
|
|
|
|
|
|
|
|
|
(define (debug-file file)
|
|
|
|
|
;; Return the name of the debug file for FILE, an absolute file name.
|
|
|
|
|
;; Once installed in the user's profile, it is in $PROFILE/lib/debug/FILE,
|
|
|
|
|
;; which is where GDB looks for it (info "(gdb) Separate Debug Files").
|
|
|
|
|
(string-append debug-output "/lib/debug/"
|
|
|
|
|
file debug-file-extension))
|
|
|
|
|
|
|
|
|
|
(define (make-debug-file file)
|
|
|
|
|
;; Create a file in DEBUG-OUTPUT containing the debugging info of FILE.
|
|
|
|
|
(let ((debug (debug-file file)))
|
|
|
|
|
(mkdir-p (dirname debug))
|
|
|
|
|
(copy-file file debug)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(invoke strip-command "--only-keep-debug" debug)
|
|
|
|
|
(chmod debug #o400)))
|
2013-07-03 17:53:31 -04:00
|
|
|
|
|
|
|
|
|
(define (add-debug-link file)
|
|
|
|
|
;; Add a debug link in FILE (info "(binutils) strip").
|
|
|
|
|
|
|
|
|
|
;; `objcopy --add-gnu-debuglink' wants to have the target of the debug
|
|
|
|
|
;; link around so it can compute a CRC of that file (see the
|
|
|
|
|
;; `bfd_fill_in_gnu_debuglink_section' function.) No reference to
|
|
|
|
|
;; DEBUG-OUTPUT is kept because bfd keeps only the basename of the debug
|
|
|
|
|
;; file.
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(invoke objcopy-command "--enable-deterministic-archives"
|
|
|
|
|
(string-append "--add-gnu-debuglink="
|
|
|
|
|
(debug-file file))
|
|
|
|
|
file))
|
2013-07-03 17:53:31 -04:00
|
|
|
|
|
2012-08-31 11:04:53 -04:00
|
|
|
|
(define (strip-dir dir)
|
build-system/gnu: Unify with (guix build-system gnu-cross-build).
* guix/build/gnu-build-system.scm (set-paths): Add `native-inputs' and
`native-search-paths' keyword parameters. Honor them.
(configure): Add `target' and `native-inputs' keyword parameters.
Look for Bash in NATIVE-INPUTS or INPUTS. Pass `--host' when TARGET
is true.
(strip): Add `strip-command' keyword parameter. Use it.
* guix/build/gnu-cross-build.scm: Remove.
* Makefile.am (MODULES): Adjust accordingly.
* gnu/packages/acl.scm, gnu/packages/attr.scm, gnu/packages/base.scm,
gnu/packages/bash.scm, gnu/packages/gawk.scm,
gnu/packages/gettext.scm, gnu/packages/guile.scm,
gnu/packages/libffi.scm, gnu/packages/libsigsegv.scm,
gnu/packages/linux.scm, gnu/packages/ncurses.scm,
gnu/packages/readline.scm, guix/build-system/gnu.scm: Replace
`%standard-cross-phases' by `%standard-phases'. Remove references
to (guix build gnu-cross-build).
2013-06-20 18:25:54 -04:00
|
|
|
|
(format #t "stripping binaries in ~s with ~s and flags ~s~%"
|
|
|
|
|
dir strip-command strip-flags)
|
2013-07-03 17:53:31 -04:00
|
|
|
|
(when debug-output
|
|
|
|
|
(format #t "debugging output written to ~s using ~s~%"
|
|
|
|
|
debug-output objcopy-command))
|
2016-09-01 17:48:08 -04:00
|
|
|
|
|
|
|
|
|
(for-each (lambda (file)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(when (or (elf-file? file) (ar-file? file))
|
2018-03-16 18:33:52 -04:00
|
|
|
|
;; If an error occurs while processing a file, issue a
|
|
|
|
|
;; warning and continue to the next file.
|
|
|
|
|
(guard (c ((invoke-error? c)
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
"warning: ~a: program ~s exited\
|
|
|
|
|
~@[ with non-zero exit status ~a~]\
|
|
|
|
|
~@[ terminated by signal ~a~]~%"
|
|
|
|
|
file
|
|
|
|
|
(invoke-error-program c)
|
|
|
|
|
(invoke-error-exit-status c)
|
|
|
|
|
(invoke-error-term-signal c))))
|
|
|
|
|
(when debug-output
|
|
|
|
|
(make-debug-file file))
|
|
|
|
|
|
|
|
|
|
;; Ensure the file is writable.
|
|
|
|
|
(make-file-writable file)
|
|
|
|
|
|
|
|
|
|
(apply invoke strip-command
|
|
|
|
|
(append strip-flags (list file)))
|
|
|
|
|
|
|
|
|
|
(when debug-output
|
|
|
|
|
(add-debug-link file)))))
|
2017-01-26 05:27:11 -05:00
|
|
|
|
(find-files dir
|
|
|
|
|
(lambda (file stat)
|
|
|
|
|
;; Ignore symlinks such as:
|
|
|
|
|
;; libfoo.so -> libfoo.so.0.0.
|
|
|
|
|
(eq? 'regular (stat:type stat)))
|
|
|
|
|
#:stat lstat)))
|
2012-08-31 11:04:53 -04:00
|
|
|
|
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(when strip-binaries?
|
|
|
|
|
(for-each
|
|
|
|
|
strip-dir
|
|
|
|
|
(append-map (match-lambda
|
|
|
|
|
((_ . dir)
|
|
|
|
|
(filter-map (lambda (d)
|
|
|
|
|
(let ((sub (string-append dir "/" d)))
|
|
|
|
|
(and (directory-exists? sub) sub)))
|
|
|
|
|
strip-directories)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
outputs))))
|
2012-08-31 11:04:53 -04:00
|
|
|
|
|
2015-04-01 10:47:49 -04:00
|
|
|
|
(define* (validate-runpath #:key
|
2015-04-23 12:50:37 -04:00
|
|
|
|
(validate-runpath? #t)
|
2015-04-01 10:47:49 -04:00
|
|
|
|
(elf-directories '("lib" "lib64" "libexec"
|
|
|
|
|
"bin" "sbin"))
|
|
|
|
|
outputs #:allow-other-keys)
|
|
|
|
|
"When VALIDATE-RUNPATH? is true, validate that all the ELF files in
|
|
|
|
|
ELF-DIRECTORIES have their dependencies found in their 'RUNPATH'.
|
|
|
|
|
|
|
|
|
|
Since the ELF parser needs to have a copy of files in memory, better run this
|
|
|
|
|
phase after stripping."
|
|
|
|
|
(define (sub-directory parent)
|
|
|
|
|
(lambda (directory)
|
|
|
|
|
(let ((directory (string-append parent "/" directory)))
|
|
|
|
|
(and (directory-exists? directory) directory))))
|
|
|
|
|
|
|
|
|
|
(define (validate directory)
|
|
|
|
|
(define (file=? file1 file2)
|
|
|
|
|
(let ((st1 (stat file1))
|
|
|
|
|
(st2 (stat file2)))
|
|
|
|
|
(= (stat:ino st1) (stat:ino st2))))
|
|
|
|
|
|
|
|
|
|
;; There are always symlinks from '.so' to '.so.1' and so on, so delete
|
|
|
|
|
;; duplicates.
|
|
|
|
|
(let ((files (delete-duplicates (find-files directory (lambda (file stat)
|
|
|
|
|
(elf-file? file)))
|
|
|
|
|
file=?)))
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
"validating RUNPATH of ~a binaries in ~s...~%"
|
|
|
|
|
(length files) directory)
|
|
|
|
|
(every* validate-needed-in-runpath files)))
|
|
|
|
|
|
|
|
|
|
(if validate-runpath?
|
|
|
|
|
(let ((dirs (append-map (match-lambda
|
|
|
|
|
(("debug" . _)
|
|
|
|
|
;; The "debug" output is full of ELF files
|
|
|
|
|
;; that are not worth checking.
|
|
|
|
|
'())
|
|
|
|
|
((name . output)
|
|
|
|
|
(filter-map (sub-directory output)
|
|
|
|
|
elf-directories)))
|
|
|
|
|
outputs)))
|
2018-03-16 06:04:38 -04:00
|
|
|
|
(unless (every* validate dirs)
|
|
|
|
|
(error "RUNPATH validation failed")))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(format (current-error-port) "skipping RUNPATH validation~%")))
|
2015-04-01 10:47:49 -04:00
|
|
|
|
|
2014-12-01 08:09:36 -05:00
|
|
|
|
(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) ...)
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(for-each validate-output directories))))
|
2014-12-01 08:09:36 -05:00
|
|
|
|
|
2017-01-26 16:05:49 -05:00
|
|
|
|
(define* (reset-gzip-timestamps #:key outputs #:allow-other-keys)
|
|
|
|
|
"Reset embedded timestamps in gzip files found in OUTPUTS."
|
|
|
|
|
(define (process-directory directory)
|
|
|
|
|
(let ((files (find-files directory
|
|
|
|
|
(lambda (file stat)
|
|
|
|
|
(and (eq? 'regular (stat:type stat))
|
|
|
|
|
(or (string-suffix? ".gz" file)
|
|
|
|
|
(string-suffix? ".tgz" file))
|
|
|
|
|
(gzip-file? file)))
|
|
|
|
|
#:stat lstat)))
|
2021-07-25 02:12:04 -04:00
|
|
|
|
;; Ensure the files are writable.
|
|
|
|
|
(for-each make-file-writable files)
|
2017-01-26 16:05:49 -05:00
|
|
|
|
(for-each reset-gzip-timestamp files)))
|
|
|
|
|
|
|
|
|
|
(match outputs
|
|
|
|
|
(((names . directories) ...)
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(for-each process-directory directories))))
|
2017-01-26 16:05:49 -05:00
|
|
|
|
|
2014-12-01 09:46:26 -05:00
|
|
|
|
(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)
|
2020-12-28 22:03:23 -05:00
|
|
|
|
(string-append link compressed-documentation-extension))))
|
2014-12-01 09:46:26 -05:00
|
|
|
|
|
|
|
|
|
(define (has-links? file)
|
|
|
|
|
;; Return #t if FILE has hard links.
|
|
|
|
|
(> (stat:nlink (lstat file)) 1))
|
|
|
|
|
|
2017-04-24 12:46:05 -04:00
|
|
|
|
(define (points-to-symlink? symlink)
|
|
|
|
|
;; Return #t if SYMLINK points to another symbolic link.
|
|
|
|
|
(let* ((target (readlink symlink))
|
|
|
|
|
(target-absolute (if (string-prefix? "/" target)
|
|
|
|
|
target
|
|
|
|
|
(string-append (dirname symlink)
|
|
|
|
|
"/" target))))
|
|
|
|
|
(catch 'system-error
|
|
|
|
|
(lambda ()
|
|
|
|
|
(symbolic-link? target-absolute))
|
|
|
|
|
(lambda args
|
|
|
|
|
(if (= ENOENT (system-error-errno args))
|
|
|
|
|
(begin
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
"The symbolic link '~a' target is missing: '~a'\n"
|
|
|
|
|
symlink target-absolute)
|
|
|
|
|
#f)
|
|
|
|
|
(apply throw args))))))
|
|
|
|
|
|
2014-12-01 09:46:26 -05:00
|
|
|
|
(define (maybe-compress-directory directory regexp)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(when (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.)
|
|
|
|
|
;; Also, do not retarget symbolic links pointing to other
|
|
|
|
|
;; symbolic links, since these are not compressed.
|
|
|
|
|
(for-each retarget-symlink
|
|
|
|
|
(filter (lambda (symlink)
|
|
|
|
|
(and (not (points-to-symlink? symlink))
|
|
|
|
|
(string-match regexp symlink)))
|
|
|
|
|
symlinks))
|
|
|
|
|
(apply invoke documentation-compressor
|
|
|
|
|
(append documentation-compressor-flags
|
|
|
|
|
(remove has-links? regular-files)))))))))
|
2014-12-01 09:46:26 -05:00
|
|
|
|
|
|
|
|
|
(define (maybe-compress output)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(maybe-compress-directory (string-append output "/share/man")
|
|
|
|
|
"\\.[0-9]+$")
|
|
|
|
|
(maybe-compress-directory (string-append output "/share/info")
|
|
|
|
|
"\\.info(-[0-9]+)?$"))
|
2014-12-01 09:46:26 -05:00
|
|
|
|
|
|
|
|
|
(if compress-documentation?
|
|
|
|
|
(match outputs
|
|
|
|
|
(((names . directories) ...)
|
2018-03-16 03:03:25 -04:00
|
|
|
|
(for-each maybe-compress directories)))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(format #t "not compressing documentation~%")))
|
2014-12-01 09:46:26 -05:00
|
|
|
|
|
2015-04-05 15:59:18 -04:00
|
|
|
|
(define* (delete-info-dir-file #:key outputs #:allow-other-keys)
|
2015-04-06 04:47:31 -04:00
|
|
|
|
"Delete any 'share/info/dir' file from OUTPUTS."
|
2015-04-05 15:59:18 -04:00
|
|
|
|
(for-each (match-lambda
|
|
|
|
|
((output . directory)
|
|
|
|
|
(let ((info-dir-file (string-append directory "/share/info/dir")))
|
|
|
|
|
(when (file-exists? info-dir-file)
|
|
|
|
|
(delete-file info-dir-file)))))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
outputs))
|
2015-04-05 15:59:18 -04:00
|
|
|
|
|
2016-09-25 01:43:21 -04:00
|
|
|
|
|
|
|
|
|
(define* (patch-dot-desktop-files #:key outputs inputs #:allow-other-keys)
|
|
|
|
|
"Replace any references to executables in '.desktop' files with their
|
|
|
|
|
absolute file names."
|
|
|
|
|
(define bin-directories
|
|
|
|
|
(append-map (match-lambda
|
|
|
|
|
((_ . directory)
|
|
|
|
|
(list (string-append directory "/bin")
|
|
|
|
|
(string-append directory "/sbin"))))
|
|
|
|
|
outputs))
|
|
|
|
|
|
|
|
|
|
(define (which program)
|
|
|
|
|
(or (search-path bin-directories program)
|
|
|
|
|
(begin
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
"warning: '.desktop' file refers to '~a', \
|
|
|
|
|
which cannot be found~%"
|
|
|
|
|
program)
|
|
|
|
|
program)))
|
|
|
|
|
|
|
|
|
|
(for-each (match-lambda
|
|
|
|
|
((_ . directory)
|
|
|
|
|
(let ((applications (string-append directory
|
|
|
|
|
"/share/applications")))
|
|
|
|
|
(when (directory-exists? applications)
|
|
|
|
|
(let ((files (find-files applications "\\.desktop$")))
|
|
|
|
|
(format #t "adjusting ~a '.desktop' files in ~s~%"
|
|
|
|
|
(length files) applications)
|
|
|
|
|
|
|
|
|
|
;; '.desktop' files contain translations and are always
|
|
|
|
|
;; UTF-8-encoded.
|
|
|
|
|
(with-fluids ((%default-port-encoding "UTF-8"))
|
|
|
|
|
(substitute* files
|
|
|
|
|
(("^Exec=([^/[:blank:]\r\n]*)(.*)$" _ binary rest)
|
|
|
|
|
(string-append "Exec=" (which binary) rest))
|
|
|
|
|
(("^TryExec=([^/[:blank:]\r\n]*)(.*)$" _ binary rest)
|
|
|
|
|
(string-append "TryExec="
|
|
|
|
|
(which binary) rest)))))))))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
outputs))
|
2016-09-25 01:43:21 -04:00
|
|
|
|
|
2020-11-27 02:55:54 -05:00
|
|
|
|
(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~%")))
|
|
|
|
|
|
2017-11-05 15:32:02 -05:00
|
|
|
|
(define %license-file-regexp
|
|
|
|
|
;; Regexp matching license files.
|
|
|
|
|
"^(COPYING.*|LICEN[CS]E.*|[Ll]icen[cs]e.*|Copy[Rr]ight(\\.(txt|md))?)$")
|
|
|
|
|
|
|
|
|
|
(define* (install-license-files #:key outputs
|
|
|
|
|
(license-file-regexp %license-file-regexp)
|
2019-03-09 09:08:11 -05:00
|
|
|
|
out-of-source?
|
2017-11-05 15:32:02 -05:00
|
|
|
|
#:allow-other-keys)
|
|
|
|
|
"Install license files matching LICENSE-FILE-REGEXP to 'share/doc'."
|
2019-03-09 09:08:11 -05:00
|
|
|
|
(define (find-source-directory package)
|
|
|
|
|
;; For an out-of-source build, guess the source directory location
|
|
|
|
|
;; relative to the current directory. Return #f on failure.
|
|
|
|
|
(match (scandir ".."
|
|
|
|
|
(lambda (file)
|
|
|
|
|
(and (not (member file '("." ".." "build")))
|
|
|
|
|
(file-is-directory?
|
|
|
|
|
(string-append "../" file)))))
|
|
|
|
|
(() ;hmm, no source
|
|
|
|
|
#f)
|
|
|
|
|
((source) ;only one other file
|
|
|
|
|
(string-append "../" source))
|
|
|
|
|
((directories ...) ;pick the most likely one
|
|
|
|
|
;; This happens for example with libstdc++, which lives within the GCC
|
|
|
|
|
;; source tree.
|
|
|
|
|
(any (lambda (directory)
|
|
|
|
|
(and (string-prefix? package directory)
|
|
|
|
|
(string-append "../" directory)))
|
|
|
|
|
directories))))
|
|
|
|
|
|
2019-03-10 17:16:14 -04:00
|
|
|
|
(define (copy-to-directories directories sub-directory)
|
|
|
|
|
(lambda (file)
|
|
|
|
|
(for-each (if (file-is-directory? file)
|
|
|
|
|
(cut copy-recursively file <>)
|
|
|
|
|
(cut install-file file <>))
|
|
|
|
|
(map (cut string-append <> "/" sub-directory)
|
|
|
|
|
directories))))
|
|
|
|
|
|
2017-11-05 15:32:02 -05:00
|
|
|
|
(let* ((regexp (make-regexp license-file-regexp))
|
|
|
|
|
(out (or (assoc-ref outputs "out")
|
|
|
|
|
(match outputs
|
|
|
|
|
(((_ . output) _ ...)
|
|
|
|
|
output))))
|
|
|
|
|
(package (strip-store-file-name out))
|
2019-03-10 17:16:14 -04:00
|
|
|
|
(outputs (match outputs
|
|
|
|
|
(((_ . outputs) ...)
|
|
|
|
|
outputs)))
|
2019-03-09 09:08:11 -05:00
|
|
|
|
(source (if out-of-source?
|
|
|
|
|
(find-source-directory
|
|
|
|
|
(package-name->name+version package))
|
|
|
|
|
"."))
|
|
|
|
|
(files (and source
|
|
|
|
|
(scandir source
|
|
|
|
|
(lambda (file)
|
|
|
|
|
(regexp-exec regexp file))))))
|
|
|
|
|
(if files
|
|
|
|
|
(begin
|
|
|
|
|
(format #t "installing ~a license files from '~a'~%"
|
|
|
|
|
(length files) source)
|
2019-03-10 17:16:14 -04:00
|
|
|
|
(for-each (copy-to-directories outputs
|
|
|
|
|
(string-append "share/doc/"
|
|
|
|
|
package))
|
2019-03-09 09:08:11 -05:00
|
|
|
|
(map (cut string-append source "/" <>) files)))
|
|
|
|
|
(format (current-error-port)
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
"failed to find license files~%"))))
|
2017-11-05 15:32:02 -05:00
|
|
|
|
|
2012-06-16 10:56:47 -04:00
|
|
|
|
(define %standard-phases
|
|
|
|
|
;; Standard build phases, as a list of symbol/procedure pairs.
|
|
|
|
|
(let-syntax ((phases (syntax-rules ()
|
|
|
|
|
((_ p ...) `((p . ,p) ...)))))
|
2016-01-05 09:49:48 -05:00
|
|
|
|
(phases set-SOURCE-DATE-EPOCH set-paths install-locale unpack
|
2018-03-11 16:46:30 -04:00
|
|
|
|
bootstrap
|
2014-08-21 11:30:08 -04:00
|
|
|
|
patch-usr-bin-file
|
2012-12-21 16:31:25 -05:00
|
|
|
|
patch-source-shebangs configure patch-generated-file-shebangs
|
2012-12-15 10:35:26 -05:00
|
|
|
|
build check install
|
2014-12-01 08:09:36 -05:00
|
|
|
|
patch-shebangs strip
|
2015-04-01 10:47:49 -04:00
|
|
|
|
validate-runpath
|
2014-12-01 09:46:26 -05:00
|
|
|
|
validate-documentation-location
|
2015-04-05 15:59:18 -04:00
|
|
|
|
delete-info-dir-file
|
2016-09-25 01:43:21 -04:00
|
|
|
|
patch-dot-desktop-files
|
2020-11-27 02:55:54 -05:00
|
|
|
|
make-dynamic-linker-cache
|
2017-11-05 15:32:02 -05:00
|
|
|
|
install-license-files
|
2017-01-26 16:05:49 -05:00
|
|
|
|
reset-gzip-timestamps
|
2014-12-01 09:46:26 -05:00
|
|
|
|
compress-documentation)))
|
2012-06-16 10:56:47 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define* (gnu-build #:key (source #f) (outputs #f) (inputs #f)
|
|
|
|
|
(phases %standard-phases)
|
|
|
|
|
#:allow-other-keys
|
|
|
|
|
#:rest args)
|
|
|
|
|
"Build from SOURCE to OUTPUTS, using INPUTS, and by running all of PHASES
|
|
|
|
|
in order. Return #t if all the PHASES succeeded, #f otherwise."
|
2015-08-30 08:08:44 -04:00
|
|
|
|
(define (elapsed-time end start)
|
|
|
|
|
(let ((diff (time-difference end start)))
|
|
|
|
|
(+ (time-second diff)
|
|
|
|
|
(/ (time-nanosecond diff) 1e9))))
|
|
|
|
|
|
2019-01-29 03:49:33 -05:00
|
|
|
|
(setvbuf (current-output-port) 'line)
|
|
|
|
|
(setvbuf (current-error-port) 'line)
|
2012-06-16 10:56:47 -04:00
|
|
|
|
|
2015-03-01 11:05:41 -05:00
|
|
|
|
;; Encoding/decoding errors shouldn't be silent.
|
|
|
|
|
(fluid-set! %default-port-conversion-strategy 'error)
|
2015-02-27 19:10:24 -05:00
|
|
|
|
|
2019-01-29 05:00:42 -05:00
|
|
|
|
(guard (c ((invoke-error? c)
|
|
|
|
|
(report-invoke-error c)
|
|
|
|
|
(exit 1)))
|
|
|
|
|
;; The trick is to #:allow-other-keys everywhere, so that each procedure in
|
|
|
|
|
;; PHASES can pick the keyword arguments it's interested in.
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(for-each (match-lambda
|
|
|
|
|
((name . proc)
|
|
|
|
|
(let ((start (current-time time-monotonic)))
|
2021-01-15 08:01:51 -05:00
|
|
|
|
(define (end-of-phase success?)
|
|
|
|
|
(let ((end (current-time time-monotonic)))
|
|
|
|
|
(format #t "phase `~a' ~:[failed~;succeeded~] after ~,1f seconds~%"
|
|
|
|
|
name success?
|
|
|
|
|
(elapsed-time end start))
|
|
|
|
|
|
|
|
|
|
;; Dump the environment variables as a shell script,
|
|
|
|
|
;; for handy debugging.
|
|
|
|
|
(system "export > $NIX_BUILD_TOP/environment-variables")))
|
|
|
|
|
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
(format #t "starting phase `~a'~%" name)
|
2021-01-15 08:01:51 -05:00
|
|
|
|
(with-throw-handler #t
|
|
|
|
|
(lambda ()
|
|
|
|
|
(apply proc args)
|
|
|
|
|
(end-of-phase #t))
|
|
|
|
|
(lambda args
|
|
|
|
|
;; This handler executes before the stack is unwound.
|
|
|
|
|
;; The exception is automatically re-thrown from here,
|
|
|
|
|
;; and we should get a proper backtrace.
|
|
|
|
|
(format (current-error-port)
|
|
|
|
|
"error: in phase '~a': uncaught exception:
|
|
|
|
|
~{~s ~}~%" name args)
|
|
|
|
|
(end-of-phase #f))))))
|
build-system/gnu: Ignore the result of phase procedures.
* guix/build/gnu-build-system.scm (set-SOURCE-DATE-EPOCH)
(set-paths, install-locale, unpack, bootstrap)
(patch-usr-bin-file, patch-source-shebangs)
(patch-generated-file-shebangs, check)
(patch-shebangs, strip, validate-runpath)
(validate-documentation-location, reset-gzip-timestamps)
(compress-documentation, delete-info-dir-file)
(patch-dot-desktop-files, install-license-files): Remove trailing #t.
(gnu-build): Use 'for-each' instead of 'every', ignore the result if
each phase procedure, and remove warning about non #t phase results.
2020-11-24 17:02:07 -05:00
|
|
|
|
phases)))
|