|
| 1 | +From f4f50a5de596d13d18f1f9b80f83e446936a4afb Mon Sep 17 00:00:00 2001 |
| 2 | +From: Max Ihlenfeldt <max@igalia.com> |
| 3 | +Date: Tue, 16 Jan 2024 12:29:30 +0000 |
| 4 | +Subject: [PATCH] Adjust the Rust build to our needs |
| 5 | + |
| 6 | +1. Set `RUSTC_BOOTSTRAP=1` environment variable when calling rustc, to |
| 7 | + avoid the need of a nightly Rust toolchain. |
| 8 | +2. Copy the target.json file which rustc needs to compile for OE's |
| 9 | + custom target triple. |
| 10 | +3. Add a rust_target_triple_vendor_for_target GN arg. OE builds the |
| 11 | + Rust libraries for the target by using TARGET_VENDOR as the vendor |
| 12 | + part for the Rust "target triple", but Chromium assumes the vendor to |
| 13 | + always be "-unknown". This new arg lets us override the default when |
| 14 | + building target code. |
| 15 | + |
| 16 | +Upstream-Status: Inappropriate [specific to our build setup] |
| 17 | +Signed-off-by: Max Ihlenfeldt <max@igalia.com> |
| 18 | +--- |
| 19 | + build/config/rust.gni | 24 +++++++++++++++++------ |
| 20 | + build/rust/rustc_wrapper.py | 1 + |
| 21 | + build/rust/std/BUILD.gn | 33 ++++++++++++++++++++++++-------- |
| 22 | + build/rust/std/find_std_rlibs.py | 13 ++++++++++--- |
| 23 | + 4 files changed, 54 insertions(+), 17 deletions(-) |
| 24 | + |
| 25 | +diff --git a/build/config/rust.gni b/build/config/rust.gni |
| 26 | +index b82ac38..702353e 100644 |
| 27 | +--- a/build/config/rust.gni |
| 28 | ++++ b/build/config/rust.gni |
| 29 | +@@ -76,6 +76,11 @@ declare_args() { |
| 30 | + # a platform. Mostly applicable to Windows, where new versions can handle ANSI |
| 31 | + # escape sequences but it's not reliable in general. |
| 32 | + force_rustc_color_output = false |
| 33 | ++ |
| 34 | ++ # Override the vendor part of the Rust target triple (with a leading dash) |
| 35 | ++ # used for building target code (not host code). Leave empty to use the |
| 36 | ++ # platform default. |
| 37 | ++ rust_target_triple_vendor_for_target = "" |
| 38 | + } |
| 39 | + |
| 40 | + # Use a separate declare_args so these variables' defaults can depend on the |
| 41 | +@@ -189,12 +194,19 @@ if (enable_rust) { |
| 42 | + # other toolchains. |
| 43 | + rust_abi_target = "" |
| 44 | + if (is_linux || is_chromeos) { |
| 45 | ++ vendor = "-unknown" |
| 46 | ++ |
| 47 | ++ is_host = current_toolchain == host_toolchain || toolchain_for_rust_host_build_tools |
| 48 | ++ if (!is_host && rust_target_triple_vendor_for_target != "") { |
| 49 | ++ vendor = rust_target_triple_vendor_for_target |
| 50 | ++ } |
| 51 | ++ |
| 52 | + if (current_cpu == "arm64") { |
| 53 | +- rust_abi_target = "aarch64-unknown-linux-gnu" |
| 54 | ++ rust_abi_target = "aarch64" + vendor + "-linux-gnu" |
| 55 | + } else if (current_cpu == "x86") { |
| 56 | +- rust_abi_target = "i686-unknown-linux-gnu" |
| 57 | ++ rust_abi_target = "i686" + vendor + "-linux-gnu" |
| 58 | + } else if (current_cpu == "x64") { |
| 59 | +- rust_abi_target = "x86_64-unknown-linux-gnu" |
| 60 | ++ rust_abi_target = "x86_64" + vendor + "-linux-gnu" |
| 61 | + } else if (current_cpu == "arm") { |
| 62 | + if (arm_float_abi == "hard") { |
| 63 | + float_suffix = "hf" |
| 64 | +@@ -203,13 +215,13 @@ if (is_linux || is_chromeos) { |
| 65 | + } |
| 66 | + if (arm_arch == "armv7-a" || arm_arch == "armv7") { |
| 67 | + # No way to inform Rust about the -a suffix. |
| 68 | +- rust_abi_target = "armv7-unknown-linux-gnueabi" + float_suffix |
| 69 | ++ rust_abi_target = "armv7" + vendor + "-linux-gnueabi" + float_suffix |
| 70 | + } else { |
| 71 | +- rust_abi_target = "arm-unknown-linux-gnueabi" + float_suffix |
| 72 | ++ rust_abi_target = "arm" + vendor + "-linux-gnueabi" + float_suffix |
| 73 | + } |
| 74 | + } else { |
| 75 | + # Best guess for other future platforms. |
| 76 | +- rust_abi_target = current_cpu + "-unknown-linux-gnu" |
| 77 | ++ rust_abi_target = current_cpu + vendor + "-linux-gnu" |
| 78 | + } |
| 79 | + } else if (is_android) { |
| 80 | + import("//build/config/android/abi.gni") |
| 81 | +diff --git a/build/rust/rustc_wrapper.py b/build/rust/rustc_wrapper.py |
| 82 | +index 1c61e9f..5f9556b 100755 |
| 83 | +--- a/build/rust/rustc_wrapper.py |
| 84 | ++++ b/build/rust/rustc_wrapper.py |
| 85 | +@@ -158,6 +158,7 @@ def main(): |
| 86 | + rustc_args = remaining_args[:ldflags_separator] |
| 87 | + ldflags = remaining_args[ldflags_separator + 1:rustenv_separator] |
| 88 | + rustenv = remaining_args[rustenv_separator + 1:sources_separator] |
| 89 | ++ rustenv += ["RUSTC_BOOTSTRAP=1"] |
| 90 | + |
| 91 | + abs_build_root = os.getcwd().replace('\\', '/') + '/' |
| 92 | + is_windows = sys.platform == 'win32' or args.target_windows |
| 93 | +diff --git a/build/rust/std/BUILD.gn b/build/rust/std/BUILD.gn |
| 94 | +index 77f4b8c..8a25798 100644 |
| 95 | +--- a/build/rust/std/BUILD.gn |
| 96 | ++++ b/build/rust/std/BUILD.gn |
| 97 | +@@ -188,7 +188,8 @@ if (toolchain_has_rust) { |
| 98 | + # our locally-built std. Both reside in root_out_dir: we must only have one of |
| 99 | + # each per GN toolchain anyway. |
| 100 | + |
| 101 | +- sysroot_lib_subdir = "lib/rustlib/$rust_abi_target/lib" |
| 102 | ++ sysroot_target_subdir = "lib/rustlib/$rust_abi_target" |
| 103 | ++ sysroot_lib_subdir = "$sysroot_target_subdir/lib" |
| 104 | + |
| 105 | + if (!rust_prebuilt_stdlib) { |
| 106 | + local_rustc_sysroot = "$root_out_dir/local_rustc_sysroot" |
| 107 | +@@ -372,12 +373,12 @@ if (toolchain_has_rust) { |
| 108 | + rust_abi_target, |
| 109 | + ] |
| 110 | + |
| 111 | +- outputs = [] |
| 112 | ++ outputs = [ "$target_out_dir/target.json" ] |
| 113 | + foreach(lib, all_stdlibs_to_copy) { |
| 114 | +- outputs += [ "$target_out_dir/lib$lib.rlib" ] |
| 115 | ++ outputs += [ "$target_out_dir/lib/lib$lib.rlib" ] |
| 116 | + } |
| 117 | + foreach(lib, extra_sysroot_libs) { |
| 118 | +- outputs += [ "$target_out_dir/$lib" ] |
| 119 | ++ outputs += [ "$target_out_dir/lib/$lib" ] |
| 120 | + } |
| 121 | + |
| 122 | + visibility = [ ":*" ] |
| 123 | +@@ -390,8 +391,18 @@ if (toolchain_has_rust) { |
| 124 | + "enable_rust=false") |
| 125 | + deps = [ ":find_stdlib" ] |
| 126 | + sources = get_target_outputs(":find_stdlib") |
| 127 | +- outputs = |
| 128 | +- [ "$prebuilt_rustc_sysroot/$sysroot_lib_subdir/{{source_file_part}}" ] |
| 129 | ++ sources -= [ "$target_out_dir/target.json" ] |
| 130 | ++ outputs = [ |
| 131 | ++ "$prebuilt_rustc_sysroot/$sysroot_lib_subdir/{{source_file_part}}", |
| 132 | ++ ] |
| 133 | ++ |
| 134 | ++ visibility = [ ":*" ] |
| 135 | ++ } |
| 136 | ++ |
| 137 | ++ copy("prebuilt_rustc_copy_target_json_to_sysroot") { |
| 138 | ++ deps = [ ":find_stdlib" ] |
| 139 | ++ sources = [ "$target_out_dir/target.json" ] |
| 140 | ++ outputs = [ "$prebuilt_rustc_sysroot/$sysroot_target_subdir/target.json" ] |
| 141 | + |
| 142 | + visibility = [ ":*" ] |
| 143 | + } |
| 144 | +@@ -429,7 +440,10 @@ if (toolchain_has_rust) { |
| 145 | + # Use the sysroot generated by :prebuilt_rustc_copy_to_sysroot. |
| 146 | + group("stdlib_for_rustc") { |
| 147 | + all_dependent_configs = [ ":prebuilt_stdlib_sysroot" ] |
| 148 | +- deps = [ ":prebuilt_rustc_copy_to_sysroot" ] |
| 149 | ++ deps = [ |
| 150 | ++ ":prebuilt_rustc_copy_to_sysroot", |
| 151 | ++ ":prebuilt_rustc_copy_target_json_to_sysroot", |
| 152 | ++ ] |
| 153 | + } |
| 154 | + |
| 155 | + # Links the Rust stdlib. Used by targets for which linking is driven by |
| 156 | +@@ -439,7 +453,10 @@ if (toolchain_has_rust) { |
| 157 | + ":prebuilt_stdlib_libs", |
| 158 | + ":stdlib_public_dependent_libs", |
| 159 | + ] |
| 160 | +- deps = [ ":prebuilt_rustc_copy_to_sysroot" ] |
| 161 | ++ deps = [ |
| 162 | ++ ":prebuilt_rustc_copy_to_sysroot", |
| 163 | ++ ":prebuilt_rustc_copy_target_json_to_sysroot", |
| 164 | ++ ] |
| 165 | + |
| 166 | + # The host builds tools toolchain supports Rust only and does not use |
| 167 | + # the allocator remapping to point it to PartitionAlloc. |
| 168 | +diff --git a/build/rust/std/find_std_rlibs.py b/build/rust/std/find_std_rlibs.py |
| 169 | +index 386258f..25fdedc 100755 |
| 170 | +--- a/build/rust/std/find_std_rlibs.py |
| 171 | ++++ b/build/rust/std/find_std_rlibs.py |
| 172 | +@@ -52,6 +52,8 @@ def main(): |
| 173 | + rustc_args.extend(["--target", args.target]) |
| 174 | + rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode() |
| 175 | + |
| 176 | ++ lib_output_dir = os.path.join(args.output, 'lib') |
| 177 | ++ |
| 178 | + # Copy the rlibs to a predictable location. Whilst we're doing so, |
| 179 | + # also write a .d file so that ninja knows it doesn't need to do this |
| 180 | + # again unless the source rlibs change. |
| 181 | +@@ -63,7 +65,7 @@ def main(): |
| 182 | + # output rlibs for that purpose. If any of the input rlibs change, ninja |
| 183 | + # will run this script again and we'll copy them all afresh. |
| 184 | + depfile.write( |
| 185 | +- "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target))) |
| 186 | ++ "%s:" % (os.path.join(lib_output_dir, "lib%s.rlib" % args.depfile_target))) |
| 187 | + |
| 188 | + def copy_file(infile, outfile): |
| 189 | + depfile.write(f" {infile}") |
| 190 | +@@ -117,14 +119,19 @@ def main(): |
| 191 | + output_filename = f"lib{concise_name}.rlib" |
| 192 | + |
| 193 | + infile = os.path.join(rustlib_dir, f) |
| 194 | +- outfile = os.path.join(args.output, output_filename) |
| 195 | ++ outfile = os.path.join(lib_output_dir, output_filename) |
| 196 | + copy_file(infile, outfile) |
| 197 | + |
| 198 | + for f in extra_libs: |
| 199 | + infile = os.path.join(rustlib_dir, f) |
| 200 | +- outfile = os.path.join(args.output, f) |
| 201 | ++ outfile = os.path.join(lib_output_dir, f) |
| 202 | + copy_file(infile, outfile) |
| 203 | + |
| 204 | ++ f = 'target.json' |
| 205 | ++ infile = os.path.join(rustlib_dir, '..', f) |
| 206 | ++ outfile = os.path.join(args.output, f) |
| 207 | ++ copy_file(infile, outfile) |
| 208 | ++ |
| 209 | + depfile.write("\n") |
| 210 | + |
| 211 | + |
0 commit comments