rust: enable build on LLVM-only systems#304
Conversation
| # Since libgcc_s.so is needed for Rust's own bootstrap binary, and | ||
| # it's dynamically linked, we'll have to add two files, libgcc_s.so.1 | ||
| # for the symlink, and libgcc_s.so so the linker points to libunwind. | ||
| case $("$CC" -print-file-name=libunwind.so) in */*) | ||
| mkdir -p libgcc | ||
| ln -sf /usr/lib/libunwind.so.1 libgcc/libgcc_s.so.1 | ||
| cat > libgcc/libgcc_s.so <<EOF | ||
| INPUT(-lunwind) | ||
| EOF | ||
| export LD_LIBRARY_PATH="$PWD/libgcc:$LD_LIBRARY_PATH" | ||
| export LIBRARY_PATH="$PWD/libgcc:$LIBRARY_PATH" | ||
| esac | ||
|
|
There was a problem hiding this comment.
Is upstream doing anything about this?
There was a problem hiding this comment.
Not that I know of. But I think they should've statically compiled the bootstrap binary instead of making it dynamically linked. Also, it's ugly so I understand if this ended up not being merged.
There was a problem hiding this comment.
They can't statically compile it because proc_macro doesn't support static linking or at least that's what the upstream rust people said when I bought up the idea. I can say that libunwind.so is mostly ABI compatible on x86_64 systems, on aarch64 and others the rust binary requires symbols such as __clear_cache which are provided by compiler-rt. I solved this with the below command:
clang -shared -o build/libgcc_s.so.1 \
-Wl,--allow-multiple-definition -Wl,--whole-archive \
$(clang -print-libgcc-file-name) -lunwind
There was a problem hiding this comment.
I'll try this later on my build file. Thanks!
|
Does this work @konimex ? diff --git a/extra/rust/build b/extra/rust/build
index edfbd012..3de1aad1 100755
--- a/extra/rust/build
+++ b/extra/rust/build
@@ -49,6 +49,10 @@ full-bootstrap = false
[install]
prefix = "/usr"
+[target.x86_64-unknown-linux-musl]
+llvm-config = "/usr/bin/llvm-config"
+crt-static = false
+
[rust]
channel = "stable"
rpath = false
@@ -59,12 +63,30 @@ jemalloc = false
debug-assertions = false
codegen-tests = false
codegen-units-std = 1
-
-[target.x86_64-unknown-linux-musl]
-llvm-config = "/usr/bin/llvm-config"
-crt-static = false
EOF
+# Workaround to get Rust to build in llvm-only environments.
+case $("$CC" -print-file-name=libunwind.so) in */*)
+ printf 'llvm-libunwind = "system"\n' >> config.toml
+
+ # libgcc_s.so is needed for Rust's bootstrap binaries, on llvm-only systems
+ # this library does not exist. This hack creates it as alias to libunwind.
+ {
+ mkdir -p libgcc
+
+ printf 'INPUT(-lunwind)\n' > \
+ libgcc/libgcc_s.so
+
+ ln -sf "$KISS_ROOT/usr/lib/libunwind.so.1" \
+ libgcc/libgcc_s.so.1
+
+ export \
+ LD_LIBRARY_PATH="$PWD/libgcc:$LD_LIBRARY_PATH" \
+ LIBRARY_PATH="$PWD/libgcc:$LIBRARY_PATH"
+ }
+esac
+
+
python3 ./x.py build -j "$(nproc)"
python3 ./x.py install |
|
Also, could something like patchelf be used to do this (replace libgcc_s with libunwind)? |
|
The patch works from my end. Regarding |
Since this is one hell of a hack (i.e. worse than the last patches I sent related to these things), I decided to wait until 1.54.0 since rust-lang/rust#84124 finally landed (and in kiss-llvm and Wyverkiss,
rustis now patch-less).Anyway, the most obvious things, of course, is setting
llvm-libunwind = "system"since the default isnofor dynamic linking tolibgcc_s.so(and we don't havelibgcc_s.so).The ugly part of this patch is, of course, the
libgcc_s.sohacks for LLVM-only systems. Since the bootstrap binary looks forlibgcc_s.so.1(and therefore, dynamically linked), we need to work around this by fooling it using the good old$LD_LIBRARY_PATH. We also need to fool some parts since it looks for-lgcc_s, so we also addlibgcc_s.sowhich only containsINPUT(-lunwind)so that-lgcc_sis more or less "aliased" to-lunwindand use$LIBRARY_PATHto fool$CC. (Surprisingly, the two unwinding functions between GCC and LLVM libunwind are compatible, though I can't say if this is an ABI compatibility or not).