BlackDex / rust-musl

For compiling static Rust binaries using musl toolchain with some pre-compiled static libraries
Apache License 2.0
31 stars 3 forks source link

[FEATURE-REQUEST] Additional Libs & aarch64 (arm64) Images #4

Closed Azathothas closed 6 months ago

Azathothas commented 7 months ago

Hi, thank you so much for this. I have been using this for Azathothas/Toolpacks https://bin.ajam.dev/ and this has made my life a lot easier. I am wondering if there are plans to support (pre-configure & install) the following Libraries:

[+] libxml
Source: https://github.com/GNOME/libxml2 || https://gitlab.gnome.org/GNOME/libxml2
Test with:  https://github.com/Orange-OpenSource/hurl
[+] libpam0g-dev | pam-devel
Source: https://github.com/linux-pam/linux-pam
Test with: https://github.com/memorysafety/sudo-rs 

And also, if the docker images could also be provided for linux/arm64 as arm64 machines, are getting cheaper and much efficient at compiling things than x86_64 ones.

BlackDex commented 7 months ago

Hello @Azathothas, thanks for creating a feature-request! Nice to see you are using this.

I might be able to add the extra libs. I do not think that would be a big issue. Regarding the aarch64. I have not encountered a use-case for this my self. Also, Github does not provide any aarch64 runners, which would make it easier.

I am planning on to changing the toolchain build to use mussel instead. Maybe i can do a canadian-cross build too which would make it possible, but that is something i have to checkout.

BlackDex commented 7 months ago

@Azathothas, during my testing to use mussel i also added both pam and xml as a library. With my modified multi crate testing I'm able to get it working, i can read a xml file for example.

And, I'm able to fully compile hurl.

And, I'm also able to use sudo-rs as a crate and call sudo_rs::sudo_main(), which ends up into an exit because of no rights. And, if i remove the pam libraries it will not build and mentions a missing pam library.

The strange thing is, if i do the same for the sudo-rs git repo exactly the same as for hurl, it also mentions not being able to find libpam. Not sure why though. So something is not matching.

BlackDex commented 7 months ago

Ah, i found the culprit. Since sudo-rs doesn't use any of the provided env variables to use for linking libraries you need to define them via rustflags. I added a default into the /root/.cargo/config, but those are overridden when you use RUSTFLAGS But it does work now :).

I also merged all the security/*.a files into the libpam.a file, not sure if that is needed, but those are all the separate modules. I tried to compile it, but i'm not fully able to get it to work though.

You might try this specific image https://hub.docker.com/layers/blackdex/rust-musl/x86_64-musl-stable-2024-02-22/images/sha256-06eaaeaac26acb017af1e9461b813392ff5e97a017bf4bccc8e5e8f9ad631ce4?context=explore

I pushed that to docker-hub (and overwritten the previous version), but i do not think anybody uses this. That image has libxml and libpam and uses the new mussel build compilers.

Please let me know if it works. But i'm afraid for pam there might be other stuff needed to get it to work, but that is a bit out of scope for me for now.

Azathothas commented 7 months ago

@BlackDex Thanks for working on this.

And, I'm able to fully compile hurl.

How? I try it with and without any RUSTFLAGS, I keep getting:

pushd "$($TMPDIRS)" > /dev/null 2>&1 && git clone --quiet --filter "blob:none" "https://github.com/Orange-OpenSource/hurl" && cd "./hurl"
export RUST_TARGET="x86_64-unknown-linux-musl" && rustup target add "$RUST_TARGET"
export RUSTFLAGS="-C target-feature=+crt-static -C default-linker-libraries=yes -C link-self-contained=yes -C prefer-dynamic=no -C embed-bitcode=yes -C lto=yes -C opt-level=3 -C debuginfo=none -C strip=symbols"
sed '/^\[profile\.release\]/,/^$/d' -i "./Cargo.toml" ; echo -e '\n[profile.release]\nstrip = true\nopt-level = 3\nlto = true' >> "./Cargo.toml"
docker run --rm -i -v "$(pwd):/home/rust/src" "blackdex/rust-musl:x86_64-musl-stable-2024-02-22" cargo build --target "$RUST_TARGET" --release --jobs="$(($(nproc)+1))" --keep-going
error: linking with `x86_64-unknown-linux-musl-ld` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/mussel/toolchain/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" VSLANG="1033" "x86_64-unknown-linux-musl-ld" "/tmp/rustcDddLWo/symbols.o" "/home/rust/src/target/x86_64-unknown-linux-musl/release/deps/hurlfmt-15ae1589387f2379.hurlfmt.f07a42a64548c737-cgu.0.rcgu.o" "--as-needed" "-L" "/home/rust/src/target/x86_64-unknown-linux-musl/release/deps" "-L" "/home/rust/src/target/release/deps" "-L" "/mussel/toolchain/lib" "-L" "/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Bstatic" "/tmp/rustcDddLWo/liblibxml-c971862f61c791f7.rlib" "/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-a35e2d2f7e164f79.rlib" "-Bdynamic" "-lm" "-lgcc_s" "-lc" "--eh-frame-hdr" "-z" "noexecstack" "-L" "/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-o" "/home/rust/src/target/x86_64-unknown-linux-musl/release/deps/hurlfmt-15ae1589387f2379" "--gc-sections" "-pie" "-z" "relro" "-z" "now" "-O1" "--strip-all"
  = note: x86_64-unknown-linux-musl-ld: cannot find -lgcc_s: No such file or directory

error: could not compile `hurlfmt` (bin "hurlfmt") due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: linking with `x86_64-unknown-linux-musl-ld` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/mussel/toolchain/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" VSLANG="1033" "x86_64-unknown-linux-musl-ld" "/tmp/rustcNicodj/symbols.o" "/home/rust/src/target/x86_64-unknown-linux-musl/release/deps/hurl-f5b6bb58d9640afa.hurl.d28085fa492497a0-cgu.00.rcgu.o" "--as-needed" "-L" "/home/rust/src/target/x86_64-unknown-linux-musl/release/deps" "-L" "/home/rust/src/target/release/deps" "-L" "/home/rust/src/target/x86_64-unknown-linux-musl/release/build/hurl-e39c865558949427/out" "-L" "/mussel/toolchain/lib" "-L" "/home/rust/src/target/x86_64-unknown-linux-musl/release/build/libz-sys-5cbce91b1ef13cf2/out/lib" "-L" "/home/rust/src/target/x86_64-unknown-linux-musl/release/build/libz-sys-5cbce91b1ef13cf2/out/lib" "-L" "/mussel/toolchain/lib" "-L" "/mussel/toolchain/lib" "-L" "/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Bstatic" "/tmp/rustcNicodj/libhurl-770f0e3b5460078c.rlib" "/tmp/rustcNicodj/liblibxml-c971862f61c791f7.rlib" "/tmp/rustcNicodj/libcurl_sys-c5c39345339bd437.rlib" "/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-a35e2d2f7e164f79.rlib" "-Bdynamic" "-lm" "-lgcc_s" "-lc" "--eh-frame-hdr" "-z" "noexecstack" "-L" "/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-o" "/home/rust/src/target/x86_64-unknown-linux-musl/release/deps/hurl-f5b6bb58d9640afa" "--gc-sections" "-pie" "-z" "relro" "-z" "now" "-O1" "--strip-all"
  = note: x86_64-unknown-linux-musl-ld: cannot find -lgcc_s: No such file or directory

error: could not compile `hurl` (bin "hurl") due to 1 previous error

I tried to compile it, but i'm not fully able to get it to work though.

Yes, it does compile but whenever I try to execute the binary, I get:

su: PAM error: PAM returned an error (PermissionDenied): Permission denied

I tested if this was a PAM issue, but using staticx as in https://github.com/Azathothas/Toolpacks/blob/main/.github/scripts/x86_64_Linux/bins/sudo-rs.sh , I don't get that error and the binaries work correctly.

BlackDex commented 7 months ago

For hurl you need at least -C target-feature=+crt-static nothing more. Ill add that as a default too. I think that is a good one.

BlackDex commented 7 months ago

I'm not getting sudo-rs to work. The problem with your current way of faking the static build is that it uses all the dynamic libraries from your OS Base.

I tried linking to the security libraries manually via -l pam_xauth.a etc... i tried adding all those libraries to the main libpam.a, i tried changing /etc/pam.d/sudo etc.. etc...

I'm for some reason not getting it to work. I probably overlook something very obvious, but I'm not seeing it.

I have pushed an image so you can try and test:

I'm fine for now with adding xml, but pam would be a no-go for now until this somehow is able to get it to work for sudo-rs.

BlackDex commented 6 months ago

@Azathothas i just released new images (building right now) which are based upon musl v1.2.5 and have libxml2 in there.

I did another attempt to get sudo-rs working, that is just not working for me. I created a discussion for this: https://github.com/BlackDex/rust-musl/discussions/7

Azathothas commented 6 months ago

I checked the latest commit. I am not a dev and don't know much, compiling things statically for https://bin.ajam.dev/ started as a hobby and then a need since I found myself getting frustrated when working on restricted systems. It has grown to have over 2000 Static Binaries, and the rust ones, when they require OpenSSL etc., I always default to using your docker image to build them. So I genuinely want to say, thank you for all the work.

Regarding hurl, I have recently learned about nix-build, and indeed I am able to successfully compile using this: scripts/x86_64_Linux/bins/hurl.sh

I tried to do the same for sudo-rs, but even nix-build failed. I think at this point, it's probably best to open an issue on their official repo and ask for assistance. Or at least learn why it's so hard to compile it statically.

The problem with your current way of faking the static build is that it uses all the dynamic libraries from your OS Base.

Actually, it works surprisingly well. I use staticx as a last resort, but I test the executables in minimal alpine docker container and a couple other restricted systems, and they often work and behave exactly as real/native static binaries.

Thanks again!