summaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
Diffstat (limited to 'guix')
-rw-r--r--guix/build-system/cargo.scm135
-rw-r--r--guix/build-system/gnu.scm7
-rw-r--r--guix/build-system/meson.scm14
-rw-r--r--guix/build-system/mix.scm186
-rw-r--r--guix/build-system/zig.scm1
-rw-r--r--guix/build/cargo-build-system.scm69
-rw-r--r--guix/build/mix-build-system.scm161
-rw-r--r--guix/build/syscalls.scm1
-rw-r--r--guix/import/go.scm37
-rw-r--r--guix/platform.scm3
-rw-r--r--guix/platforms/arm.scm2
-rw-r--r--guix/platforms/avr.scm28
-rw-r--r--guix/platforms/mips.scm1
-rw-r--r--guix/platforms/powerpc.scm3
-rw-r--r--guix/platforms/riscv.scm1
-rw-r--r--guix/platforms/x86.scm5
-rw-r--r--guix/scripts/challenge.scm11
-rw-r--r--guix/scripts/weather.scm61
-rw-r--r--guix/store.scm18
-rw-r--r--guix/utils.scm6
20 files changed, 701 insertions, 49 deletions
diff --git a/guix/build-system/cargo.scm b/guix/build-system/cargo.scm
index 912400a191..c029cc1dda 100644
--- a/guix/build-system/cargo.scm
+++ b/guix/build-system/cargo.scm
@@ -55,12 +55,18 @@
to NAME and VERSION."
(string-append crate-url name "/" version "/download"))
-(define (default-rust)
+(define (default-rust target)
"Return the default Rust package."
;; Lazily resolve the binding to avoid a circular dependency.
(let ((rust (resolve-interface '(gnu packages rust))))
(module-ref rust 'rust)))
+(define (default-rust-sysroot target)
+ "Return the default Rust sysroot for <target>."
+ ;; Lazily resolve the binding to avoid a circular dependency.
+ (let ((module (resolve-interface '(gnu packages rust))))
+ (module-ref module 'make-rust-sysroot)))
+
(define %cargo-utils-modules
;; Build-side modules imported by default.
`((guix build cargo-utils)
@@ -126,6 +132,69 @@ to NAME and VERSION."
#:graft? #f
#:guile-for-build guile))
+(define* (cargo-cross-build name
+ #:key
+ source target
+ build-inputs target-inputs host-inputs
+ (tests? #f)
+ (test-target #f)
+ (vendor-dir "guix-vendor")
+ (cargo-build-flags ''("--release"))
+ (cargo-test-flags ''("--release"))
+ (cargo-package-flags ''("--no-metadata" "--no-verify"))
+ (features ''())
+ (skip-build? #f)
+ (install-source? (not (target-mingw? target)))
+ (phases '%standard-phases)
+ (outputs '("out"))
+ (search-paths '())
+ (native-search-paths '())
+ (system (%current-system))
+ (guile #f)
+ (imported-modules %cargo-build-system-modules)
+ (modules '((guix build cargo-build-system)
+ (guix build utils))))
+ "Cross-build SOURCE using CARGO, and with INPUTS."
+
+ (define builder
+ (with-imported-modules imported-modules
+ #~(begin
+ (use-modules #$@(sexp->gexp modules))
+
+ (cargo-build #:name #$name
+ #:source #+source
+ #:target #+target
+ #:system #$system
+ #:test-target #$test-target
+ #:vendor-dir #$vendor-dir
+ #:cargo-build-flags #$(sexp->gexp cargo-build-flags)
+ #:cargo-test-flags #$(sexp->gexp cargo-test-flags)
+ #:cargo-package-flags #$(sexp->gexp cargo-package-flags)
+ #:features #$(sexp->gexp features)
+ #:skip-build? #$skip-build?
+ #:install-source? #$install-source?
+ #:tests? #$(and tests? (not skip-build?))
+ #:phases #$(if (pair? phases)
+ (sexp->gexp phases)
+ phases)
+ #:outputs #$(outputs->gexp outputs)
+ #:inputs (append #$(input-tuples->gexp host-inputs)
+ #+(input-tuples->gexp target-inputs))
+ #:native-inputs #+(input-tuples->gexp build-inputs)
+ #:make-dynamic-linker-cache? #f ;cross-compiling
+ #:search-paths '#$(sexp->gexp
+ (map search-path-specification->sexp
+ search-paths))
+ #:native-search-paths '#$(sexp->gexp
+ (map search-path-specification->sexp
+ native-search-paths))))))
+
+ (gexp->derivation name builder
+ #:system system
+ #:target target
+ #:graft? #f
+ #:guile-for-build guile))
+
(define (package-cargo-inputs p)
(apply
(lambda* (#:key (cargo-inputs '()) #:allow-other-keys)
@@ -235,7 +304,8 @@ any dependent crates. This can be a benefits:
(define* (lower name
#:key source inputs native-inputs outputs system target
- (rust (default-rust))
+ (rust (default-rust target))
+ (rust-sysroot (default-rust-sysroot target))
(cargo-inputs '())
(cargo-development-inputs '())
#:allow-other-keys
@@ -243,28 +313,49 @@ any dependent crates. This can be a benefits:
"Return a bag for NAME."
(define private-keywords
- '(#:target #:rust #:inputs #:native-inputs #:outputs
- #:cargo-inputs #:cargo-development-inputs))
+ `(#:rust #:inputs #:native-inputs #:outputs
+ #:cargo-inputs #:cargo-development-inputs
+ #:rust-sysroot
+ ,@(if target '() '(#:target))))
+
+ (bag
+ (name name)
+ (system system)
+ (target target)
+ (host-inputs `(,@(if source
+ `(("source" ,source))
+ '())
+
+ ;,@(if target '() inputs)
+ ,@(if target inputs '())
+
+ ,@(expand-crate-sources cargo-inputs cargo-development-inputs)))
+ (build-inputs `(("cargo" ,rust "cargo")
+ ("rustc" ,rust)
+
+ ,@native-inputs
+ ;,@(if target inputs '())
+ ,@(if target '() inputs)
+ ;,@inputs
- (and (not target) ;; TODO: support cross-compilation
- (bag
- (name name)
- (system system)
- (target target)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs
+ ,@(if target
+ ;; Use the standard cross inputs of
+ ;; 'gnu-build-system'.
+ (standard-cross-packages target 'host)
+ '())
+ ;; Keep the standard inputs of 'gnu-build-system'
+ ,@(standard-packages)))
+ (target-inputs `(,@(if target
+ (standard-cross-packages target 'target)
+ '())
- ;; Keep the standard inputs of 'gnu-build-system'
- ,@(standard-packages)))
- (build-inputs `(("cargo" ,rust "cargo")
- ("rustc" ,rust)
- ,@(expand-crate-sources cargo-inputs cargo-development-inputs)
- ,@native-inputs))
- (outputs outputs)
- (build cargo-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
+ ;; This provides a separate sysroot for the regular rustc
+ ,@(if target
+ `(("rust-sysroot" ,(rust-sysroot target)))
+ '())))
+ (outputs outputs)
+ (build (if target cargo-cross-build cargo-build))
+ (arguments (strip-keyword-arguments private-keywords arguments))))
(define cargo-build-system
(build-system
diff --git a/guix/build-system/gnu.scm b/guix/build-system/gnu.scm
index c1aa187c42..cdbb547773 100644
--- a/guix/build-system/gnu.scm
+++ b/guix/build-system/gnu.scm
@@ -460,10 +460,13 @@ is one of `host' or `target'."
`(("cross-gcc" ,(gcc target
#:xbinutils (binutils target)
#:libc libc))
- ("cross-libc" ,libc)
+ ;; Some targets don't have a libc. (e.g. *-elf targets).
+ ,@(if libc
+ `(("cross-libc" ,libc))
+ '())
;; MinGW's libc doesn't have a "static" output.
- ,@(if (member "static" (package-outputs libc))
+ ,@(if (and libc (member "static" (package-outputs libc)))
`(("cross-libc:static" ,libc "static"))
'()))))))))
diff --git a/guix/build-system/meson.scm b/guix/build-system/meson.scm
index 2d14016b94..bf9ca15ecc 100644
--- a/guix/build-system/meson.scm
+++ b/guix/build-system/meson.scm
@@ -49,11 +49,13 @@ for TRIPLET."
`((system . ,(cond ((target-hurd? triplet) "gnu")
((target-linux? triplet) "linux")
((target-mingw? triplet) "windows")
+ ((target-avr? triplet) "none")
(#t (error "meson: unknown operating system"))))
(cpu_family . ,(cond ((target-x86-32? triplet) "x86")
((target-x86-64? triplet) "x86_64")
((target-arm32? triplet) "arm")
((target-aarch64? triplet) "aarch64")
+ ((target-avr? triplet) "avr")
((target-mips64el? triplet) "mips64")
((target-powerpc? triplet)
(if (target-64bit? triplet)
@@ -66,6 +68,7 @@ for TRIPLET."
((target-x86-64? triplet) "x86_64")
((target-aarch64? triplet) "armv8-a")
((target-arm32? triplet) "armv7")
+ ((target-avr? triplet) "avr")
;; According to #mesonbuild on OFTC, there does not appear
;; to be an official-ish list of CPU types recognised by
;; Meson, the "cpu" field is not used by Meson itself and
@@ -89,6 +92,13 @@ TRIPLET."
(ld . ,(string-append triplet "-ld"))
(strip . ,(string-append triplet "-strip"))))
+(define (make-built-in-options-alist triplet)
+ (if (target-avr? triplet)
+ `((b_pie . #f)
+ (b_staticpic . #f)
+ (default_library . "static"))
+ '()))
+
(define (make-cross-file triplet)
(computed-file "cross-file"
(with-imported-modules '((guix build meson-configuration))
@@ -99,7 +109,9 @@ TRIPLET."
(write-section-header port "host_machine")
(write-assignments port '#$(make-machine-alist triplet))
(write-section-header port "binaries")
- (write-assignments port '#$(make-binaries-alist triplet))))))))
+ (write-assignments port '#$(make-binaries-alist triplet))
+ (write-section-header port "built-in options")
+ (write-assignments port '#$(make-built-in-options-alist triplet))))))))
(define %meson-build-system-modules
;; Build-side modules imported by default.
diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm
new file mode 100644
index 0000000000..1b04053d70
--- /dev/null
+++ b/guix/build-system/mix.scm
@@ -0,0 +1,186 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <contact@phfrohring.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; 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.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; 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
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+;; Commentary:
+;;
+;; Standard build procedure for Elixir packages using 'mix'. This is
+;; implemented as an extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define-module (guix build-system mix)
+ #:use-module (guix build mix-build-system)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system)
+ #:use-module (guix gexp)
+ #:use-module (guix monads)
+ #:use-module (guix packages)
+ #:use-module (guix search-paths)
+ #:use-module (guix store)
+ #:use-module (guix utils)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:export (mix-build-system hexpm-uri))
+
+;; Lazily resolve bindings to avoid circular dependencies.
+(define (default-glibc-utf8-locales)
+ (let* ((base (resolve-interface '(gnu packages base))))
+ (module-ref base 'glibc-utf8-locales)))
+
+(define (default-elixir-hex)
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir-hex)))
+
+(define (default-rebar3)
+ (let ((erlang (resolve-interface '(gnu packages erlang))))
+ (module-ref erlang 'rebar3)))
+
+(define (default-elixir)
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir)))
+
+(define* (strip-prefix name #:optional (prefix "elixir-"))
+ "Return NAME without the prefix PREFIX."
+ (if (string-prefix? prefix name)
+ (string-drop name (string-length prefix))
+ name))
+
+(define (hexpm-uri name version)
+ "Return the URI where to fetch the sources of a Hex package NAME at VERSION.
+NAME is the name of the package which should look like: elixir-pkg-name-X.Y.Z
+See: https://github.com/hexpm/specifications/blob/main/endpoints.md"
+ ((compose
+ (cute string-append "https://repo.hex.pm/tarballs/" <> "-" version ".tar")
+ (cute string-replace-substring <> "-" "_")
+ strip-prefix)
+ name))
+
+;; A number of environment variables specific to the Mix build system are
+;; reflected here. They are documented at
+;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables. Other
+;; parameters located in mix.exs are defined at
+;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration
+(define* (mix-build name
+ inputs
+ #:key
+ source
+ (tests? #t)
+ (mix-path #f) ;See MIX_PATH.
+ (mix-exs "mix.exs") ;See MIX_EXS.
+ (build-per-environment #t) ;See :build_per_environment.
+ (phases '%standard-phases)
+ (outputs '("out"))
+ (search-paths '())
+ (system (%current-system))
+ (guile #f)
+ (imported-modules `((guix build mix-build-system)
+ ,@%gnu-build-system-modules))
+ (modules '((guix build mix-build-system)
+ (guix build utils))))
+ "Build SOURCE using Elixir, and with INPUTS."
+
+ ;; Check the documentation of :build_per_environment here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration And
+ ;; "Environments" here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments
+ (define mix-environments
+ (if build-per-environment
+ `("prod" ,@(if tests? '("test") '()))
+ '("shared")))
+
+ (define builder
+ (with-imported-modules imported-modules
+ #~(begin
+
+ (use-modules #$@(sexp->gexp modules))
+
+ #$(with-build-variables inputs outputs
+ #~(mix-build #:name #$name
+ #:source #+source
+ #:system #$system
+ #:tests? #$tests?
+ #:mix-path #$mix-path
+ #:mix-exs #$mix-exs
+ #:mix-environments '#$mix-environments
+ #:build-per-environment #$build-per-environment
+ #:phases #$(if (pair? phases)
+ (sexp->gexp phases)
+ phases)
+ #:outputs %outputs
+ #:search-paths '#$(sexp->gexp
+ (map
+ search-path-specification->sexp
+ search-paths))
+ #:inputs
+ %build-inputs)))))
+
+ (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
+ system
+ #:graft? #f)))
+ (gexp->derivation name
+ builder
+ #:system system
+ #:graft? #f ;consistent with 'gnu-build'
+ #:target #f
+ #:guile-for-build guile)))
+
+(define* (lower name
+ #:key
+ (elixir (default-elixir))
+ (elixir-hex (default-elixir-hex))
+ (glibc-utf8-locales (default-glibc-utf8-locales))
+ (inputs '())
+ (native-inputs '())
+ (propagated-inputs '())
+ (rebar3 (default-rebar3))
+ (tests? #t)
+ outputs
+ source
+ system
+ target
+ #:allow-other-keys #:rest arguments)
+ "Return a bag for NAME."
+ (let ((private-keywords
+ '(#:inputs #:native-inputs
+ #:outputs #:system #:target
+ #:elixir #:elixir-hex #:glibc-utf8-locales
+ #:rebar3 #:erlang))
+ (build-inputs
+ `(,@(standard-packages)
+ ("glibc-utf8-locales" ,glibc-utf8-locales)
+ ("erlang" ,(lookup-package-input elixir "erlang"))
+ ("rebar3" ,rebar3)
+ ("elixir" ,elixir)
+ ("elixir-hex" ,elixir-hex)
+ ,@inputs
+ ,@native-inputs)))
+ (bag (name name)
+ (system system)
+ (build-inputs build-inputs)
+ (host-inputs (if target inputs '()))
+ (outputs outputs)
+ (build mix-build)
+ (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define mix-build-system
+ (build-system (name 'mix)
+ (description "The standard Mix build system")
+ (lower lower)))
+
+;;; mix.scm ends here
diff --git a/guix/build-system/zig.scm b/guix/build-system/zig.scm
index 16b8a712cc..215178ceb4 100644
--- a/guix/build-system/zig.scm
+++ b/guix/build-system/zig.scm
@@ -39,7 +39,6 @@
(define %zig-build-system-modules
;; Build-side modules imported by default.
`((guix build zig-build-system)
- (guix build syscalls)
,@%gnu-build-system-modules))
(define* (zig-build name inputs
diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm
index 505c0b4b01..ffb2ec898e 100644
--- a/guix/build/cargo-build-system.scm
+++ b/guix/build/cargo-build-system.scm
@@ -119,6 +119,7 @@ libraries or executables."
(error "Possible pre-generated files found:" pregenerated-files))))
(define* (configure #:key inputs
+ target
(vendor-dir "guix-vendor")
#:allow-other-keys)
"Vendor Cargo.toml dependencies as guix inputs."
@@ -146,27 +147,75 @@ libraries or executables."
(invoke "tar" "xf" path "-C" crate-dir "--strip-components" "1")))))
inputs)
- ;; Configure cargo to actually use this new directory.
+ ;; For cross-building
+ (when target
+ (setenv "CARGO_BUILD_TARGET"
+ ;; Can this be replaced with platform-rust-architecture?
+ ;; Keep this synchronized with (guix platforms *)
+ (match target
+ ("aarch64-linux-gnu" "aarch64-unknown-linux-gnu")
+ ("arm-linux-gnueabihf" "armv7-unknown-linux-gnueabihf")
+ ("i686-linux-gnu" "i686-unknown-linux-gnu")
+ ("mips64el-linux-gnu" "mips64el-unknown-linux-gnuabi64")
+ ("powerpc-linux-gnu" "powerpc-unknown-linux-gnu")
+ ("powerpc64-linux-gnu" "powerpc64-unknown-linux-gnu")
+ ("powerpc64le-linux-gnu" "powerpc64le-unknown-linux-gnu")
+ ("riscv64-linux-gnu" "riscv64gc-unknown-linux-gnu")
+ ("x86_64-linux-gnu" "x86_64-unknown-linux-gnu")
+ ("i586-pc-gnu" "i686-unknown-hurd-gnu")
+ ("i686-w64-mingw32" "i686-pc-windows-gnu")
+ ("x86_64-w64-mingw32" "x86_64-pc-windows-gnu")
+ (else #f)))
+ (setenv "RUSTFLAGS" (string-append
+ (or (getenv "RUSTFLAGS") "")
+ " --sysroot " (assoc-ref inputs "rust-sysroot")))
+
+ (setenv "PKG_CONFIG" (string-append target "-pkg-config"))
+
+ ;; We've removed all the bundled libraries, don't look for them.
+ (setenv "WINAPI_NO_BUNDLED_LIBRARIES" "1")
+
+ ;; Prevent targeting the build machine.
+ (setenv "CRATE_CC_NO_DEFAULTS" "1"))
+
+ ;; Configure cargo to actually use this new directory with all the crates.
(setenv "CARGO_HOME" (string-append (getcwd) "/.cargo"))
(mkdir-p ".cargo")
+ ;; Not .cargo/config.toml, rustc/cargo will generate .cargo/config otherwise.
(let ((port (open-file ".cargo/config" "w" #:encoding "utf-8")))
- (display "
+ ;; Placed here so it doesn't cause random rebuilds. Neither of these work.
+ ;; sysroot = '" (assoc-ref inputs "rust-sysroot") "'
+ ;; rustflags = ['--sysroot', '" (assoc-ref inputs "rust-sysroot") "']
+ (when target
+ (display (string-append "
+[target." (getenv "CARGO_BUILD_TARGET") "]
+linker = '" target "-gcc'
+
+[build]
+target = ['" (getenv "CARGO_BUILD_TARGET") "']") port))
+ (display (string-append "
[source.crates-io]
replace-with = 'vendored-sources'
[source.vendored-sources]
-directory = '" port)
- (display (string-append (getcwd) "/" vendor-dir) port)
- (display "'
-" port)
+directory = '" vendor-dir "'") port)
(close-port port))
;; Lift restriction on any lints: a crate author may have decided to opt
;; into stricter lints (e.g. #![deny(warnings)]) during their own builds
;; but we don't want any build failures that could be caused later by
;; upgrading the compiler for example.
- (setenv "RUSTFLAGS" "--cap-lints allow")
- (setenv "CC" (string-append (assoc-ref inputs "gcc") "/bin/gcc"))
+ (setenv "RUSTFLAGS" (string-append (or (getenv "RUSTFLAGS") "")
+ " --cap-lints allow"))
+
+ (if (assoc-ref inputs "cross-gcc")
+ (begin
+ (setenv "HOST_CC" "gcc")
+ (setenv "TARGET_CC" (string-append target "-gcc"))
+ (setenv "TARGET_AR" (string-append target "-ar"))
+ (setenv "TARGET_PKG_CONFIG" (string-append target "-pkg-config")))
+ (setenv "CC" (string-append (assoc-ref inputs "gcc") "/bin/gcc")))
+
(setenv "LIBGIT2_SYS_USE_PKG_CONFIG" "1")
(setenv "LIBSSH2_SYS_USE_PKG_CONFIG" "1")
(when (assoc-ref inputs "openssl")
@@ -264,7 +313,11 @@ directory = '" port)
(unless (eq? (stat:type s) 'symlink)
(utime file 0 0 0 0))))
(find-files dir #:directories? #t))
+
(apply invoke "tar" "czf" (string-append dir ".crate")
+ ;; avoid non-determinism in the archive
+ "--sort=name" "--mtime=@0"
+ "--owner=root:0" "--group=root:0"
(find-files dir #:directories? #t))
(delete-file-recursively dir)))
(find-files "." "\\.crate$")))))
diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-system.scm
new file mode 100644
index 0000000000..fe2e36d184
--- /dev/null
+++ b/guix/build/mix-build-system.scm
@@ -0,0 +1,161 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <contact@phfrohring.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; 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.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; 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
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+;; Commentary:
+;;
+;; Code:
+
+(define-module (guix build mix-build-system)
+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+ #:use-module (guix build utils)
+ #:use-module (ice-9 ftw)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-71)
+ #:export (mix-build
+ %standard-phases))
+
+;; The Elixir version is constant as soon as it is computable from the current
+;; execution. It is a X.Y string where X and Y are respectively the major and
+;; minor version number of the Elixir used in the build.
+(define %elixir-version (make-parameter "X.Y"))
+
+(define* (elixir-libdir path #:optional (version (%elixir-version)))
+ "Return the path where all libraries under PATH for a specified Elixir
+VERSION are installed."
+ (string-append path "/lib/elixir/" version))
+
+(define* (strip-prefix name #:optional (prefix "elixir-"))
+ "Return NAME without the prefix PREFIX."
+ (if (string-prefix? prefix name)
+ (string-drop name (string-length prefix))
+ name))
+
+(define (mix-build-dir mix-build-root mix-env)
+ "Return the directory where build artifacts are to be installed according to
+en environment MIX-ENV in the current directory. MIX-BUILD-ROOT depends on the
+package arguments. See: https://hexdocs.pm/mix/1.15/Mix.html#module-environment-variables"
+ (string-append mix-build-root "/" mix-env "/lib"))
+
+(define (elixir-version inputs)
+ "Return an X.Y string where X and Y are respectively the major and minor version number of PACKAGE.
+Example: /gnu/store/…-elixir-1.14.0 → 1.14"
+ ((compose
+ (cute string-join <> ".")
+ (cute take <> 2)
+ (cute string-split <> #\.)
+ strip-prefix
+ strip-store-file-name)
+ (assoc-ref inputs "elixir")))
+
+(define* (unpack #:key source mix-path #:allow-other-keys)
+ "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."
+ (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
+ (gnu-unpack #:source source)
+ (when (file-exists? "contents.tar.gz")
+ (invoke "tar" "xvf" "contents.tar.gz"))))
+
+(define (list-directories dir)
+ "List absolute paths of directories directly under the directory DIR."
+ (map (cute string-append dir "/" <>)
+ (scandir dir (lambda (filename)
+ (and (not (member filename '("." "..")))
+ (directory-exists? (string-append dir "/" filename)))))))
+
+(define* (set-mix-env #:key inputs mix-path mix-exs #:allow-other-keys)
+ "Set environment variables.
+See: https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables"
+ (setenv "MIX_ARCHIVES" "archives")
+ (setenv "MIX_BUILD_ROOT" "_build")
+ (setenv "MIX_DEPS_PATH" "deps")
+ (setenv "MIX_EXS" mix-exs)
+ (setenv "MIX_HOME" (getcwd))
+ (setenv "MIX_PATH" (or mix-path ""))
+ (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3") "/bin/rebar3")))
+
+(define* (set-elixir-version #:key inputs #:allow-other-keys)
+ "Store the version number of the Elixir input in a parameter."
+ (%elixir-version (elixir-version inputs))
+ (format #t "Elixir version: ~a~%" (%elixir-version)))
+
+(define* (build #:key mix-environments #:allow-other-keys)
+ "Builds the Mix project."
+ (for-each (lambda (mix-env)
+ (setenv "MIX_ENV" mix-env)
+ (invoke "mix" "compile" "--no-deps-check"))
+ mix-environments))
+
+(define* (check #:key (tests? #t) #:allow-other-keys)
+ "Test the Mix project."
+ (if tests?
+ (invoke "mix" "test" "--no-deps-check")
+ (format #t "tests? = ~a~%" tests?)))
+
+(define* (remove-mix-dirs . _)
+ "Remove all .mix/ directories.
+We do not want to copy them to the installation directory."
+ (for-each delete-file-recursively
+ (find-files "." (file-name-predicate "\\.mix$") #:directories? #t)))
+
+(define (package-name->elixir-name name+ver)
+ "Convert the Guix package NAME-VER to the corresponding Elixir name-version
+format. Example: elixir-a-pkg-1.2.3 -> a_pkg"
+ ((compose
+ (cute string-join <> "_")
+ (cute drop-right <> 1)
+ (cute string-split <> #\-))
+ (strip-prefix name+ver)))
+
+(define* (install #:key
+ inputs
+ outputs
+ name
+ build-per-environment
+ #:allow-other-keys)
+ "Install build artifacts in the store."
+ (let* ((lib-name (package-name->elixir-name name))
+ (lib-dir (string-append (elixir-libdir (assoc-ref outputs "out")) "/" lib-name))
+ (root (getenv "MIX_BUILD_ROOT"))
+ (env (if build-per-environment "prod" "shared")))
+ (mkdir-p lib-dir)
+ (copy-recursively (string-append (mix-build-dir root env) "/" lib-name) lib-dir
+ #:follow-symlinks? #t)))
+
+(define %standard-phases
+ (modify-phases gnu:%standard-phases
+ (delete 'bootstrap)
+ (delete 'configure)
+ (add-after 'install-locale 'set-mix-env set-mix-env)
+ (add-after 'set-mix-env 'set-elixir-version set-elixir-version)
+ (replace 'unpack unpack)
+ (replace 'build build)
+ (replace 'check check)
+ (add-before 'install 'remove-mix-dirs remove-mix-dirs)
+ (replace 'install install)))
+
+(define* (mix-build #:key inputs (phases %standard-phases)
+ #:allow-other-keys #:rest args)
+ "Build the given Mix package, applying all of PHASES in order."
+ (apply gnu:gnu-build #:inputs inputs #:phases phases args))
+
+;;; mix-build-system.scm ends here
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 4afe6d2f87..b2871c3c10 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -1098,6 +1098,7 @@ Turning finalization off shuts down the finalization thread as a side effect."
("armv7l" 120)
("aarch64" 220)
("ppc64le" 120)
+ ("riscv64" 220)
(_ #f))))
(lambda (flags)
"Create a new child process by duplicating the current parent process.
diff --git a/guix/import/go.scm b/guix/import/go.scm
index 0357e6a1eb..dd9298808d 100644
--- a/guix/import/go.scm
+++ b/guix/import/go.scm
@@ -7,6 +7,7 @@
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
+;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -28,6 +29,7 @@
#:use-module (guix git)
#:use-module (guix hash)
#:use-module (guix i18n)
+ #:use-module ((guix utils) #:select (version>?))
#:use-module (guix diagnostics)
#:use-module (guix import utils)
#:use-module (guix import json)
@@ -92,6 +94,11 @@
;;; Code:
+(define (go-package)
+ "Return the 'go' package. This is a lazy reference so that we don't
+depend on (gnu packages golang)."
+ (module-ref (resolve-interface '(gnu packages golang)) 'go))
+
(define http-fetch*
;; Like http-fetch, but memoized and returning the body as a string.
(memoize (lambda args
@@ -293,7 +300,10 @@ comment, or unknown) and is followed by the indicated data."
;; The following directives may all be used solo or in a block
;; RequireSpec = ModulePath Version newline .
- (define-peg-pattern require all (and module-path version EOL))
+ (define-peg-pattern require all
+ (and module-path version
+ ;; We don't want the transitive dependencies.
+ (not-followed-by (and (* WS) "//" (* WS) "indirect")) EOL))
(define-peg-pattern require-top body
(and (ignore "require")
(or (and block-start (* (or require block-line)) block-end) require)))
@@ -310,7 +320,7 @@ comment, or unknown) and is followed by the indicated data."
(define-peg-pattern with all (or (and module-path version) file-path))
(define-peg-pattern replace all (and original => with EOL))
(define-peg-pattern replace-top body
- (and (ignore "replace")
+ (and (ignore "replace")
(or (and block-start (* (or replace block-line)) block-end) replace)))
;; RetractSpec = ( Version | "[" Version "," Version "]" ) newline .
@@ -374,6 +384,17 @@ DIRECTIVE."
;; Prevent inlining of this procedure, which is accessed by unit tests.
(set! go.mod-requirements go.mod-requirements)
+(define (go.mod-go-version go.mod)
+ "Return the minimum version of go required to specified by GO.MOD."
+ (let ((go-version (go.mod-directives go.mod 'go)))
+ (if (null? go-version)
+ ;; If the go directive is missing, go 1.16 is assumed.
+ '(version "1.16")
+ (flatten go-version))))
+
+;; Prevent inlining of this procedure, which is accessed by unit tests.
+(set! go.mod-go-version go.mod-go-version)
+
(define-record-type <vcs>
(%make-vcs url-prefix root-regex type)
vcs?
@@ -606,6 +627,7 @@ When VERSION is unspecified, the latest version available is used."
available-versions
module-path))
(content (fetch-go.mod goproxy module-path version*))
+ (min-go-version (second (go.mod-go-version (parse-go.mod content))))
(dependencies+versions (go.mod-requirements (parse-go.mod content)))
(dependencies (if pin-versions?
dependencies+versions
@@ -630,10 +652,13 @@ When VERSION is unspecified, the latest version available is used."
,(vcs->origin vcs-type vcs-repo-url version*))
(build-system go-build-system)
(arguments
- '(#:import-path ,module-path
- ,@(if (string=? module-path-sans-suffix root-module-path)
- '()
- `(#:unpack-path ,root-module-path))))
+ (list ,@(if (version>? min-go-version (package-version (go-package)))
+ `(#:go ,(string->number min-go-version))
+ '())
+ #:import-path ,module-path
+ ,@(if (string=? module-path-sans-suffix root-module-path)
+ '()
+ `(#:unpack-path ,root-module-path))))
,@(maybe-propagated-inputs
(map (match-lambda
((name version)
diff --git a/guix/platform.scm b/guix/platform.scm
index 55917ca308..994563ab26 100644
--- a/guix/platform.scm
+++ b/guix/platform.scm
@@ -29,6 +29,7 @@
platform-target
platform-system
platform-linux-architecture
+ platform-rust-target
platform-glibc-dynamic-linker
&platform-not-found-error
@@ -74,6 +75,8 @@
(system platform-system)
(linux-architecture platform-linux-architecture
(default #false))
+ (rust-target platform-rust-target
+ (default #false))
(glibc-dynamic-linker platform-glibc-dynamic-linker))
diff --git a/guix/platforms/arm.scm b/guix/platforms/arm.scm
index 32c0fbc032..b0c76efc73 100644
--- a/guix/platforms/arm.scm
+++ b/guix/platforms/arm.scm
@@ -27,6 +27,7 @@
(target "arm-linux-gnueabihf")
(system "armhf-linux")
(linux-architecture "arm")
+ (rust-target "armv7-unknown-linux-gnueabihf")
(glibc-dynamic-linker "/lib/ld-linux-armhf.so.3")))
(define aarch64-linux
@@ -34,4 +35,5 @@
(target "aarch64-linux-gnu")
(system "aarch64-linux")
(linux-architecture "arm64")
+ (rust-target "aarch64-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld-linux-aarch64.so.1")))
diff --git a/guix/platforms/avr.scm b/guix/platforms/avr.scm
new file mode 100644
index 0000000000..ba178db6ea
--- /dev/null
+++ b/guix/platforms/avr.scm
@@ -0,0 +1,28 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Foundation Devices, Inc. <hello@foundationdevices.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; 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.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; 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
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix platforms avr)
+ #:use-module (guix platform)
+ #:use-module (guix records)
+ #:export (avr))
+
+(define avr
+ (platform
+ (target "avr")
+ (system #f)
+ (glibc-dynamic-linker #f)))
diff --git a/guix/platforms/mips.scm b/guix/platforms/mips.scm
index e6fa9eb292..17b6958f48 100644
--- a/guix/platforms/mips.scm
+++ b/guix/platforms/mips.scm
@@ -26,4 +26,5 @@
(target "mips64el-linux-gnu")
(system "mips64el-linux")
(linux-architecture "mips")
+ (rust-target "mips64el-unknown-linux-gnuabi64")
(glibc-dynamic-linker "/lib/ld.so.1")))
diff --git a/guix/platforms/powerpc.scm b/guix/platforms/powerpc.scm
index 1c7141ab42..c55301768d 100644
--- a/guix/platforms/powerpc.scm
+++ b/guix/platforms/powerpc.scm
@@ -28,6 +28,7 @@
(target "powerpc-linux-gnu")
(system "powerpc-linux")
(linux-architecture "powerpc")
+ (rust-target "powerpc-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld.so.1")))
(define powerpc64-linux
@@ -35,6 +36,7 @@
(target "powerpc64-linux-gnu")
(system #f) ;not supported
(linux-architecture "powerpc")
+ (rust-target "powerpc64-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld64.so.1")))
(define powerpc64le-linux
@@ -42,4 +44,5 @@
(target "powerpc64le-linux-gnu")
(system "powerpc64le-linux")
(linux-architecture "powerpc")
+ (rust-target "powerpc64le-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld64.so.2")))
diff --git a/guix/platforms/riscv.scm b/guix/platforms/riscv.scm
index c716c12c12..1b34e82b36 100644
--- a/guix/platforms/riscv.scm
+++ b/guix/platforms/riscv.scm
@@ -26,4 +26,5 @@
(target "riscv64-linux-gnu")
(system "riscv64-linux")
(linux-architecture "riscv")
+ (rust-target "riscv64gc-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld-linux-riscv64-lp64d.so.1")))
diff --git a/guix/platforms/x86.scm b/guix/platforms/x86.scm
index 6f547dd770..4ed5638c14 100644
--- a/guix/platforms/x86.scm
+++ b/guix/platforms/x86.scm
@@ -30,6 +30,7 @@
(target "i686-linux-gnu")
(system "i686-linux")
(linux-architecture "i386")
+ (rust-target "i686-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld-linux.so.2")))
(define x86_64-linux
@@ -37,22 +38,26 @@
(target "x86_64-linux-gnu")
(system "x86_64-linux")
(linux-architecture "x86_64")
+ (rust-target "x86_64-unknown-linux-gnu")
(glibc-dynamic-linker "/lib/ld-linux-x86-64.so.2")))
(define i686-mingw
(platform
(target "i686-w64-mingw32")
(system #f)
+ (rust-target "i686-pc-windows-gnu")
(glibc-dynamic-linker #f)))
(define x86_64-mingw
(platform
(target "x86_64-w64-mingw32")
(system #f)
+ (rust-target "x86_64-pc-windows-gnu")
(glibc-dynamic-linker #f)))
(define i586-gnu
(platform
(target "i586-pc-gnu")
(system "i586-gnu")
+ (rust-target "i686-unknown-hurd-gnu")
(glibc-dynamic-linker "/lib/ld.so.1")))
diff --git a/guix/scripts/challenge.scm b/guix/scripts/challenge.scm
index 01e2f9a2b2..d38171b868 100644
--- a/guix/scripts/challenge.scm
+++ b/guix/scripts/challenge.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015-2017, 2019-2022 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015-2017, 2019-2023 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -504,7 +504,6 @@ Challenge the substitutes for PACKAGE... provided by one or more servers.\n"))
(define %default-options
`((system . ,(%current-system))
- (substitute-urls . ,%default-substitute-urls)
(difference-report . ,report-differing-files)))
@@ -539,7 +538,13 @@ Challenge the substitutes for PACKAGE... provided by one or more servers.\n"))
(G_ "no arguments specified, nothing to do~%"))
(exit 0))
(x
- files))))
+ files)))
+ (urls (or urls
+ (substitute-urls store)
+ (begin
+ (warning (G_ "could not determine current \
+substitute URLs; using defaults~%"))
+ %default-substitute-urls))))
(set-build-options store
#:use-substitutes? #f)
diff --git a/guix/scripts/weather.scm b/guix/scripts/weather.scm
index 140df3435f..2f8985593d 100644
--- a/guix/scripts/weather.scm
+++ b/guix/scripts/weather.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2017-2022 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2018 Kyle Meyer <kyle@kyleam.com>
;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
@@ -35,6 +35,8 @@
#:use-module ((guix build utils) #:select (every*))
#:use-module (guix substitutes)
#:use-module (guix narinfo)
+ #:use-module (guix pki)
+ #:autoload (gcrypt pk-crypto) (canonical-sexp->string)
#:use-module (guix http-client)
#:use-module (guix ci)
#:use-module (guix sets)
@@ -185,6 +187,44 @@ or #f if it could not be determined."
(()
#f)))
+(define (check-narinfo-authorization narinfo)
+ "Print a warning when NARINFO is not signed by an authorized key."
+ (define acl
+ (catch 'system-error
+ (lambda ()
+ (current-acl))
+ (lambda args
+ (warning (G_ "could not read '~a': ~a~%")
+ %acl-file (strerror (system-error-errno args)))
+ (warning (G_ "'~a' is unreadable, cannot determine whether \
+substitutes are authorized~%")
+ %acl-file)
+ #f)))
+
+ (unless (or (not acl) (valid-narinfo? narinfo acl))
+ (warning (G_ "substitutes from '~a' are unauthorized~%")
+ (narinfo-uri-base narinfo))
+ ;; The "all substitutes" below reflects the fact that, in reality, it *is*
+ ;; possible to download "unauthorized" substitutes, as long as they match
+ ;; authorized substitutes.
+ (display-hint (G_ "To authorize all substitutes from @uref{~a} to be
+downloaded, the following command needs to be run as root:
+
+@example
+guix archive --authorize <<EOF
+~a
+EOF
+@end example
+
+Alternatively, on Guix System, you can add the signing key above to the
+@code{authorized-keys} field of @code{guix-configuration}.
+
+See \"Getting Substitutes from Other Servers\" in the manual for more
+information.")
+ (narinfo-uri-base narinfo)
+ (canonical-sexp->string
+ (signature-subject (narinfo-signature narinfo))))))
+
(define* (report-server-coverage server items
#:key display-missing?)
"Report the subset of ITEMS available as substitutes on SERVER.
@@ -204,6 +244,12 @@ In case ITEMS is an empty list, return 1 instead."
#:make-progress-reporter
(lambda* (total #:key url #:allow-other-keys)
(progress-reporter/bar total)))))
+ (match narinfos
+ (() #f)
+ ((narinfo . _)
+ ;; Help diagnose missing substitute authorizations.
+ (check-narinfo-authorization narinfo)))
+
(let ((obtained (length narinfos))
(requested (length items))
(missing (lset-difference string=?
@@ -391,7 +437,7 @@ Report the availability of substitutes.\n"))
%standard-native-build-options))
(define %default-options
- `((substitute-urls . ,%default-substitute-urls)))
+ '())
(define (load-manifest file)
"Load the manifest from FILE and return the list of packages it refers to."
@@ -582,7 +628,16 @@ SERVER. Display information for packages with at least THRESHOLD dependents."
(let* ((opts (parse-command-line args %options
(list %default-options)
#:build-options? #f))
- (urls (assoc-ref opts 'substitute-urls))
+ (urls (or (assoc-ref opts 'substitute-urls)
+ (with-store store
+ (substitute-urls store))
+ (begin
+ ;; Could not determine the daemon's current
+ ;; substitute URLs, presumably because it's too
+ ;; old.
+ (warning (G_ "using default \
+substitute URLs~%"))
+ %default-substitute-urls)))
(systems (match (filter-map (match-lambda
(('system . system) system)
(_ #f))
diff --git a/guix/store.scm b/guix/store.scm
index f8e77b2cd9..97c4f32a5b 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012-2022 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2019, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de>
@@ -145,6 +145,7 @@
path-info-nar-size
built-in-builders
+ substitute-urls
references
references/cached
references*
@@ -199,7 +200,7 @@
derivation-log-file
log-file))
-(define %protocol-version #x163)
+(define %protocol-version #x164)
(define %worker-magic-1 #x6e697863) ; "nixc"
(define %worker-magic-2 #x6478696f) ; "dxio"
@@ -253,7 +254,8 @@
(query-valid-derivers 33)
(optimize-store 34)
(verify-store 35)
- (built-in-builders 80))
+ (built-in-builders 80)
+ (substitute-urls 81))
(define-enumerate-type hash-algo
;; hash.hh
@@ -1780,6 +1782,16 @@ The result is always the empty list unless the daemon was started with
This makes sense only when the daemon was started with '--cache-failures'."
boolean)
+(define substitute-urls
+ (let ((urls (operation (substitute-urls)
+ #f
+ string-list)))
+ (lambda (store)
+ "Return the list of currently configured substitutes URLs for STORE, or
+#f if the daemon is too old and does not implement this RPC."
+ (and (>= (store-connection-version store) #x164)
+ (urls store)))))
+
;;;
;;; Per-connection caches.
diff --git a/guix/utils.scm b/guix/utils.scm
index 7a42b49df2..8e71f97e1c 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -19,6 +19,7 @@
;;; Copyright © 2023 Philip McGrath <philip@philipmcgrath.com>
;;; Copyright © 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2023 Zheng Junjie <873216071@qq.com>
+;;; Copyright © 2023 Foundation Devices, Inc. <hello@foundationdevices.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -99,6 +100,7 @@
target-arm32?
target-aarch64?
target-arm?
+ target-avr?
target-ppc32?
target-ppc64le?
target-powerpc?
@@ -724,6 +726,10 @@ architecture (x86_64)?"
(%current-system))))
(or (target-arm32? target) (target-aarch64? target)))
+(define* (target-avr? #:optional (target (%current-target-system)))
+ "Is the architecture of TARGET a variant of Microchip's AVR architecture?"
+ (or (string=? target "avr") (string-prefix? "avr-" target)))
+
(define* (target-ppc32? #:optional (target (or (%current-target-system)
(%current-system))))
(string-prefix? "powerpc-" target))