guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

02/02: gnu: Add rust-i686-linux.


From: guix-commits
Subject: 02/02: gnu: Add rust-i686-linux.
Date: Tue, 30 Nov 2021 22:35:16 -0500 (EST)

apteryx pushed a commit to branch wip-cross-built-rust
in repository guix.

commit a05951f72fe4824cc73a963a5ed18ca039a6b5de
Author: Maxim Cournoyer <maxim.cournoyer@gmail.com>
AuthorDate: Sun Nov 28 23:41:26 2021 -0500

    gnu: Add rust-i686-linux.
    
    * gnu/packages/rust.scm (rust-bootstrapped-package)
    [version, checksum]: Make arguments optional.
    (rust-i686-linux): 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                              | 211 +++++++++++++++++++--
 3 files changed, 275 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..61bdf02 100644
--- a/gnu/packages/rust.scm
+++ b/gnu/packages/rust.scm
@@ -42,6 +42,7 @@
   #:use-module (gnu packages jemalloc)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages llvm)
+  #:use-module (gnu packages ninja)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
   #:use-module (gnu packages ssh)
@@ -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,178 @@ 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)
+
+(define (force-system p system)
+  (package/inherit p
+    (arguments
+     (substitute-keyword-arguments (package-arguments p)
+       ((#:system _ #f) system)))))
+
+(define force-i686 (cut force-system <> "i686-linux"))
+
+;;; Rust cross-built for i686-linux.
+;;; TODO: Make a procedure of it that returns a cross-built rust package.
+(define-public rust-i686-linux
+  (let* ((base-rust (rust-bootstrapped-package rust))
+         (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")
+      (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")))
+             (add-after 'unpack 'remove-cross-linker-from-path
+               ;; This wrapper shouldn't appear on PATH; it is to be used
+               ;; exclusively by the rustc wrap phase.
+               (lambda* (#:key native-inputs #:allow-other-keys)
+                 (let ((cross-ld-wrapper (assoc-ref native-inputs
+                                                    "cross-ld-wrapper")))
+                   (when cross-ld-wrapper
+                     (let* ((cross-ld-wrapper-bin (string-append
+                                                   cross-ld-wrapper "/bin"))
+                            (paths (string-split (getenv "PATH") #\:))
+                            (new-paths (remove (lambda (p)
+                                                 (string=? cross-ld-wrapper-bin
+                                                           p))
+                                               paths)))
+                       (setenv "PATH" (string-join new-paths ":")))))))
+             ;; 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]
+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")))
+                       (gcc (assoc-ref inputs "cross-gcc")))
+                   (invoke "./x.py" job-spec "build"
+                           "--stage=2" "--host=i686-unknown-linux-gnu"
+                           "--target=i686-unknown-linux-gnu"
+                           "compiler/rustc"
+                           "library/std"
+                           "src/tools/cargo"
+                           "src/tools/rustfmt"))))
+             (replace 'install
+               ;; Phase overridden to also install rustfmt.
+               (lambda* (#:key outputs #:allow-other-keys)
+                 (define out (assoc-ref outputs "out"))
+                 (invoke "./x.py" "install" "--host=i686-unknown-linux-gnu"
+                         "--target=i686-unknown-linux-gnu")
+                 (substitute* "config.toml"
+                   ;; Adjust the prefix to the 'cargo' output.
+                   (("prefix = \"[^\"]*\"")
+                    (format #f "prefix = ~s" (assoc-ref outputs "cargo"))))
+                 (invoke "./x.py" "install" "--host=i686-unknown-linux-gnu"
+                         "--target=i686-unknown-linux-gnu"
+                         "cargo")
+                 (substitute* "config.toml"
+                   ;; Adjust the prefix to the 'rustfmt' output.
+                   (("prefix = \"[^\"]*\"")
+                    (format #f "prefix = ~s" (assoc-ref outputs "rustfmt"))))
+                 (invoke "./x.py" "install" "--host=i686-unknown-linux-gnu"
+                         "--target=i686-unknown-linux-gnu"
+                         "rustfmt")))
+             (replace 'wrap-rustc
+               (lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
+                 (let ((out (assoc-ref outputs "out"))
+                       (libc (assoc-ref inputs "cross-libc"))
+                       (ld-wrapper (assoc-ref native-inputs 
"cross-ld-wrapper")))
+                   ;; Let gcc find ld and libc startup files.
+                   (wrap-program (string-append out "/bin/rustc")
+                     `("PATH" ":" prefix (,(string-append ld-wrapper "/bin")))
+                     `("LIBRARY_PATH" ":"
+                       suffix (,(string-append libc "/lib")))))))))))
+      (native-inputs
+       `(("ninja" ,ninja)
+         ("llvm" ,llvm-12)
+         ("openssl", openssl)
+         ("libssh2" ,libssh2)
+         ("libcurl" ,curl)
+         ;; FIXME: allow ld-wrapper to cross-compile so that it can be used
+         ;; for other targets than i686.  When fixed, simply add 'ld-wrapper'
+         ;; to inputs.
+         ("cross-ld-wrapper" ,(force-i686
+                               (module-ref (resolve-interface
+                                            '(gnu packages commencement))
+                                           'ld-wrapper)))
+         ,@(package-native-inputs base-rust)))
+      (propagated-inputs '())
+      (supported-systems '("x86_64-linux")))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]