Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chromium: Enable Rust #782

Merged
merged 3 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion meta-chromium/conf/layer.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ BBFILE_PATTERN_chromium-browser-layer := "^${LAYERDIR}/"
BBFILE_PRIORITY_chromium-browser-layer = "7"

LAYERVERSION_chromium-browser-layer = "1"
LAYERSERIES_COMPAT_chromium-browser-layer = "dunfell gatesgarth hardknott honister kirkstone langdale mickledore nanbield"
LAYERSERIES_COMPAT_chromium-browser-layer = "kirkstone langdale mickledore nanbield"

LAYERDEPENDS_chromium-browser-layer = "clang-layer core openembedded-layer"
68 changes: 63 additions & 5 deletions meta-chromium/recipes-browser/chromium/chromium-gn.inc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SRC_URI += "\
file://backport/IWYU-for-chrome-browser-ui-tabs-organizatio.patch \
file://backport/IWYU-for-content-browser-generic_sensor-fra.patch \
file://backport/IWYU-for-g-c-service-shared_image-ozone_ima.patch \
file://backport/Make-toolchain_supports_rust_thin_lto-configurable.patch \
"
# Non-specific patches.
SRC_URI += "\
Expand All @@ -45,6 +46,8 @@ SRC_URI += "\
file://0020-Fix-implicitly-deleted-default-constructor-build-err.patch \
file://0021-Don-t-delete-CrashKeyWithName-dtor.patch \
file://0022-Use-base-ranges-instead-of-std-ranges.patch \
file://0023-Use-the-correct-path-to-libclang_rt.builtins.a.patch \
file://0024-Adjust-the-Rust-build-to-our-needs.patch \
"
# ARM/AArch64-specific patches.
SRC_URI:append:arm = "\
Expand Down Expand Up @@ -107,9 +110,11 @@ DEPENDS += " \
pkgconfig-native \
${@bb.utils.contains('DISTRO_FEATURES', 'pulseaudio', 'pulseaudio', '', d)} \
qemu-native \
rust \
rust-native \
virtual/libgl \
"
DEPEND:append:runtime-llvm = " compiler-rt-native libcxx-native"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, does this mean that this line was completely broken before?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was working before, but when Rust is enabled Chromium needs to link against the target clang runtime libraries, see https://source.chromium.org/chromium/chromium/src/+/main:build/config/compiler/BUILD.gn;l=1660-1668;drc=ab6484854e1fb7a38160336acc6b34b6ecdda628.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but does it mean the previous variable name was incorrect and therefore the assignment did not have any effect?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right, I overlooked that I changed that as well. Yes, that might have indeed been the case 😅

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. That might explain some of the bug reports we've had over the years :-) Glad to see it's been fixed.

DEPENDS:append:runtime-llvm = " compiler-rt compiler-rt-native libcxx-native"
DEPENDS:append:libc-musl = " libexecinfo"

LDFLAGS:append:libc-musl = " -lexecinfo"
Expand Down Expand Up @@ -306,19 +311,36 @@ GN_ARGS += ' \
gold_path="" \
host_toolchain="//build/toolchain/yocto:yocto_native" \
is_clang=true \
clang_base_path="${@clang_install_path(d)}" \
clang_use_chrome_plugins=false \
target_cpu="${@gn_target_arch_name(d)}" \
v8_snapshot_toolchain="//build/toolchain/yocto:yocto_target" \
'

# Make sure Chromium is able to find clang libraries. See
# 0023-Use-the-correct-path-to-libclang_rt.builtins.a.patch and the
# add_clang_symlink and copy_clang_library tasks for more context.
GN_ARGS += ' \
clang_base_path="${@clang_install_path(d)}" \
clang_version="latest" \
'

# This parameter is added by limit-number-of-LTO-jobs.patch with the default value of 8,
# but we can use whatever user configured in PARALLEL_MAKE
GN_ARGS += 'max_jobs_per_link="${@oe.utils.parallel_make_argument(d, '%d')}"'

# We haven't figured out how to best support Rust yet, so disable it for now.
# See the discussion at https://github.com/OSSystems/meta-browser/issues/723.
GN_ARGS += 'enable_rust=false'
# Use our own toolchain instead of the one upstream provides. See
# //build/config/rust.gni for more details.
# Note: the value of rustc_version doesn't matter, it's only used to ensure all
# Rust code is rebuilt after updating the Rust toolchain. This is irrelevant for
# our build setup, but not setting it leads to an error.
GN_ARGS += ' \
rust_sysroot_absolute="${RECIPE_SYSROOT_NATIVE}/usr" \
rustc_version="custom" \
rust_target_triple_vendor_for_target="${TARGET_VENDOR}" \
'

# This would require the Rust toolchain to use the same LLVM version as clang.
GN_ARGS += 'toolchain_supports_rust_thin_lto=false'

# ARM builds need special additional flags (see ${S}/build/config/arm.gni).
# If we do not pass |arm_arch| and friends to GN, it will deduce a value that
Expand Down Expand Up @@ -442,6 +464,42 @@ do_add_nodejs_symlink () {
}
addtask add_nodejs_symlink after do_configure before do_compile

do_add_clang_symlink () {
# Creates a `latest` symlink in the native sysroot's /usr/lib/clang
# directory that points to /usr/lib/clang/$CLANG_VERSION. Chromium manually
# links against libclang_rt.builtins.a and uses the `clang_version` GN
# variable to find it. This allows us to set it to the same value for all
# Yocto releases.
cd "${RECIPE_SYSROOT_NATIVE}/usr/lib/clang"
# find the directory containing the library
for dir in *; do
if [ -n "$(find $dir -name 'libclang_rt.builtins*')" ] ; then
ln -sf "$dir" latest
break
fi
done
}
addtask add_clang_symlink after do_configure before do_compile

do_copy_clang_library () {
# Chromium needs to link against libclang_rt.builtins.a for both host and
# target code, and expects to find both libraries in the same directory
# (thanks to 0023-Use-the-correct-path-to-libclang_rt.builtins.a.patch).
cd "${RECIPE_SYSROOT}"
lib_file="$(find usr/lib/clang -name 'libclang_rt.builtins*')"
lib_dir="$(dirname $lib_file)"
cp "$lib_file" "${RECIPE_SYSROOT_NATIVE}/$lib_dir"
}
addtask copy_clang_library after do_configure before do_compile

do_copy_target_rustlibs () {
# Chromium needs a single Rust sysroot that contains the rustlibs for both
# the host and target, so we copy the target rustlibs to the native sysroot.
rustlib_src_dir="${RECIPE_SYSROOT}/usr/lib/rustlib/${TARGET_ARCH}"*
cp -r $rustlib_src_dir "${RECIPE_SYSROOT_NATIVE}/usr/lib/rustlib"
}
addtask copy_target_rustlibs after do_configure before do_compile

do_configure() {
cd ${S}
python3 ./build/linux/unbundle/replace_gn_files.py --system-libraries ${GN_UNBUNDLE_LIBS}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
From 334f64aafb062324a9124a13855128dfe733c0c2 Mon Sep 17 00:00:00 2001
From: Max Ihlenfeldt <[email protected]>
Date: Tue, 19 Dec 2023 12:14:05 +0000
Subject: [PATCH] Use the correct path to libclang_rt.builtins.a

Chromium needs to link against libclang_rt.builtins.a, but it expects
it in a slightly different directory than where it actually is in our
sysroot. Thus, we need adjust the where Chromium looks for the library.

Note that the directory used by this patch is actually independent of
the target architecture. This has the added benefit that we can just
copy the target's libclang_rt.builtins.a to the host's sysroot (to the
same directory where the host's library is). This is necessary because
Chromium needs to link against this library for both host and target
code, but only allows us to specify a single `clang_base_path`.

Upstream-Status: Inappropriate [specific to our sysroot setup]
Signed-off-by: Max Ihlenfeldt <[email protected]>
---
build/config/clang/BUILD.gn | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
index 46f4de0..ad3bfc4 100644
--- a/build/config/clang/BUILD.gn
+++ b/build/config/clang/BUILD.gn
@@ -122,14 +122,15 @@ template("clang_lib") {
} else if (is_apple) {
_dir = "darwin"
} else if (is_linux || is_chromeos) {
+ _dir = "linux"
if (current_cpu == "x64") {
- _dir = "x86_64-unknown-linux-gnu"
+ _suffix = "-x86_64"
} else if (current_cpu == "x86") {
- _dir = "i386-unknown-linux-gnu"
+ _suffix = "-i386"
} else if (current_cpu == "arm") {
- _dir = "armv7-unknown-linux-gnueabihf"
+ _suffix = "-armhf"
} else if (current_cpu == "arm64") {
- _dir = "aarch64-unknown-linux-gnu"
+ _suffix = "-aarch64"
} else {
assert(false) # Unhandled cpu type
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
From f4f50a5de596d13d18f1f9b80f83e446936a4afb Mon Sep 17 00:00:00 2001
From: Max Ihlenfeldt <[email protected]>
Date: Tue, 16 Jan 2024 12:29:30 +0000
Subject: [PATCH] Adjust the Rust build to our needs

1. Set `RUSTC_BOOTSTRAP=1` environment variable when calling rustc, to
avoid the need of a nightly Rust toolchain.
2. Copy the target.json file which rustc needs to compile for OE's
custom target triple.
3. Add a rust_target_triple_vendor_for_target GN arg. OE builds the
Rust libraries for the target by using TARGET_VENDOR as the vendor
part for the Rust "target triple", but Chromium assumes the vendor to
always be "-unknown". This new arg lets us override the default when
building target code.

Upstream-Status: Inappropriate [specific to our build setup]
Signed-off-by: Max Ihlenfeldt <[email protected]>
---
build/config/rust.gni | 24 +++++++++++++++++------
build/rust/rustc_wrapper.py | 1 +
build/rust/std/BUILD.gn | 33 ++++++++++++++++++++++++--------
build/rust/std/find_std_rlibs.py | 13 ++++++++++---
4 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/build/config/rust.gni b/build/config/rust.gni
index b82ac38..702353e 100644
--- a/build/config/rust.gni
+++ b/build/config/rust.gni
@@ -76,6 +76,11 @@ declare_args() {
# a platform. Mostly applicable to Windows, where new versions can handle ANSI
# escape sequences but it's not reliable in general.
force_rustc_color_output = false
+
+ # Override the vendor part of the Rust target triple (with a leading dash)
+ # used for building target code (not host code). Leave empty to use the
+ # platform default.
+ rust_target_triple_vendor_for_target = ""
}

# Use a separate declare_args so these variables' defaults can depend on the
@@ -189,12 +194,19 @@ if (enable_rust) {
# other toolchains.
rust_abi_target = ""
if (is_linux || is_chromeos) {
+ vendor = "-unknown"
+
+ is_host = current_toolchain == host_toolchain || toolchain_for_rust_host_build_tools
+ if (!is_host && rust_target_triple_vendor_for_target != "") {
+ vendor = rust_target_triple_vendor_for_target
+ }
+
if (current_cpu == "arm64") {
- rust_abi_target = "aarch64-unknown-linux-gnu"
+ rust_abi_target = "aarch64" + vendor + "-linux-gnu"
} else if (current_cpu == "x86") {
- rust_abi_target = "i686-unknown-linux-gnu"
+ rust_abi_target = "i686" + vendor + "-linux-gnu"
} else if (current_cpu == "x64") {
- rust_abi_target = "x86_64-unknown-linux-gnu"
+ rust_abi_target = "x86_64" + vendor + "-linux-gnu"
} else if (current_cpu == "arm") {
if (arm_float_abi == "hard") {
float_suffix = "hf"
@@ -203,13 +215,13 @@ if (is_linux || is_chromeos) {
}
if (arm_arch == "armv7-a" || arm_arch == "armv7") {
# No way to inform Rust about the -a suffix.
- rust_abi_target = "armv7-unknown-linux-gnueabi" + float_suffix
+ rust_abi_target = "armv7" + vendor + "-linux-gnueabi" + float_suffix
} else {
- rust_abi_target = "arm-unknown-linux-gnueabi" + float_suffix
+ rust_abi_target = "arm" + vendor + "-linux-gnueabi" + float_suffix
}
} else {
# Best guess for other future platforms.
- rust_abi_target = current_cpu + "-unknown-linux-gnu"
+ rust_abi_target = current_cpu + vendor + "-linux-gnu"
}
} else if (is_android) {
import("//build/config/android/abi.gni")
diff --git a/build/rust/rustc_wrapper.py b/build/rust/rustc_wrapper.py
index 1c61e9f..5f9556b 100755
--- a/build/rust/rustc_wrapper.py
+++ b/build/rust/rustc_wrapper.py
@@ -158,6 +158,7 @@ def main():
rustc_args = remaining_args[:ldflags_separator]
ldflags = remaining_args[ldflags_separator + 1:rustenv_separator]
rustenv = remaining_args[rustenv_separator + 1:sources_separator]
+ rustenv += ["RUSTC_BOOTSTRAP=1"]

abs_build_root = os.getcwd().replace('\\', '/') + '/'
is_windows = sys.platform == 'win32' or args.target_windows
diff --git a/build/rust/std/BUILD.gn b/build/rust/std/BUILD.gn
index 77f4b8c..8a25798 100644
--- a/build/rust/std/BUILD.gn
+++ b/build/rust/std/BUILD.gn
@@ -188,7 +188,8 @@ if (toolchain_has_rust) {
# our locally-built std. Both reside in root_out_dir: we must only have one of
# each per GN toolchain anyway.

- sysroot_lib_subdir = "lib/rustlib/$rust_abi_target/lib"
+ sysroot_target_subdir = "lib/rustlib/$rust_abi_target"
+ sysroot_lib_subdir = "$sysroot_target_subdir/lib"

if (!rust_prebuilt_stdlib) {
local_rustc_sysroot = "$root_out_dir/local_rustc_sysroot"
@@ -372,12 +373,12 @@ if (toolchain_has_rust) {
rust_abi_target,
]

- outputs = []
+ outputs = [ "$target_out_dir/target.json" ]
foreach(lib, all_stdlibs_to_copy) {
- outputs += [ "$target_out_dir/lib$lib.rlib" ]
+ outputs += [ "$target_out_dir/lib/lib$lib.rlib" ]
}
foreach(lib, extra_sysroot_libs) {
- outputs += [ "$target_out_dir/$lib" ]
+ outputs += [ "$target_out_dir/lib/$lib" ]
}

visibility = [ ":*" ]
@@ -390,8 +391,18 @@ if (toolchain_has_rust) {
"enable_rust=false")
deps = [ ":find_stdlib" ]
sources = get_target_outputs(":find_stdlib")
- outputs =
- [ "$prebuilt_rustc_sysroot/$sysroot_lib_subdir/{{source_file_part}}" ]
+ sources -= [ "$target_out_dir/target.json" ]
+ outputs = [
+ "$prebuilt_rustc_sysroot/$sysroot_lib_subdir/{{source_file_part}}",
+ ]
+
+ visibility = [ ":*" ]
+ }
+
+ copy("prebuilt_rustc_copy_target_json_to_sysroot") {
+ deps = [ ":find_stdlib" ]
+ sources = [ "$target_out_dir/target.json" ]
+ outputs = [ "$prebuilt_rustc_sysroot/$sysroot_target_subdir/target.json" ]

visibility = [ ":*" ]
}
@@ -429,7 +440,10 @@ if (toolchain_has_rust) {
# Use the sysroot generated by :prebuilt_rustc_copy_to_sysroot.
group("stdlib_for_rustc") {
all_dependent_configs = [ ":prebuilt_stdlib_sysroot" ]
- deps = [ ":prebuilt_rustc_copy_to_sysroot" ]
+ deps = [
+ ":prebuilt_rustc_copy_to_sysroot",
+ ":prebuilt_rustc_copy_target_json_to_sysroot",
+ ]
}

# Links the Rust stdlib. Used by targets for which linking is driven by
@@ -439,7 +453,10 @@ if (toolchain_has_rust) {
":prebuilt_stdlib_libs",
":stdlib_public_dependent_libs",
]
- deps = [ ":prebuilt_rustc_copy_to_sysroot" ]
+ deps = [
+ ":prebuilt_rustc_copy_to_sysroot",
+ ":prebuilt_rustc_copy_target_json_to_sysroot",
+ ]

# The host builds tools toolchain supports Rust only and does not use
# the allocator remapping to point it to PartitionAlloc.
diff --git a/build/rust/std/find_std_rlibs.py b/build/rust/std/find_std_rlibs.py
index 386258f..25fdedc 100755
--- a/build/rust/std/find_std_rlibs.py
+++ b/build/rust/std/find_std_rlibs.py
@@ -52,6 +52,8 @@ def main():
rustc_args.extend(["--target", args.target])
rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()

+ lib_output_dir = os.path.join(args.output, 'lib')
+
# Copy the rlibs to a predictable location. Whilst we're doing so,
# also write a .d file so that ninja knows it doesn't need to do this
# again unless the source rlibs change.
@@ -63,7 +65,7 @@ def main():
# output rlibs for that purpose. If any of the input rlibs change, ninja
# will run this script again and we'll copy them all afresh.
depfile.write(
- "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))
+ "%s:" % (os.path.join(lib_output_dir, "lib%s.rlib" % args.depfile_target)))

def copy_file(infile, outfile):
depfile.write(f" {infile}")
@@ -117,14 +119,19 @@ def main():
output_filename = f"lib{concise_name}.rlib"

infile = os.path.join(rustlib_dir, f)
- outfile = os.path.join(args.output, output_filename)
+ outfile = os.path.join(lib_output_dir, output_filename)
copy_file(infile, outfile)

for f in extra_libs:
infile = os.path.join(rustlib_dir, f)
- outfile = os.path.join(args.output, f)
+ outfile = os.path.join(lib_output_dir, f)
copy_file(infile, outfile)

+ f = 'target.json'
+ infile = os.path.join(rustlib_dir, '..', f)
+ outfile = os.path.join(args.output, f)
+ copy_file(infile, outfile)
+
depfile.write("\n")


Loading