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

Experimental MUSL target support for the compiler #24777

Merged
merged 10 commits into from Apr 28, 2015

Conversation

Projects
None yet
8 participants
@alexcrichton
Copy link
Member

alexcrichton commented Apr 24, 2015

These commits build on some great work on reddit for adding MUSL support to the compiler. This goal of this PR is to enable a --target x86_64-unknown-linux-musl argument to the compiler to work A-OK. The outcome here is that there are 0 compile-time dependencies for a MUSL-targeting build except for a linker. Currently this also assumes that MUSL is being used for statically linked binaries so there is no support for dynamically linked binaries with MUSL.

MUSL support largely just entailed munging around with the linker and where libs are located, and the major highlights are:

  • The entirety of libc.a is included in liblibc.rlib (statically included as an archive).
  • The entirety of libunwind.a is included in libstd.rlib (like with liblibc).
  • The target specification for MUSL passes a number of ... flavorful options! Each option is documented in the relevant commit.
  • The entire test suite currently passes with MUSL as a target, except for:
    • Dynamic linking tests are all ignored as it's not supported with MUSL
    • Stack overflow detection is not working MUSL yet (I'm not sure why)
  • There is a language change included in this PR to add a target_env #[cfg] directive. This is used to conditionally build code for only MUSL (or for linux distros not MUSL). I highly suspect that this will also be used by Windows to target MSVC instead of a MinGW-based toolchain.

To build a compiler targeting MUSL you need to follow these steps:

  1. Clone the current MUSL repo from git://git.musl-libc.org/musl. Build this as usual and install it.
  2. Clone and build LLVM's libcxxabi library. Only the libunwind.a artifact is needed. I have tried using upstream libunwind's source repo but I have not gotten unwinding to work with it unfortunately. Move libunwind.a adjacent to MUSL's libc.a
  3. Configure a Rust checkout with --target=x86_64-unknown-linux-musl --musl-root=$MUSL_ROOT where MUSL_ROOT is where you installed MUSL in step 1.

I hope to improve building a copy of libunwind as it's still a little sketchy and difficult to do today, but other than that everything should "just work"! This PR is not intended to include 100% comprehensive support for MUSL, as future modifications will probably be necessary.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Apr 24, 2015

r? @pcwalton

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 24, 2015

r? @brson

@rust-highfive rust-highfive assigned brson and unassigned pcwalton Apr 24, 2015

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Apr 24, 2015

Why 'x86_64-unknown-linux-musl'? It seems reasonable to me, but Google doesn't have a lot of hits for it.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Apr 24, 2015

Neat!

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 24, 2015

@brson I found it followed clang's target triple format, but I personally got the idea from the reddit post.

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Apr 24, 2015

r=me

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 24, 2015

@brson I've pushed some more commits clarifying some documentation and also feature gating target_env by just not defining it unless the gate is turned on. I've avoided rebasing for now but I'll rebase all the commits up after review.

@alexcrichton alexcrichton force-pushed the alexcrichton:musl branch from fe31352 to 01963a6 Apr 24, 2015

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 24, 2015

@bors: r=brson 01963a6

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 25, 2015

⌛️ Testing commit 01963a6 with merge 9e28730...

bors added a commit that referenced this pull request Apr 25, 2015

Auto merge of #24777 - alexcrichton:musl, r=brson
These commits build on [some great work on reddit](http://www.reddit.com/r/rust/comments/33boew/weekend_experiment_link_rust_programs_against/) for adding MUSL support to the compiler. This goal of this PR is to enable a `--target x86_64-unknown-linux-musl` argument to the compiler to work A-OK. The outcome here is that there are 0 compile-time dependencies for a MUSL-targeting build *except for a linker*. Currently this also assumes that MUSL is being used for statically linked binaries so there is no support for dynamically linked binaries with MUSL.

MUSL support largely just entailed munging around with the linker and where libs are located, and the major highlights are:

* The entirety of `libc.a` is included in `liblibc.rlib` (statically included as an archive).
* The entirety of `libunwind.a` is included in `libstd.rlib` (like with liblibc).
* The target specification for MUSL passes a number of ... flavorful options! Each option is documented in the relevant commit.
* The entire test suite currently passes with MUSL as a target, except for:
  * Dynamic linking tests are all ignored as it's not supported with MUSL
  * Stack overflow detection is not working MUSL yet (I'm not sure why)
* There is a language change included in this PR to add a `target_env` `#[cfg]` directive. This is used to conditionally build code for only MUSL (or for linux distros not MUSL). I highly suspect that this will also be used by Windows to target MSVC instead of a MinGW-based toolchain.

To build a compiler targeting MUSL you need to follow these steps:

1. Clone the current MUSL repo from `git://git.musl-libc.org/musl`. Build this as usual and install it.
2. Clone and build LLVM's [libcxxabi](http://libcxxabi.llvm.org/) library. Only the `libunwind.a` artifact is needed. I have tried using upstream libunwind's source repo but I have not gotten unwinding to work with it unfortunately. Move `libunwind.a` adjacent to MUSL's `libc.a`
3. Configure a Rust checkout with `--target=x86_64-unknown-linux-musl --musl-root=$MUSL_ROOT` where `MUSL_ROOT` is where you installed MUSL in step 1.

I hope to improve building a copy of libunwind as it's still a little sketchy and difficult to do today, but other than that everything should "just work"! This PR is not intended to include 100% comprehensive support for MUSL, as future modifications will probably be necessary.
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 25, 2015

💔 Test failed - auto-win-64-nopt-t

alexcrichton added some commits Apr 21, 2015

rustc: Add target_env for triples by default
This adds a new `#[cfg]` matcher against the `target_env` property of the
destination target triple. For example all windows triples today end with `-gnu`
but we will also hopefully support non-`gnu` targets for Windows, at which point
we'll need to differentiate between the two. This new `target_env` matches is
provided and filled in with the target's environment name.

Currently the only non-empty value of this name is `gnu`, but `musl` will be
shortly added for the linux triples.
mk: Add support for musl-based builds
This commit adds support to the makefiles, configuration script, and build
system to understand MUSL. This is broken up into a few parts:

* Any target of the form `*-musl` requires the `--musl-root` option to
  `./configure` which will indicate the root of the MUSL installation. It is
  also expected that there is a libunwind build inside of that installation
  built against that MUSL.

* Objects from MUSL are copied into the build tree for Rust to be statically
  linked into the appropriate Rust library.

* Objects for binary startup and shutdown are included in each Rust installation
  by default for MUSL. This requires MUSL to only be installed on the machine
  compiling rust. Only a linker will be necessary for compiling against MUSL on
  a target machine.

Eventually a MUSL and/or libunwind build may be integrated by default into the
build but for now they are just always assumed to exist externally.
std: Prepare for linking to musl
This commit modifies the standard library and its dependencies to link correctly
when built against MUSL. This primarily ensures that the right libraries are
linked against and when they're linked against they're linked against
statically.
rustc_back: Add x86_64-unknown-linux-musl as a target
This commit adds support for x86_64-unknown-linux-musl as a target of the
compiler. There's some comments in the commit about some of the more flavorful
flags passed to the linker as it's not quite as trivial as the normal specs.
rustc: Add support for linking arbitrary objects
MUSL for example provides its own start/end objects in place of the standard
ones shipped by gcc.
compiletest: Don't force dylibs on musl
MUSL support is currently only with static builds, so building a dylib will
always fail.
std: Don't assume dlopen() works on yourself
Statically linked executables do not succeed (aka MUSL-based executables).
compiletest: Add support for `// ignore-musl`
Add the ability to ignore a test based on the environment of the triple being
used.

@alexcrichton alexcrichton force-pushed the alexcrichton:musl branch from 01963a6 to faa1a81 Apr 27, 2015

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 27, 2015

@bors: r=brson faa1a81

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 28, 2015

⌛️ Testing commit faa1a81 with merge a574d45...

bors added a commit that referenced this pull request Apr 28, 2015

Auto merge of #24777 - alexcrichton:musl, r=brson
These commits build on [some great work on reddit](http://www.reddit.com/r/rust/comments/33boew/weekend_experiment_link_rust_programs_against/) for adding MUSL support to the compiler. This goal of this PR is to enable a `--target x86_64-unknown-linux-musl` argument to the compiler to work A-OK. The outcome here is that there are 0 compile-time dependencies for a MUSL-targeting build *except for a linker*. Currently this also assumes that MUSL is being used for statically linked binaries so there is no support for dynamically linked binaries with MUSL.

MUSL support largely just entailed munging around with the linker and where libs are located, and the major highlights are:

* The entirety of `libc.a` is included in `liblibc.rlib` (statically included as an archive).
* The entirety of `libunwind.a` is included in `libstd.rlib` (like with liblibc).
* The target specification for MUSL passes a number of ... flavorful options! Each option is documented in the relevant commit.
* The entire test suite currently passes with MUSL as a target, except for:
  * Dynamic linking tests are all ignored as it's not supported with MUSL
  * Stack overflow detection is not working MUSL yet (I'm not sure why)
* There is a language change included in this PR to add a `target_env` `#[cfg]` directive. This is used to conditionally build code for only MUSL (or for linux distros not MUSL). I highly suspect that this will also be used by Windows to target MSVC instead of a MinGW-based toolchain.

To build a compiler targeting MUSL you need to follow these steps:

1. Clone the current MUSL repo from `git://git.musl-libc.org/musl`. Build this as usual and install it.
2. Clone and build LLVM's [libcxxabi](http://libcxxabi.llvm.org/) library. Only the `libunwind.a` artifact is needed. I have tried using upstream libunwind's source repo but I have not gotten unwinding to work with it unfortunately. Move `libunwind.a` adjacent to MUSL's `libc.a`
3. Configure a Rust checkout with `--target=x86_64-unknown-linux-musl --musl-root=$MUSL_ROOT` where `MUSL_ROOT` is where you installed MUSL in step 1.

I hope to improve building a copy of libunwind as it's still a little sketchy and difficult to do today, but other than that everything should "just work"! This PR is not intended to include 100% comprehensive support for MUSL, as future modifications will probably be necessary.
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 28, 2015

💔 Test failed - auto-win-32-nopt-t

@alexcrichton alexcrichton force-pushed the alexcrichton:musl branch from faa1a81 to d6e7c7a Apr 28, 2015

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 28, 2015

@bors: r=brson d6e7c7a

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 28, 2015

⌛️ Testing commit d6e7c7a with merge c975c65...

bors added a commit that referenced this pull request Apr 28, 2015

Auto merge of #24777 - alexcrichton:musl, r=brson
These commits build on [some great work on reddit](http://www.reddit.com/r/rust/comments/33boew/weekend_experiment_link_rust_programs_against/) for adding MUSL support to the compiler. This goal of this PR is to enable a `--target x86_64-unknown-linux-musl` argument to the compiler to work A-OK. The outcome here is that there are 0 compile-time dependencies for a MUSL-targeting build *except for a linker*. Currently this also assumes that MUSL is being used for statically linked binaries so there is no support for dynamically linked binaries with MUSL.

MUSL support largely just entailed munging around with the linker and where libs are located, and the major highlights are:

* The entirety of `libc.a` is included in `liblibc.rlib` (statically included as an archive).
* The entirety of `libunwind.a` is included in `libstd.rlib` (like with liblibc).
* The target specification for MUSL passes a number of ... flavorful options! Each option is documented in the relevant commit.
* The entire test suite currently passes with MUSL as a target, except for:
  * Dynamic linking tests are all ignored as it's not supported with MUSL
  * Stack overflow detection is not working MUSL yet (I'm not sure why)
* There is a language change included in this PR to add a `target_env` `#[cfg]` directive. This is used to conditionally build code for only MUSL (or for linux distros not MUSL). I highly suspect that this will also be used by Windows to target MSVC instead of a MinGW-based toolchain.

To build a compiler targeting MUSL you need to follow these steps:

1. Clone the current MUSL repo from `git://git.musl-libc.org/musl`. Build this as usual and install it.
2. Clone and build LLVM's [libcxxabi](http://libcxxabi.llvm.org/) library. Only the `libunwind.a` artifact is needed. I have tried using upstream libunwind's source repo but I have not gotten unwinding to work with it unfortunately. Move `libunwind.a` adjacent to MUSL's `libc.a`
3. Configure a Rust checkout with `--target=x86_64-unknown-linux-musl --musl-root=$MUSL_ROOT` where `MUSL_ROOT` is where you installed MUSL in step 1.

I hope to improve building a copy of libunwind as it's still a little sketchy and difficult to do today, but other than that everything should "just work"! This PR is not intended to include 100% comprehensive support for MUSL, as future modifications will probably be necessary.
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 28, 2015

💔 Test failed - auto-win-64-nopt-t

test: Fix some tests to run with musl
There were a few test cases to fix:

* Dynamic libraries are not supported with MUSL right now, so all of those
  related test which force or require dylibs are ignored.
* Looks like the default stack for MUSL is smaller than glibc, so a few stack
  allocations in benchmarks were boxed up (shouldn't have a perf impact).
* Some small linkage tweaks here and there
* Out-of-stack detection does not currently work with MUSL

@alexcrichton alexcrichton force-pushed the alexcrichton:musl branch from d6e7c7a to 247842b Apr 28, 2015

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 28, 2015

@bors: r=brson 247842b

bors added a commit that referenced this pull request Apr 28, 2015

Auto merge of #24777 - alexcrichton:musl, r=brson
These commits build on [some great work on reddit](http://www.reddit.com/r/rust/comments/33boew/weekend_experiment_link_rust_programs_against/) for adding MUSL support to the compiler. This goal of this PR is to enable a `--target x86_64-unknown-linux-musl` argument to the compiler to work A-OK. The outcome here is that there are 0 compile-time dependencies for a MUSL-targeting build *except for a linker*. Currently this also assumes that MUSL is being used for statically linked binaries so there is no support for dynamically linked binaries with MUSL.

MUSL support largely just entailed munging around with the linker and where libs are located, and the major highlights are:

* The entirety of `libc.a` is included in `liblibc.rlib` (statically included as an archive).
* The entirety of `libunwind.a` is included in `libstd.rlib` (like with liblibc).
* The target specification for MUSL passes a number of ... flavorful options! Each option is documented in the relevant commit.
* The entire test suite currently passes with MUSL as a target, except for:
  * Dynamic linking tests are all ignored as it's not supported with MUSL
  * Stack overflow detection is not working MUSL yet (I'm not sure why)
* There is a language change included in this PR to add a `target_env` `#[cfg]` directive. This is used to conditionally build code for only MUSL (or for linux distros not MUSL). I highly suspect that this will also be used by Windows to target MSVC instead of a MinGW-based toolchain.

To build a compiler targeting MUSL you need to follow these steps:

1. Clone the current MUSL repo from `git://git.musl-libc.org/musl`. Build this as usual and install it.
2. Clone and build LLVM's [libcxxabi](http://libcxxabi.llvm.org/) library. Only the `libunwind.a` artifact is needed. I have tried using upstream libunwind's source repo but I have not gotten unwinding to work with it unfortunately. Move `libunwind.a` adjacent to MUSL's `libc.a`
3. Configure a Rust checkout with `--target=x86_64-unknown-linux-musl --musl-root=$MUSL_ROOT` where `MUSL_ROOT` is where you installed MUSL in step 1.

I hope to improve building a copy of libunwind as it's still a little sketchy and difficult to do today, but other than that everything should "just work"! This PR is not intended to include 100% comprehensive support for MUSL, as future modifications will probably be necessary.
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 28, 2015

⌛️ Testing commit 247842b with merge cadc67e...

@bors bors merged commit 247842b into rust-lang:master Apr 28, 2015

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details

@alexcrichton alexcrichton deleted the alexcrichton:musl branch Apr 30, 2015

@aidanhs

This comment has been minimized.

Copy link
Member

aidanhs commented May 10, 2015

@alexcrichton got any details of the issues you had with libunwind upstream? I only ask because a toy program I tried seemed to work ok, so I guess it's related to the additional complexity in the compiler?

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented May 10, 2015

@aidanhs unfortunately I could never get any more detail other than "unwinding didn't work". I was able to build libunwind upstream with musl-gcc (aka build it against MUSL's libc.a), and it was also correctly linked into the standard library and Rust programs. When running, however, it either couldn't find the unwind tables or couldn't find the handler for the unwind, as all attempts to unwind failed with "handler not found".

In your test program, did you trigger an unwind, or was it just running as usual? Also, did you configure libunwind with any special flags or anything?

let lib = match DynamicLibrary::open(None) {
Ok(l) => l,
Err(..) => return,
};

This comment has been minimized.

@nagisa

nagisa May 10, 2015

Contributor

This might be why stack overflow detection is not working.

This comment has been minimized.

@alexcrichton

alexcrichton May 10, 2015

Author Member

Hm, could you elaborate a little more? This should in theory just affect the return value of this function, which I'm not sure how connected it is to stack sizes.

This comment has been minimized.

@nagisa

nagisa May 10, 2015

Contributor

Before it failed loud and clear when this didn’t work, but now min_stack_size returns PTHREAD_STACK_MIN instead which might or might not be a correct value to use in the stack size calculations.

/me shrugs.

@aidanhs

This comment has been minimized.

Copy link
Member

aidanhs commented May 10, 2015

@alexcrichton oops, I didn't get unwinding working (though normal execution worked). I did get a different error to you though:

$ ./target/debug/binary
thread '<main>' panicked at 'mypanic', src/main.rs:28
fatal runtime error: Could not unwind stack, error = 5
Illegal instruction (core dumped)

Sorry for the noise!

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented May 10, 2015

I did get a different error to you though:

Ah that's actually the same error that I was seeing, oh well!

@asaaki asaaki referenced this pull request Aug 4, 2015

Closed

Build fails with musl #27290

@ranma42 ranma42 referenced this pull request Oct 28, 2015

Merged

1.4 release notes #29416

Centril added a commit to Centril/rust that referenced this pull request Jan 14, 2019

Rollup merge of rust-lang#57465 - jethrogb:jb/stablize-cfg-target-ven…
…dor, r=joshtriplett,Centril

Stabilize cfg_target_vendor

This stabilizes the use of `cfg(target_vendor = "...")` and removes the corresponding `cfg_target_vendor` feature. Other unstable cfgs remain behind their existing feature gates.

This functionality was added back in 2015 in rust-lang#28612 to complete the coverage of target tuples (`<arch><sub>-<vendor>-<os>-<env>`). [RFC 131](https://github.com/rust-lang/rfcs/blob/master/text/0131-target-specification.md) governs the target specification, not including `target_vendor` seems to have just been an oversight. `target_os`, `target_family`, and `target_arch` are stable as of 1.0.0. `target_env` was also not mentioned in RFC 131, was added in rust-lang#24777, never behind a feature_gate, and insta-stable at 1.1.0.

The functionality is tested in [test/run-pass/cfg/cfg-target-vendor.rs](https://github.com/rust-lang/rust/blob/master/src/test/run-pass/cfg/cfg-target-vendor.rs).

Closes rust-lang#29718

Centril added a commit to Centril/rust that referenced this pull request Jan 14, 2019

Rollup merge of rust-lang#57465 - jethrogb:jb/stablize-cfg-target-ven…
…dor, r=joshtriplett,Centril

Stabilize cfg_target_vendor

This stabilizes the use of `cfg(target_vendor = "...")` and removes the corresponding `cfg_target_vendor` feature. Other unstable cfgs remain behind their existing feature gates.

This functionality was added back in 2015 in rust-lang#28612 to complete the coverage of target tuples (`<arch><sub>-<vendor>-<os>-<env>`). [RFC 131](https://github.com/rust-lang/rfcs/blob/master/text/0131-target-specification.md) governs the target specification, not including `target_vendor` seems to have just been an oversight. `target_os`, `target_family`, and `target_arch` are stable as of 1.0.0. `target_env` was also not mentioned in RFC 131, was added in rust-lang#24777, never behind a feature_gate, and insta-stable at 1.1.0.

The functionality is tested in [test/run-pass/cfg/cfg-target-vendor.rs](https://github.com/rust-lang/rust/blob/master/src/test/run-pass/cfg/cfg-target-vendor.rs).

Closes rust-lang#29718

Centril added a commit to Centril/rust that referenced this pull request Jan 14, 2019

Rollup merge of rust-lang#57465 - jethrogb:jb/stablize-cfg-target-ven…
…dor, r=joshtriplett,Centril

Stabilize cfg_target_vendor

This stabilizes the use of `cfg(target_vendor = "...")` and removes the corresponding `cfg_target_vendor` feature. Other unstable cfgs remain behind their existing feature gates.

This functionality was added back in 2015 in rust-lang#28612 to complete the coverage of target tuples (`<arch><sub>-<vendor>-<os>-<env>`). [RFC 131](https://github.com/rust-lang/rfcs/blob/master/text/0131-target-specification.md) governs the target specification, not including `target_vendor` seems to have just been an oversight. `target_os`, `target_family`, and `target_arch` are stable as of 1.0.0. `target_env` was also not mentioned in RFC 131, was added in rust-lang#24777, never behind a feature_gate, and insta-stable at 1.1.0.

The functionality is tested in [test/run-pass/cfg/cfg-target-vendor.rs](https://github.com/rust-lang/rust/blob/master/src/test/run-pass/cfg/cfg-target-vendor.rs).

Closes rust-lang#29718

Centril added a commit to Centril/rust that referenced this pull request Jan 14, 2019

Rollup merge of rust-lang#57465 - jethrogb:jb/stablize-cfg-target-ven…
…dor, r=joshtriplett,Centril

Stabilize cfg_target_vendor

This stabilizes the use of `cfg(target_vendor = "...")` and removes the corresponding `cfg_target_vendor` feature. Other unstable cfgs remain behind their existing feature gates.

This functionality was added back in 2015 in rust-lang#28612 to complete the coverage of target tuples (`<arch><sub>-<vendor>-<os>-<env>`). [RFC 131](https://github.com/rust-lang/rfcs/blob/master/text/0131-target-specification.md) governs the target specification, not including `target_vendor` seems to have just been an oversight. `target_os`, `target_family`, and `target_arch` are stable as of 1.0.0. `target_env` was also not mentioned in RFC 131, was added in rust-lang#24777, never behind a feature_gate, and insta-stable at 1.1.0.

The functionality is tested in [test/run-pass/cfg/cfg-target-vendor.rs](https://github.com/rust-lang/rust/blob/master/src/test/run-pass/cfg/cfg-target-vendor.rs).

Closes rust-lang#29718
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.