Repository navigation
Duplication of libLLVM-*.so in the distributed rustc component. #70838
Description
Since #57286, libLLVM-*.so has been distributed in the rustc component in two locations:
lib/libLLVM-*.so(presumably as a runtime dependency ofbin/rustc)lib/rustlib/$target/lib/libLLVM-*.so(not sure, maybe for linking custom drivers?)- likely belongs in the
rustc-devcomponent, if the duplication can't be avoided
- likely belongs in the
The difference can be seen in these consecutive nightlies' rustc components:
- https://static.rust-lang.org/dist/2019-01-06/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz
- has just the second
libLLVM-*.so- maybe it's used via relative
RPATHbylib/rustlib/$target/codegen-backends/librustc_codegen_llvm-llvm.so? separate codegen backends are gone, maybe we should just try removing it?
- maybe it's used via relative
- has just the second
- https://static.rust-lang.org/dist/2019-01-07/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz
- first nightly to include bootstrap: Link LLVM as a dylib with ThinLTO (take 2) #57286
- has both copies
All 3 of those libLLVM-8svn.so files are identical (even across nightlies, yay for deterministic builds):
e400d157a7ceaee26f8680cb6f7430bd98c251dbb32e1f10549dda9f5769dc42 before/rustc-nightly-x86_64-unknown-linux-gnu/rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/libLLVM-8svn.so
e400d157a7ceaee26f8680cb6f7430bd98c251dbb32e1f10549dda9f5769dc42 after/rustc-nightly-x86_64-unknown-linux-gnu/rustc/lib/libLLVM-8svn.so
e400d157a7ceaee26f8680cb6f7430bd98c251dbb32e1f10549dda9f5769dc42 after/rustc-nightly-x86_64-unknown-linux-gnu/rustc/lib/rustlib/x86_64-unknown-linux-gnu/lib/libLLVM-8svn.so
One fascinating aspect is that the size only increases from 82.22 MiB to 83.18 MiB, despite libLLVM-8svn.so alone being 67 MiB uncompressed, so compression is really helping.
Even the .tar.gz only goes from 111.41 MiB to 113.26 MiB.
(I'm using archive sizes from the 2019-01-06 and 2019-01-07 directory listings in https://static.rust-lang.org/dist, FWIW)
This part of the build system seems relevant, but I'm not sure which of the two this creates:
Lines 755 to 757 in 733f104
| // Ensure that `libLLVM.so` ends up in the newly build compiler directory, | |
| // so that it can be found when the newly built `rustc` is run. | |
| dist::maybe_install_llvm_dylib(builder, target_compiler.host, &sysroot); |
cc @alexcrichton @rust-lang/release
Activity
Mark-Simulacrum commentedon Apr 6, 2020
cc @cuviper -- you've touched code related to this a bunch recently I think, so maybe would have some time to investigate fixing this. I suspect we want to only ship one LLVM per tarball, at least, though ideally we would only have just the one LLVM library total as well.
eddyb commentedon Apr 6, 2020
Half-way through writing up this issue I realized the
codegen-backendsconnection.I'd suggest we try to get rid of the
lib/rustlib/$target/lib/libLLVM-*.socopy and see what breaks, it's possible it's been dead weight for a while now.And only if we have to keep both for some odd reason, we'd move it to
rustc-dev.cuviper commentedon Apr 6, 2020
The
rust-installerpurposely orders the tarred files so that similar filenames are adjacent in the compression stream, especially in hope of helping with such duplicate files.I think we may still want the
rustlibcopy for the odd cross-compiled tool usinglibrustc*, but that definitely belongs inrustc-dev.eddyb commentedon Apr 6, 2020
Is that... even possible? Is
rustc-deva per-target component in the same wayrust-stdis?cuviper commentedon Apr 6, 2020
Yes it is -- try
rustup component list-- but I don't know if anyone really needs that...eddyb commentedon Apr 6, 2020
Actually, can you try something like cross-compiling a copy of
src/rustctoi686, after deleting the per-targetlibLLVM-*.so?I suspect that it would actually run just fine on a
i686host, becauserustc-dev'srlibs should only really contain thermetainformation and maybe some object code thatlibrustc_driver-*.sois missing (which we could get rid of if we kept MIR for everything but idk how feasible that is).That is, the result of linking against
lib/rustlib/$target/lib/librustc_driver-*.soshould still uselib/librustc_driver-*.soat runtime, solibLLVM-*.soinrustlibis unnecessary.But maybe I'm missing something. Like running the cross-compiled
i686on ax64host without anything more than therustc-devcomponent?cuviper commentedon Apr 6, 2020
Hmm, I can't actually get cross-builds to work with
rustc-dev. I added this torustc.rs:... so it would pick that up from the sysroot. Trying to cross-compile i686, I get:
I do have both i686 and x86_64 builds of
rustc_macrosin the sysroot. I suspect the error is because the i686 build has different metadata than my host build, so it can't find the one it wants for the host. That may mean thatrustc-devis really tied to being used on the same host.It works if I just compile native x86_64 though. Then I tried removing the
rustlib/.../libLLVM.so, and it gets essentially the same error as #68714:AFAICS, building normal crates still works fine with that extra
libLLVMremoved though.In short:
rustc-devseems broken -- maybe it should be shipped native-only.rustc-devcrates will inherit-lLLVM, so that needs to be in the library path.eddyb commentedon Apr 6, 2020
Ah, fascinating. What happens if you build such an executable and then remove the
rustc-devcomponent entirely? Can it pick up the dylibs outsiderustlibor does it hardcode the paths inside?cuviper commentedon Apr 6, 2020
The final executable still isn't actually linked to LLVM, since it didn't need any of those symbols:
I can run this with
rustup run nightly ./rustc, which setLD_LIBRARY_PATH=$sysroot/lib, or even if I set that path myself. ButLD_LIBRARY_PATH=$sysroot/lib/rustlib/.../libdoesn't work if we've removed that library, sincelibrustc_driverneedslibLLVMitself.eddyb commentedon Apr 6, 2020
Okay, it being dependent on
LD_LIBRARY_PATHmakes sense.Overall, probably the safe thing to do would be to move the duplicate
.sotorustc-dev, oh well.cuviper commentedon Apr 7, 2020
Oh,
llvm-tools-previewalso needs LLVM, and those binaries are installed inrustlib/$target/binwith RUNPATH$ORIGIN/../lib. I guess they might be able to find the LLVM in$sysroot/libanyway?Auto merge of rust-lang#72000 - cuviper:dist-llvm, r=Mark-Simulacrum