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

x86_64-musl: allow building dylibs with -crt-static #38075

Closed
wants to merge 4 commits into from

Conversation

japaric
Copy link
Member

@japaric japaric commented Nov 29, 2016

Tested with:

$ rustc src/lib.rs --crate-type dylib --target x86_64-unknown-linux-musl -C target-feature=-crt-static -Z unstable-options -Z print-link-args -C linker=x86_64-unknown-linux-musl-gcc
"x86_64-unknown-linux-musl-gcc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-nostdlib" "-Wl,--eh-frame-hdr" "-Wl,-(" "-m64" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "lib.0.o" "-o" "liblib.so" "lib.metadata.o" "-nodefaultlibs" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/libstd-ce5d590d9ad4e1f6.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/librand-3b2d8065d4b3f8de.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/libcollections-14fd7ed60480d5fa.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/librustc_unicode-0457dfc409106094.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/libpanic_unwind-9e5638684273e062.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/libunwind-bc88660fb5e3bcdf.rlib""-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/liballoc-f1d94131b8ae5efd.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/liballoc_system-e7e82202710773f4.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/liblibc-585bea47151a8284.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.EYGJnMT6jBmB/libcore-a68d02603096f00e.rlib" "-Wl,--no-whole-archive" "/tmp/rustc.EYGJnMT6jBmB/libcompiler_builtins-de1e72abeff6232c.rlib" "-l" "c" "-shared" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/crtn.o" "-Wl,-)"

Note that x86_64-unknown-linux-musl-gcc is a "real" MUSL toolchain unlike the musl-gcc wrapper that Ubuntu provides. The former provides a MUSL libc.so; the latter doesn't because it's just a wrapper around gcc with some extra flags (-static, etc.).

Also this made me realize that when using -crt-static with MUSL targets:

  • We shouldn't be passing crt*.o objects; the MUSL toolchain will provide those.

  • With that ^ change, we should be able to enable PIE for these dynamically linked MUSL binaries.

  • We probably can drop the -Wl,-( and -Wl,-) as well.

Also, with this change, Cargo still refuses to compile dylibs:

$ cargo rustc --target x86_64-unknown-linux-musl -- -C target-feature=-crt-static -Z unstable-options
error: cannot produce dylib for `bar v0.1.0 (file:///home/japaric/build/bar)` as the target `x86_64-unknown-linux-musl` does not support these crate types

r? @alexcrichton

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@@ -237,7 +237,16 @@ pub fn default_output_for_target(sess: &Session) -> config::CrateType {
/// Checks if target supports crate_type as output
pub fn invalid_output_for_target(sess: &Session,
crate_type: config::CrateType) -> bool {
match (sess.target.target.options.dynamic_linking,
let requested_features = sess.opts.cg.target_feature.split(',');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addition duplicates part of the add_configuration function (librustc_driver/target_feature.rs) and should be refactored into its own function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this logic could get refactored to a method on Session? I had it there originally but ended up not using it, but I feel like we should avoid duplicating that here.

@@ -62,7 +62,7 @@ pub fn opts() -> TargetOptions {
// MUSL support doesn't currently include dynamic linking, so there's no
// need for dylibs or rpath business. Additionally `-pie` is incompatible
// with `-static`, so we can't pass `-pie`.
base.dynamic_linking = false;
base.dynamic_linking = true;
base.has_rpath = false;
base.position_independent_executables = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I wonder if this logic is insufficient now? Presumably we should pass -pie for dynamically linked musl executables?

@japaric
Copy link
Member Author

japaric commented Nov 30, 2016

We shouldn't be passing crt*.o objects; the MUSL toolchain will provide those.
With that ^ change, we should be able to enable PIE for these dynamically linked MUSL binaries.

Done both.

We probably can drop the -Wl,-( and -Wl,-) as well.

Forgot about this one. 😅

Refactored the crt_static logic as well.

And tested with:

$ rustc hello.rs --target x86_64-unknown-linux-musl -Z print-link-args
"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-nostdlib" "-Wl,--eh-frame-hdr" "-Wl,-(" "-m64" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/crt1.o" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/crti.o" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "hello.0.o" "-o" "hello" "-Wl,--gc-sections" "-nodefaultlibs" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd-ce5d590d9ad4e1f6.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/librand-3b2d8065d4b3f8de.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libcollections-14fd7ed60480d5fa.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_unicode-0457dfc409106094.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libpanic_unwind-9e5638684273e062.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libunwind-bc88660fb5e3bcdf.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc-f1d94131b8ae5efd.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc_jemalloc-502770d9740c66f8.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-585bea47151a8284.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libcore-a68d02603096f00e.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-de1e72abeff6232c.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/crtn.o" "-Wl,-)"

$ rustc hello.rs --target x86_64-unknown-linux-musl -Z print-link-args -C linker=x86_64-unknown-linux-musl-gcc -Z unstable-options -C target-feature=-crt-static
"x86_64-unknown-linux-musl-gcc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-nostdlib" "-Wl,--eh-frame-hdr" "-Wl,-(" "-m64" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "hello.0.o" "-o" "hello" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd-ce5d590d9ad4e1f6.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/librand-3b2d8065d4b3f8de.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libcollections-14fd7ed60480d5fa.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_unicode-0457dfc409106094.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libpanic_unwind-9e5638684273e062.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libunwind-bc88660fb5e3bcdf.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc-f1d94131b8ae5efd.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc_jemalloc-502770d9740c66f8.rlib" "/tmp/rustc.2ydaeypkVjF4/liblibc-585bea47151a8284.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libcore-a68d02603096f00e.rlib" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-de1e72abeff6232c.rlib" "-l" "c" "-Wl,-)"

$ rustc src/lib.rs --target x86_64-unknown-linux-musl --crate-type dylib -Z print-link-args -C linker=x86_64-unknown-linux-musl-gcc -Z unstable-options -C target-feature=-crt-static
"x86_64-unknown-linux-musl-gcc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-nostdlib" "-Wl,--eh-frame-hdr" "-Wl,-(" "-m64" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "lib.0.o" "-o" "liblib.so" "lib.metadata.o" "-nodefaultlibs" "-L" "/home/japaric/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/libstd-ce5d590d9ad4e1f6.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/librand-3b2d8065d4b3f8de.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/libcollections-14fd7ed60480d5fa.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/librustc_unicode-0457dfc409106094.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/libpanic_unwind-9e5638684273e062.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/libunwind-bc88660fb5e3bcdf.rlib""-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/liballoc-f1d94131b8ae5efd.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/liballoc_system-e7e82202710773f4.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/liblibc-585bea47151a8284.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc.nigsOugl1Qn5/libcore-a68d02603096f00e.rlib" "-Wl,--no-whole-archive" "/tmp/rustc.nigsOugl1Qn5/libcompiler_builtins-de1e72abeff6232c.rlib" "-l" "c" "-shared" "-Wl,-)"

Disclaimer: Still testing the latest commit.

@@ -237,7 +237,7 @@ pub fn default_output_for_target(sess: &Session) -> config::CrateType {
/// Checks if target supports crate_type as output
pub fn invalid_output_for_target(sess: &Session,
crate_type: config::CrateType) -> bool {
match (sess.target.target.options.dynamic_linking,
match (sess.target.target.options.dynamic_linking && !sess.target_is_crt_static(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I think this isn't quite accurate for MSVC where you can statically link msvcrt but still create DLLs (I believe)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following that logic, it should also be possible to build MUSL dylibs (.so libraries) that statically link to libc but link dynamically to other libraries I think (maybe not?). Do we want to support that as well?

If not then I can just add a !musl || here I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose if it's possible we should allow it. AFAIK it just gave a weird linker error when I tried with musl awhile back. That's probably b/c we were using wrong startup objects or something like that?

Ideally we'd avoid as many !musl conditions as possible...

cmd.arg(root.join(obj));
// When dynamically linking to MUSL we don't need to pass our startup
// objects as those will be provided by the MUSL toolchain
if !musl || crt_static {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm this is always something I wish we could sink into the target specs rather than have here... Does anything leap to mind for you as an easy way to do that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anything leap to mind for you as an easy way to do that?

pre_link_objects_crt_static and pre_link_objects_crt_dynamic? 😄

BTW, is pre_link_args "setable" from JSON files? This field feels like a Rust distribution implementation detail because the objects get prepended with the sysroot's absolute path. I doubt custom targets will be able to use this field lest they modify the sysroot ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think all options are configurable from json files now (we round-trip through that format to read our own options IIRC).

I mean all the options in the custom target specs are already super specific... I guess I wouldn't really have a problem with those.

@steveklabnik
Copy link
Member

Ping, all! It's been a month since the last activity here.

@alexcrichton
Copy link
Member

@japaric do you have further thoughts on my comments? I think I'd still like to remove some special casing here if we can.

@alexcrichton
Copy link
Member

Closing due to inactivity, but feel free to reopen/resubmit!

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

Successfully merging this pull request may close these issues.

4 participants