[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
02/03: gnu: Add rust-i686-linux-cross.
From: |
guix-commits |
Subject: |
02/03: gnu: Add rust-i686-linux-cross. |
Date: |
Fri, 3 Dec 2021 11:10:20 -0500 (EST) |
apteryx pushed a commit to branch wip-cross-built-rust
in repository guix.
commit 4de521e0b0774df92642ff733e4c641cad2e6720
Author: Maxim Cournoyer <maxim.cournoyer@gmail.com>
AuthorDate: Sun Nov 28 23:41:26 2021 -0500
gnu: Add rust-i686-linux-cross.
* gnu/packages/rust.scm (rust-bootstrapped-package)
[version, checksum]: Make arguments optional.
(rust-i686-linux-cross): New variable.
* gnu/packages/patches/rust-per-target-default-linker.patch: New file.
* gnu/local.mk (dist_patch_DATA): Register it.
---
gnu/local.mk | 1 +
.../patches/rust-per-target-default-linker.patch | 77 +++++++++
gnu/packages/rust.scm | 177 +++++++++++++++++++--
3 files changed, 241 insertions(+), 14 deletions(-)
diff --git a/gnu/local.mk b/gnu/local.mk
index 1063269..27fa92d 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1735,6 +1735,7 @@ dist_patch_DATA =
\
%D%/packages/patches/rocm-opencl-runtime-4.3-noopencl.patch \
%D%/packages/patches/ruby-sanitize-system-libxml.patch \
%D%/packages/patches/rustc-1.39.0-src.patch \
+ %D%/packages/patches/rust-per-target-default-linker.patch \
%D%/packages/patches/rust-adblock-ignore-live-tests.patch \
%D%/packages/patches/rust-coresimd-doctest.patch \
%D%/packages/patches/rust-ndarray-remove-blas-src-dep.patch \
diff --git a/gnu/packages/patches/rust-per-target-default-linker.patch
b/gnu/packages/patches/rust-per-target-default-linker.patch
new file mode 100644
index 0000000..d07d993
--- /dev/null
+++ b/gnu/packages/patches/rust-per-target-default-linker.patch
@@ -0,0 +1,77 @@
+diff --git a/config.toml.example b/config.toml.example
+index 4dd953a495d..fba15213f4b 100644
+--- a/config.toml.example
++++ b/config.toml.example
+@@ -488,9 +488,11 @@ changelog-seen = 2
+ # FIXME(#75760): Some UI tests fail when this option is enabled.
+ #parallel-compiler = false
+
+-# The default linker that will be hard-coded into the generated compiler for
+-# targets that don't specify linker explicitly in their target specifications.
+-# Note that this is not the linker used to link said compiler.
++# The default linker that will be hard-coded into the generated
++# compiler for targets that don't specify linker explicitly in their
++# target specifications. Note that this is not the linker used to
++# link said compiler. It can also be set per-target, which may be
++# useful for example in a cross-compilation setting.
+ #
+ # See https://doc.rust-lang.org/rustc/codegen-options/index.html#linker for
more information.
+ #default-linker = <none> (path)
+diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
+index 007ca9f7f5a..8fb11d79a55 100644
+--- a/src/bootstrap/compile.rs
++++ b/src/bootstrap/compile.rs
+@@ -661,6 +661,8 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut
Cargo, target: TargetS
+ .env("CFG_VERSION", builder.rust_version());
+
+ let libdir_relative = builder.config.libdir_relative().unwrap_or_else(||
Path::new("lib"));
++ let target_config = builder.config.target_config.get(&target);
++
+ cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
+
+ if let Some(ref ver_date) = builder.rust_info.commit_date() {
+@@ -672,9 +674,15 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut
Cargo, target: TargetS
+ if !builder.unstable_features() {
+ cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
+ }
+- if let Some(ref s) = builder.config.rustc_default_linker {
++
++ // Prefer the current target's own default_linker, else a globally
++ // specified one.
++ if let Some(s) = target_config.and_then(|c| c.default_linker.as_ref()) {
++ cargo.env("CFG_DEFAULT_LINKER", s);
++ } else if let Some(ref s) = builder.config.rustc_default_linker {
+ cargo.env("CFG_DEFAULT_LINKER", s);
+ }
++
+ if builder.config.rustc_parallel {
+ cargo.rustflag("--cfg=parallel_compiler");
+ cargo.rustdocflag("--cfg=parallel_compiler");
+@@ -699,7 +707,6 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut
Cargo, target: TargetS
+ }
+ let llvm_config = builder.ensure(native::Llvm { target });
+ cargo.env("LLVM_CONFIG", &llvm_config);
+- let target_config = builder.config.target_config.get(&target);
+ if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+ cargo.env("CFG_LLVM_ROOT", s);
+ }
+diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
+index 68e20f90b7f..3475cf5075e 100644
+--- a/src/bootstrap/config.rs
++++ b/src/bootstrap/config.rs
+@@ -294,6 +294,7 @@ pub struct Target {
+ pub cxx: Option<PathBuf>,
+ pub ar: Option<PathBuf>,
+ pub ranlib: Option<PathBuf>,
++ pub default_linker: Option<PathBuf>,
+ pub linker: Option<PathBuf>,
+ pub ndk: Option<PathBuf>,
+ pub sanitizers: Option<bool>,
+@@ -531,6 +532,7 @@ struct TomlTarget {
+ cxx: Option<String>,
+ ar: Option<String>,
+ ranlib: Option<String>,
++ default_linker: Option<String>,
+ linker: Option<String>,
+ llvm_config: Option<String>,
+ llvm_filecheck: Option<String>,
diff --git a/gnu/packages/rust.scm b/gnu/packages/rust.scm
index 2a43e88..99107c5 100644
--- a/gnu/packages/rust.scm
+++ b/gnu/packages/rust.scm
@@ -30,6 +30,7 @@
(define-module (gnu packages rust)
#:use-module (gnu packages base)
+ #:use-module (gnu packages bash)
#:use-module (gnu packages bison)
#:use-module (gnu packages bootstrap)
#:use-module (gnu packages cmake)
@@ -102,20 +103,27 @@
(string-append "https://" dist ".rust-lang.org/dist/"
"rustc-" version "-src.tar.gz"))
-(define* (rust-bootstrapped-package base-rust version checksum)
- "Bootstrap rust VERSION with source checksum CHECKSUM using BASE-RUST."
- (package
- (inherit base-rust)
- (version version)
- (source
- (origin
- (inherit (package-source base-rust))
- (uri (rust-uri version))
- (sha256 (base32 checksum))))
- (native-inputs
- (alist-replace "cargo-bootstrap" (list base-rust "cargo")
- (alist-replace "rustc-bootstrap" (list base-rust)
- (package-native-inputs base-rust))))))
+(define* (rust-bootstrapped-package base-rust
+ #:optional
+ (version (package-version base-rust))
+ checksum)
+ "Bootstrap rust VERSION with source checksum CHECKSUM using BASE-RUST. When
+CHECKSUM is omitted, the source of BASE-RUST is reused."
+ (let ((base-source (package-source base-rust)))
+ (package
+ (inherit base-rust)
+ (version version)
+ (source
+ (if checksum
+ (origin
+ (inherit base-source)
+ (uri (rust-uri version))
+ (sha256 (base32 checksum)))
+ base-source))
+ (native-inputs
+ (alist-replace "cargo-bootstrap" (list base-rust "cargo")
+ (alist-replace "rustc-bootstrap" (list base-rust)
+ (package-native-inputs base-rust)))))))
;;; Note: mrustc's only purpose is to be able to bootstap Rust; it's designed
;;; to be used in source form. The latest support for bootstrapping from
@@ -776,3 +784,144 @@ safety and thread safety guarantees.")
;;; be relied upon. This is to ease maintenance and reduce the time
;;; required to build the full Rust bootstrap chain.
(define-public rust rust-1.54)
+
+;;; Rust cross-built for i686-linux.
+;;; TODO: Build statically.
+;;; TODO: Make a procedure of it that returns a cross-built rust package.
+(define-public rust-i686-linux-cross
+ (let* ((base-rust (rust-bootstrapped-package rust-x86-64-linux))
+ (base-source (package-source base-rust)))
+ (package/inherit base-rust
+ (source (origin
+ (inherit base-source)
+ (patches (append (search-patches
+ "rust-per-target-default-linker.patch")
+ (origin-patches base-source)))))
+ (name "rust-i686-linux-cross")
+ (outputs '("out"))
+ (arguments
+ (substitute-keyword-arguments (package-arguments base-rust)
+ ((#:target _ #f) "i686-linux-gnu")
+ ((#:tests? _ #f) #f) ;cannot test cross-built rust
+ ((#:phases phases)
+ `(modify-phases ,phases
+ (replace 'set-env
+ ;; Overridden to not set CC for the cross-compiler.
+ ;; TODO: Use linker option in main rust; do not set CC.
+ (lambda* (#:key inputs #:allow-other-keys)
+ (setenv "SHELL" (which "sh"))
+ (setenv "CONFIG_SHELL" (which "sh"))
+ ;; The Guix LLVM package installs only shared libraries.
+ (setenv "LLVM_LINK_SHARED" "1")))
+ ;; Delete test-related phases since we do not run tests and
+ ;; look their inputs in 'inputs' incorrectly.
+ ;; TODO: Fix rust to use (or native-inputs inputs) when looking
+ ;; for its inputs, then we can keep the patching.
+ ;; FIXME: Oops! 500 MiB of doc. Should be installed to its own
output.
+ (delete 'enable-docs)
+ (delete 'add-gdb-to-config)
+ (delete 'patch-process-tests) ;no bash in cross-compiled env
+ (replace 'configure
+ (lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (binutils (assoc-ref native-inputs "cross-binutils"))
+ (binutils-native (assoc-ref native-inputs "binutils"))
+ (gcc (assoc-ref inputs "cross-gcc"))
+ (gcc-native (assoc-ref native-inputs "gcc"))
+ (llvm (assoc-ref inputs "llvm"))
+ (llvm-native (assoc-ref native-inputs "llvm"))
+ (python (assoc-ref native-inputs "python"))
+ (rustc (assoc-ref native-inputs "rustc-bootstrap"))
+ (cargo (assoc-ref native-inputs "cargo-bootstrap"))
+ (openssl (assoc-ref inputs "openssl")))
+ ;; pkg-config doesn't detect the libraries correctly in a
+ ;; cross compilation setting and causes cargo to link with
+ ;; the native libraries. Configure the locations manually.
+ (setenv "I686_UNKNOWN_LINUX_GNU_OPENSSL_DIR" openssl)
+ ;; Note: jemalloc is disabled, since the JEMALLOC_OVERRIDE
+ ;; variable necessary to have the system version used is
+ ;; global (not per-target specific). This is problematic
+ ;; as rustc needs to build artifacts for both the host and
+ ;; the target during cross-compilation.
+ (call-with-output-file "config.toml"
+ (lambda (port)
+ (display (string-append "
+[llvm]
+[build]
+host = [\"i686-unknown-linux-gnu\"]
+cargo = \"" cargo "/bin/cargo" "\"
+rustc = \"" rustc "/bin/rustc" "\"
+docs = false
+python = \"" python "/bin/python" "\"
+vendor = true
+submodules = false
+[install]
+prefix = \"" out "\"
+sysconfdir = \"etc\"
+[rust]
+jemalloc=false
+channel = \"stable\"
+rpath = true
+[target." ,(nix-system->gnu-triplet-for-rust) "]
+default-linker = \"" gcc-native "/bin/gcc" "\"
+linker = \"" gcc-native "/bin/gcc" "\"
+llvm-config = \"" llvm-native "/bin/llvm-config" "\"
+cc = \"" gcc-native "/bin/gcc" "\"
+cxx = \"" gcc-native "/bin/g++" "\"
+ar = \"" binutils-native "/bin/ar" "\"
+[target.i686-unknown-linux-gnu]
+default-linker = \"" gcc "/bin/i686-linux-gnu-gcc" "\"
+linker = \"" gcc "/bin/i686-linux-gnu-gcc" "\"
+llvm-config = \"" llvm "/bin/llvm-config" "\"
+cc = \"" gcc "/bin/i686-linux-gnu-gcc" "\"
+cxx = \"" gcc "/bin/i686-linux-gnu-g++" "\"
+ar = \"" binutils "/bin/i686-linux-gnu-ar" "\"
+[dist]
+") port))))))
+ (replace 'build
+ (lambda* (#:key inputs parallel-build? #:allow-other-keys)
+ (let ((job-spec (string-append
+ "-j" (if parallel-build?
+ (number->string
(parallel-job-count))
+ "1"))))
+ (invoke "./x.py" job-spec "build"
+ "compiler/rustc"
+ "library/std"
+ "src/tools/cargo"))))
+ (replace 'install
+ (lambda* (#:key outputs #:allow-other-keys)
+ (invoke "./x.py" "install")
+ (invoke "./x.py" "install" "cargo")))
+ ;; Using ld-wrapper is problematic as it doesn't cross compile;
+ ;; the Guix-provided (in cross-gcc "lib" output) libgcc_s.so
+ ;; should also be used by the rustc-produced binaries (by adding
+ ;; it to LIBRARY_PATH?).
+ (delete 'wrap-rustc)))))
+ (native-inputs
+ `(("llvm" ,llvm-12)
+ ("openssl", openssl)
+ ("libssh2" ,libssh2)
+ ("libcurl" ,curl)
+ ,@(package-native-inputs base-rust)))
+ (inputs `(("bash" ,bash) ;for the patch-shebangs phase
+ ,@(package-inputs base-rust)))
+ (propagated-inputs '())
+ (supported-systems '("x86_64-linux")))))
+
+;;; WIP:
+;;
+;; (define-public rust-i686-linux-bootstrap
+;; (package/inherit rust-i686-linux-cross
+;; (name "rust-i686-linux-bootstrap")
+;; (source (origin
+;; (method url-fetch)
+;; (uri "file:///srv/")
+;; (sha256
+;; (base32
+;; ""))))
+;; (build-system )
+;; (synopsis "Rust bootstrap for i686-linux")
+;; (description "Pre-built i686-linux Rust for bootstrapping purposes.")
+;; (supported-systems '("i686-linux"))))
+
+;;; Use the above to bootstrap a rust-i686-linux package.