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

How to find which libc.so will rustc --target=$TARGET link against? #71564

Closed
dubiousjim opened this issue Apr 25, 2020 · 9 comments
Closed

How to find which libc.so will rustc --target=$TARGET link against? #71564

dubiousjim opened this issue Apr 25, 2020 · 9 comments

Comments

@dubiousjim
Copy link

When running rustc --target=x86_64-unknown-linux-musl on a glibc host (specifically, 1.43.0-x86_64-unknown-linux-gnu), I'd like to be able to determine programmatically, either in a build script or in the library being built, what is the location of the relevant libc.so file. (The reason I want to do this is so that I can execute libc.so --version to determine its version information; that's provided by C macros by glibc but not by musl).

From what I understand --- but please correct me if I'm wrong --- when the toolchain is on a glibc host, we can only create statically-linked musl outputs. So I can't inspect a binary generated by rustc --target=x86_64-unknown-linux-musl to see what libc it has dynamically linked against.

I also raised this question on StackOverflow, and there it was suggested to pass the flags -C link-args=-Wl,-Map=map.out to rustc and inspect the generated map file. But this doesn't point to the libc.so file when the file is being statically linked.

I am able to programmatically find the libstd-*.so file that is used when running rustc --target=x86_64-unknown-linux-musl, and that seems to have a link in it to the relevant libc file. But I can't query it using ldd. On a glibc host, running ldd /root/.rustup/toolchains/1.43.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd-*.so yields "invalid ELF header".

I can use the tools readelf -d or objdump -p to read the dynamic section of the libstd-*.so file. But they only report information like this:

 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../lib]

There's no full path to the relevant libc.so file. (I know where it is on my own system; but I'm trying to find it programmatically on arbitrary systems.)

The environment I'm working in are these Docker containers. But I'd hope to find a way to obtain this information that works on any system where rustc is capable of targeting musl.

@sfackler
Copy link
Member

If you're statically linking to MUSL glibc, you aren't dynamically linking to a glibc at all. There is no libc.so dynamic library involved if you aren't linking to glibc dynamically.

@dubiousjim
Copy link
Author

dubiousjim commented Apr 26, 2020

Right, but the static lib is coming from a directory, that also has the libc.so in it, and I can execute that with --version. I need to determine which directory that is.

Right? Or is the libc archive already folded into the libstd.so for the musl target?

@sfackler
Copy link
Member

libc.so is a dynamic library, as is libstd.so.

Rust binaries do not link to libstd.so in standard builds, they link statically to libstd.rlib.

There is no libc.so in the MUSL target distribution because that is a dynamic library and the MUSL target is statically linked. I can't remember exactly what archive the MUSL libc is statically linked into (maybe libcore.rlib?), but there's definitely no binary to run --version against.

@dubiousjim
Copy link
Author

Oh ok thanks. The (auto-generated) docker containers I linked to do have a musl libc.so binary, but given what you're saying I'm not sure why. And what you've said implies that I can't expect such a binary to exist on arbitrary systems that are compiling musl targets.

@sfackler
Copy link
Member

sfackler commented Apr 26, 2020 via email

@dubiousjim
Copy link
Author

I guess the best (and only partial) solution for my purposes is to run musl-gcc -print-file-name=libc.so. If musl-gcc isn't available in the environment (as I suppose may sometimes be the case even though rustc --target=x86_64-unknown-linux-musl works), I can't rely on the musl libc.so being available either.

@sfackler
Copy link
Member

The x86_64-unknown-linux-musl target doesn't use the system MUSL, it bundles MUSL 1.2.22. https://github.com/rust-lang/rust/blob/master/src/ci/docker/scripts/musl.sh#L27

@dubiousjim
Copy link
Author

Ok, thanks, glad I came here else it would have taken me a while to figure that out. I guess then I should fetch and parse that script.

#!/bin/sh

die() { printf '%s: %s\n' "$0" "$*" >&2; exit 1; }

if [ $# -eq 0 ] || [ x-h = "x$1" ] || [ x--help = "x$1" ] || [ xrustc = "x$1" ]; then
  printf 'Usage: %s "$(rustc --version)"\n' "$0" >&2
  exit 1
fi

VERSION="${1#rustc }"
VERSION="${VERSION% (*}"

SCRIPTPATH="src/ci/docker/scripts/musl.sh"
URL="https://raw.githubusercontent.com/rust-lang/rust/$VERSION/$SCRIPTPATH"

SCRIPT=$(curl -sf "$URL") || die "couldn't fetch $SCRIPTPATH from rust-lang/rust"

MUSL=$(sed -n 's/^MUSL=//p' <<< "$SCRIPT")
[ -n "$MUSL" ] || die "couldn't find MUSL variable"

echo "${MUSL#musl-}"

@Mark-Simulacrum
Copy link
Member

I'm going to go ahead and close this as it looks like this has been resolved. For the future, questions like this are best directed at users.rust-lang.org, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants