coreutils
coreutils copied to clipboard
Adding back support for an external libstdbuf.so
#1120 changed the way stdbuf works to embed the .so inside of the binary. This, however, has some notable cons, such as:
- Distro packaging tooling can't access the inner .so, which means things like post-build stripping or dependency scanning or anything else won't run on it. This makes it effectively impossible to do a build with debug info and pull the debug information out for external use after the build completes. (We hit this internally which led to an investigation as to what was going on exactly with the strip process.)
$TMPDIRmight be mounted as noexec, in which case theLD_PRELOADwill simply not work.
Would a change to partially add back support for building libstdbuf.so externally be accepted? This could be perhaps configurable at build time & off-by-default (e.g. make USE_EXTERNAL_STDBUF=1), which would help a lot with the first point. (It wouldn't for the second, though! I'm not sure what the best solution for that is.)
One issue with current code (tested with commit 2ae14a393a ) is that it does not work when cross-compiling. It injects libstdbuf.so with the wrong architecture into the coreutils binary:
coreutils$ rustup target add aarch64-unknown-linux-gnu
coreutils$ cat .cargo/config.toml
[target.x86_64-unknown-redox]
linker = "x86_64-unknown-redox-gcc"
[target.aarch64-unknown-linux-gnu]
linker="aarch64-linux-gnu-gcc"
coreutils$cargo build --target=aarch64-unknown-linux-gnu --features "stdbuf" --no-default-features
coreutils$ file ./target/aarch64-unknown-linux-gnu/debug/build/uu_stdbuf-8b6d4486adbced66/out/libstdbuf.so
./target/aarch64-unknown-linux-gnu/debug/build/uu_stdbuf-8b6d4486adbced66/out/libstdbuf.so: ELF 64-bit LSB shared object, **x86-64**, version 1 (SYSV), dynamically linked, BuildID[sha1]=55fb82975ab1cd0e16686137dd59b2f3cb03b688, with debug_info, not stripped
$ file ./target/aarch64-unknown-linux-gnu/debug/coreutils
./target/aarch64-unknown-linux-gnu/debug/coreutils: ELF 64-bit LSB pie executable, **ARM aarch64**, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=17e23dda73a25c36d9959f3299d7ed45766b95f7, for GNU/Linux 3.7.0, with debug_info, not stripped
$ xxd -p ./target/aarch64-unknown-linux-gnu/debug/coreutils | tr -d '[ \n]' > coreutils-hex
$ xxd -p ./target/aarch64-unknown-linux-gnu/debug/build/uu_stdbuf-8b6d4486adbced66/out/libstdbuf.so | tr -d '[ \n]' > libstdbuf.so-hex
$ test $(grep -F -f ./libstdbuf.so-hex ./coreutils-hex) && echo "contained"
contained
You can see that the x86-64 libstdbuf.so was injected into the AARCH64 coreutils binary.
I think it is a regression caused by https://github.com/uutils/coreutils/pull/1120 . Testing 37270824042e00ca97461c492e66d92ee43b4a47 with rust 1.22, you can see that a static library ./target/aarch64-unknown-linux-gnu/debug/build/stdbuf-6a46e82d861bf028/out/libstdbuf.a used to be created with the correct aarch64 architecture. This is not the case any more after https://github.com/uutils/coreutils/pull/1120
Full logs: build-after-1120.txt build-before-1120.txt
@Ecordonnier is it something you could fix directly in the code ? :) merci
@sylvestre yes it is on my to-do list, I don't know yet when I'll have time to work on it unfortunately
I started working on the cross-compilation issue. I will try to implement a solution using https://github.com/rnza0u/blaze/blob/master/core/build.rs#L98 as example. Long-term, the cargo feature "bindeps" should be used instead (but at the moment it is only available in nightly). Currently, having libstdbuf as "build-dependencies" of stdbuf in Cargo.toml ensures that libstdbuf is built before stdbuf so that it can be injected into stdbuf using include_bytes, however this breaks cross-compilation, since build-dependencies are built for the host architecture, and not for the target architecture.