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

Don't use static crt by default when build proc-macro #69519

Merged
merged 9 commits into from Mar 17, 2020
11 changes: 6 additions & 5 deletions src/librustc_codegen_ssa/back/link.rs
Expand Up @@ -497,7 +497,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
cmd.args(args);
}
if let Some(args) = sess.target.target.options.pre_link_args_crt.get(&flavor) {
if sess.crt_static() {
if sess.crt_static(Some(crate_type)) {
cmd.args(args);
}
}
Expand All @@ -523,7 +523,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
cmd.arg(get_file_path(sess, obj));
}

if crate_type == config::CrateType::Executable && sess.crt_static() {
if crate_type == config::CrateType::Executable && sess.crt_static(Some(crate_type)) {
for obj in &sess.target.target.options.pre_link_objects_exe_crt {
cmd.arg(get_file_path(sess, obj));
}
Expand Down Expand Up @@ -558,7 +558,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
for obj in &sess.target.target.options.post_link_objects {
cmd.arg(get_file_path(sess, obj));
}
if sess.crt_static() {
if sess.crt_static(Some(crate_type)) {
for obj in &sess.target.target.options.post_link_objects_crt {
cmd.arg(get_file_path(sess, obj));
}
Expand Down Expand Up @@ -1288,7 +1288,8 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
let more_args = &sess.opts.cg.link_arg;
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());

if is_pic(sess) && !sess.crt_static() && !args.any(|x| *x == "-static") {
if is_pic(sess) && !sess.crt_static(Some(crate_type)) && !args.any(|x| *x == "-static")
{
position_independent_executable = true;
}
}
Expand Down Expand Up @@ -1373,7 +1374,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
if crate_type != config::CrateType::Executable {
cmd.build_dylib(out_filename);
}
if crate_type == config::CrateType::Executable && sess.crt_static() {
if crate_type == config::CrateType::Executable && sess.crt_static(Some(crate_type)) {
cmd.build_static_executable();
}

Expand Down
4 changes: 3 additions & 1 deletion src/librustc_codegen_utils/link.rs
Expand Up @@ -167,7 +167,9 @@ pub fn invalid_output_for_target(sess: &Session, crate_type: config::CrateType)
if !sess.target.target.options.dynamic_linking {
return true;
}
if sess.crt_static() && !sess.target.target.options.crt_static_allows_dylibs {
if sess.crt_static(Some(crate_type))
&& !sess.target.target.options.crt_static_allows_dylibs
{
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_interface/util.rs
Expand Up @@ -49,7 +49,7 @@ pub fn add_configuration(

cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat))));

if sess.crt_static_feature() {
if sess.crt_static_feature(None) {
cfg.insert((tf, Some(Symbol::intern("crt-static"))));
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_metadata/dependency_format.rs
Expand Up @@ -97,7 +97,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {

// If the global prefer_dynamic switch is turned off, or the final
// executable will be statically linked, prefer static crate linkage.
config::CrateType::Executable if !sess.opts.cg.prefer_dynamic || sess.crt_static() => {
config::CrateType::Executable
if !sess.opts.cg.prefer_dynamic || sess.crt_static(Some(ty)) =>
{
Linkage::Static
}
config::CrateType::Executable => Linkage::Dynamic,
Expand Down Expand Up @@ -129,7 +131,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
// If any are not found, generate some nice pretty errors.
if ty == config::CrateType::Staticlib
|| (ty == config::CrateType::Executable
&& sess.crt_static()
&& sess.crt_static(Some(ty))
&& !sess.target.target.options.crt_static_allows_dylibs)
{
for &cnum in tcx.crates().iter() {
Expand Down
41 changes: 33 additions & 8 deletions src/librustc_session/session.rs
Expand Up @@ -540,25 +540,50 @@ impl Session {
.unwrap_or(self.opts.debug_assertions)
}

pub fn crt_static(&self) -> bool {
/// Check whether this compile session and crate type use static crt.
pub fn crt_static(&self, crate_type: Option<config::CrateType>) -> bool {
// If the target does not opt in to crt-static support, use its default.
if self.target.target.options.crt_static_respected {
self.crt_static_feature()
self.crt_static_feature(crate_type)
} else {
self.target.target.options.crt_static_default
}
}

pub fn crt_static_feature(&self) -> bool {
/// Check whether this compile session and crate type use `crt-static` feature.
pub fn crt_static_feature(&self, crate_type: Option<config::CrateType>) -> bool {
let requested_features = self.opts.cg.target_feature.split(',');
let found_negative = requested_features.clone().any(|r| r == "-crt-static");
let found_positive = requested_features.clone().any(|r| r == "+crt-static");

// If the target we're compiling for requests a static crt by default,
// then see if the `-crt-static` feature was passed to disable that.
// Otherwise if we don't have a static crt by default then see if the
// `+crt-static` feature was passed.
if self.target.target.options.crt_static_default { !found_negative } else { found_positive }
if self.target.target.options.crt_static_default {
12101111 marked this conversation as resolved.
Show resolved Hide resolved
// `proc-macro` always required to be compiled to dylibs.
// We don't use a static crt unless the `+crt-static` feature was passed.
if !self.target.target.options.crt_static_allows_dylibs {
12101111 marked this conversation as resolved.
Show resolved Hide resolved
match crate_type {
Some(config::CrateType::ProcMacro) => found_positive,
Some(_) => !found_negative,
None => {
// FIXME: When crate_type is not available,
// we use compiler options to determine the crate_type.
// We can't check `#![crate_type = "proc-macro"]` here.
if self.opts.crate_types.contains(&config::CrateType::ProcMacro) {
found_positive
} else {
!found_negative
}
}
}
} else {
// If the target we're compiling for requests a static crt by default,
// then see if the `-crt-static` feature was passed to disable that.
!found_negative
}
} else {
// If the target we're compiling for don't have a static crt by default then see if the
// `+crt-static` feature was passed.
found_positive
}
}

pub fn must_not_eliminate_frame_pointers(&self) -> bool {
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/proc-macro/musl-proc-macro.rs
@@ -0,0 +1,15 @@
// Test proc-macro crate can be built without addtional RUSTFLAGS
// on musl target

// build-pass
// only-musl
Copy link
Contributor

Choose a reason for hiding this comment

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

This test doesn't depend on any musl-specific functionality, so I would expect it to run everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It depend on musl target but CI don't have it.

2020-03-03T09:46:02.3188089Z error[E0463]: can't find crate for `std`
2020-03-03T09:46:02.3188535Z    |
2020-03-03T09:46:02.3189112Z    = note: the `x86_64-unknown-linux-musl` target may not be installed
2020-03-03T09:46:02.3189589Z error: aborting due to previous error
2020-03-03T09:46:02.3189910Z 
2020-03-03T09:46:02.3190426Z For more information about this error, try `rustc --explain E0463`.

Copy link
Contributor

Choose a reason for hiding this comment

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

Which CI job was it? This is a problem with the CI configuration, not something that needs to be worked around in the test. Specifically, the musl targets built by CI are missing the dynamic version of libstd. To fix this, they need to be built with crt_static=false (the config.toml option, not the rustc flag), like the dist-x86_64-musl job does:

--set target.x86_64-unknown-linux-musl.crt-static=false \

Copy link
Contributor

Choose a reason for hiding this comment

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

@smaeul it failed on x86_64-gnu-llvm-7.

Copy link
Contributor

Choose a reason for hiding this comment

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

The x86_64-gnu-llvm-7 job only builds for x86_64-unknown-linux-gnu. It doesn't look like it does anything with musl at all. So where did "--target=x86_64-unknown-linux-musl" in the rustc arguments for this test come from?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I see, the old version of the test had compile-flags: --target=x86_64-unknown-linux-musl in it. That was the problem. After removing that line, the test should work on all targets.

So since the behavior tested here is not musl-specific, I would suggest 1) removing only-musl and 2) renaming the test to mention crt-static instead of musl.

#![crate_type = "proc-macro"]

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro_derive(Foo)]
pub fn derive_foo(input: TokenStream) -> TokenStream {
input
}