build/cargo-build-system: Enable cross-compiling.
* guix/build-system/cargo.scm (default-rust): Accept an argument. (default-rust-sysroot, cargo-cross-build): New procedures. (lower): Accept a rust-sysroot. [private-kewords]: Add rust-sysroot. Remove target if cross-compiling. [bag]: Allow cross-compiling. In host-inputs only have inputs when cross-compiling, move crate sources to here, remove standard-packages. In build-inputs add the inputs when not cross-compiling, add the standard-cross-packages when cross-compiling, add the standard-packages to here. Add target-inputs with the standard-cross-packages and rust-sysroot when cross-compiling. * guix/build/cargo-build-system.scm (configure): Accept target argument. When cross-compiling set some environment variables. Adjust the .config/cargo.toml to have configure options for cross-compiling. Change-Id: I388d1e1f48943e45ff01f55af8efc0746f383b4a
parent
584bd0bb3d
commit
e604972d9c
|
@ -55,12 +55,18 @@
|
||||||
to NAME and VERSION."
|
to NAME and VERSION."
|
||||||
(string-append crate-url name "/" version "/download"))
|
(string-append crate-url name "/" version "/download"))
|
||||||
|
|
||||||
(define (default-rust)
|
(define (default-rust target)
|
||||||
"Return the default Rust package."
|
"Return the default Rust package."
|
||||||
;; Lazily resolve the binding to avoid a circular dependency.
|
;; Lazily resolve the binding to avoid a circular dependency.
|
||||||
(let ((rust (resolve-interface '(gnu packages rust))))
|
(let ((rust (resolve-interface '(gnu packages rust))))
|
||||||
(module-ref rust '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
|
(define %cargo-utils-modules
|
||||||
;; Build-side modules imported by default.
|
;; Build-side modules imported by default.
|
||||||
`((guix build cargo-utils)
|
`((guix build cargo-utils)
|
||||||
|
@ -126,6 +132,69 @@ to NAME and VERSION."
|
||||||
#:graft? #f
|
#:graft? #f
|
||||||
#:guile-for-build guile))
|
#: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)
|
(define (package-cargo-inputs p)
|
||||||
(apply
|
(apply
|
||||||
(lambda* (#:key (cargo-inputs '()) #:allow-other-keys)
|
(lambda* (#:key (cargo-inputs '()) #:allow-other-keys)
|
||||||
|
@ -235,7 +304,8 @@ any dependent crates. This can be a benefits:
|
||||||
|
|
||||||
(define* (lower name
|
(define* (lower name
|
||||||
#:key source inputs native-inputs outputs system target
|
#:key source inputs native-inputs outputs system target
|
||||||
(rust (default-rust))
|
(rust (default-rust target))
|
||||||
|
(rust-sysroot (default-rust-sysroot target))
|
||||||
(cargo-inputs '())
|
(cargo-inputs '())
|
||||||
(cargo-development-inputs '())
|
(cargo-development-inputs '())
|
||||||
#:allow-other-keys
|
#:allow-other-keys
|
||||||
|
@ -243,28 +313,49 @@ any dependent crates. This can be a benefits:
|
||||||
"Return a bag for NAME."
|
"Return a bag for NAME."
|
||||||
|
|
||||||
(define private-keywords
|
(define private-keywords
|
||||||
'(#:target #:rust #:inputs #:native-inputs #:outputs
|
`(#:rust #:inputs #:native-inputs #:outputs
|
||||||
#:cargo-inputs #:cargo-development-inputs))
|
#:cargo-inputs #:cargo-development-inputs
|
||||||
|
#:rust-sysroot
|
||||||
|
,@(if target '() '(#:target))))
|
||||||
|
|
||||||
(and (not target) ;; TODO: support cross-compilation
|
(bag
|
||||||
(bag
|
(name name)
|
||||||
(name name)
|
(system system)
|
||||||
(system system)
|
(target target)
|
||||||
(target target)
|
(host-inputs `(,@(if source
|
||||||
(host-inputs `(,@(if source
|
`(("source" ,source))
|
||||||
`(("source" ,source))
|
'())
|
||||||
'())
|
|
||||||
,@inputs
|
|
||||||
|
|
||||||
;; Keep the standard inputs of 'gnu-build-system'
|
;,@(if target '() inputs)
|
||||||
,@(standard-packages)))
|
,@(if target inputs '())
|
||||||
(build-inputs `(("cargo" ,rust "cargo")
|
|
||||||
("rustc" ,rust)
|
,@(expand-crate-sources cargo-inputs cargo-development-inputs)))
|
||||||
,@(expand-crate-sources cargo-inputs cargo-development-inputs)
|
(build-inputs `(("cargo" ,rust "cargo")
|
||||||
,@native-inputs))
|
("rustc" ,rust)
|
||||||
(outputs outputs)
|
|
||||||
(build cargo-build)
|
,@native-inputs
|
||||||
(arguments (strip-keyword-arguments private-keywords arguments)))))
|
;,@(if target inputs '())
|
||||||
|
,@(if target '() inputs)
|
||||||
|
;,@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)
|
||||||
|
'())
|
||||||
|
|
||||||
|
;; 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
|
(define cargo-build-system
|
||||||
(build-system
|
(build-system
|
||||||
|
|
|
@ -119,6 +119,7 @@ libraries or executables."
|
||||||
(error "Possible pre-generated files found:" pregenerated-files))))
|
(error "Possible pre-generated files found:" pregenerated-files))))
|
||||||
|
|
||||||
(define* (configure #:key inputs
|
(define* (configure #:key inputs
|
||||||
|
target
|
||||||
(vendor-dir "guix-vendor")
|
(vendor-dir "guix-vendor")
|
||||||
#:allow-other-keys)
|
#:allow-other-keys)
|
||||||
"Vendor Cargo.toml dependencies as guix inputs."
|
"Vendor Cargo.toml dependencies as guix inputs."
|
||||||
|
@ -146,27 +147,74 @@ libraries or executables."
|
||||||
(invoke "tar" "xf" path "-C" crate-dir "--strip-components" "1")))))
|
(invoke "tar" "xf" path "-C" crate-dir "--strip-components" "1")))))
|
||||||
inputs)
|
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"))
|
(setenv "CARGO_HOME" (string-append (getcwd) "/.cargo"))
|
||||||
(mkdir-p ".cargo")
|
(mkdir-p ".cargo")
|
||||||
(let ((port (open-file ".cargo/config" "w" #:encoding "utf-8")))
|
(let ((port (open-file ".cargo/config.toml" "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]
|
[source.crates-io]
|
||||||
replace-with = 'vendored-sources'
|
replace-with = 'vendored-sources'
|
||||||
|
|
||||||
[source.vendored-sources]
|
[source.vendored-sources]
|
||||||
directory = '" port)
|
directory = '" vendor-dir "'") port)
|
||||||
(display (string-append (getcwd) "/" vendor-dir) port)
|
|
||||||
(display "'
|
|
||||||
" port)
|
|
||||||
(close-port port))
|
(close-port port))
|
||||||
|
|
||||||
;; Lift restriction on any lints: a crate author may have decided to opt
|
;; Lift restriction on any lints: a crate author may have decided to opt
|
||||||
;; into stricter lints (e.g. #![deny(warnings)]) during their own builds
|
;; 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
|
;; but we don't want any build failures that could be caused later by
|
||||||
;; upgrading the compiler for example.
|
;; upgrading the compiler for example.
|
||||||
(setenv "RUSTFLAGS" "--cap-lints allow")
|
(setenv "RUSTFLAGS" (string-append (or (getenv "RUSTFLAGS") "")
|
||||||
(setenv "CC" (string-append (assoc-ref inputs "gcc") "/bin/gcc"))
|
" --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 "LIBGIT2_SYS_USE_PKG_CONFIG" "1")
|
||||||
(setenv "LIBSSH2_SYS_USE_PKG_CONFIG" "1")
|
(setenv "LIBSSH2_SYS_USE_PKG_CONFIG" "1")
|
||||||
(when (assoc-ref inputs "openssl")
|
(when (assoc-ref inputs "openssl")
|
||||||
|
|
Reference in New Issue