address review comments

This commit is contained in:
Jorge Aparicio 2018-08-09 16:08:12 -05:00
parent eb74f21f5a
commit a0911cf95d
2 changed files with 43 additions and 60 deletions

View file

@ -69,18 +69,13 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
// This worked historically but is needed manually since #42436 (regression // This worked historically but is needed manually since #42436 (regression
// was tagged as #42791) and some more info can be found on #44443 for // was tagged as #42791) and some more info can be found on #44443 for
// emscripten itself. // emscripten itself.
let mut cmd = (|| { let mut cmd = match linker.to_str() {
if let Some(linker) = linker.to_str() { Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker),
if cfg!(windows) && linker.ends_with(".bat") { _ => match flavor {
return Command::bat_script(linker)
}
}
match flavor {
LinkerFlavor::Lld(f) => Command::lld(linker, f), LinkerFlavor::Lld(f) => Command::lld(linker, f),
_ => Command::new(linker), _ => Command::new(linker),
} }
})(); };
let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe"); let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
@ -600,33 +595,26 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary]) {
} }
} }
pub fn linker_and_flavor(sess: &Session) -> Result<(PathBuf, LinkerFlavor), ()> { pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
fn from<F>( fn infer_from(
sess: &Session, sess: &Session,
linker: Option<PathBuf>, linker: Option<PathBuf>,
flavor: Option<LinkerFlavor>, flavor: Option<LinkerFlavor>,
otherwise: F, ) -> Option<(PathBuf, LinkerFlavor)> {
) -> Result<(PathBuf, LinkerFlavor), ()>
where
F: FnOnce() -> Result<(PathBuf, LinkerFlavor), ()>
{
match (linker, flavor) { match (linker, flavor) {
(Some(linker), Some(flavor)) => Ok((linker, flavor)), (Some(linker), Some(flavor)) => Some((linker, flavor)),
// only the linker flavor is known; use the default linker for the selected flavor // only the linker flavor is known; use the default linker for the selected flavor
(None, Some(flavor)) => Ok((PathBuf::from(match flavor { (None, Some(flavor)) => Some((PathBuf::from(match flavor {
LinkerFlavor::Em => "emcc", LinkerFlavor::Em => if cfg!(windows) { "emcc.bat" } else { "emcc" },
LinkerFlavor::Gcc => "gcc", LinkerFlavor::Gcc => "gcc",
LinkerFlavor::Ld => "ld", LinkerFlavor::Ld => "ld",
LinkerFlavor::Msvc => "link.exe", LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::Lld(_) => "lld", LinkerFlavor::Lld(_) => "lld",
}), flavor)), }), flavor)),
// infer the linker flavor from the linker name
(Some(linker), None) => { (Some(linker), None) => {
let stem = linker.file_stem().and_then(|stem| stem.to_str()).ok_or_else(|| { let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
sess sess.fatal("couldn't extract file stem from specified linker");
.struct_err(&format!("couldn't extract file stem from specified linker")) }).to_owned();
.emit();
})?.to_owned();
let flavor = if stem == "emcc" { let flavor = if stem == "emcc" {
LinkerFlavor::Em LinkerFlavor::Em
@ -637,32 +625,35 @@ pub fn linker_and_flavor(sess: &Session) -> Result<(PathBuf, LinkerFlavor), ()>
} else if stem == "link" || stem == "lld-link" { } else if stem == "link" || stem == "lld-link" {
LinkerFlavor::Msvc LinkerFlavor::Msvc
} else { } else {
sess // fall back to the value in the target spec
.struct_err(&format!("couldn't infer linker flavor from specified linker")) sess.target.target.linker_flavor
.emit();
return Err(());
}; };
Ok((linker, flavor)) Some((linker, flavor))
}, },
(None, None) => otherwise(), (None, None) => None,
} }
} }
// linker and linker flavor specified via command line have precedence over what the target // linker and linker flavor specified via command line have precedence over what the target
// specification specifies // specification specifies
from(sess, sess.opts.cg.linker.clone(), sess.opts.debugging_opts.linker_flavor, || { if let Some(ret) = infer_from(
from( sess,
sess, sess.opts.cg.linker.clone(),
sess.target.target.options.linker.clone().map(PathBuf::from), sess.opts.debugging_opts.linker_flavor,
Some(sess.target.target.linker_flavor), ) {
|| { return ret;
sess }
.struct_err(&format!("no linker or linker flavor information provided"))
.emit(); if let Some(ret) = infer_from(
Err(()) sess,
}) sess.target.target.options.linker.clone().map(PathBuf::from),
}) Some(sess.target.target.linker_flavor),
) {
return ret;
}
sess.fatal("Not enough information provided to determine how to invoke the linker");
} }
// Create a dynamic library or executable // Create a dynamic library or executable
@ -675,12 +666,7 @@ fn link_natively(sess: &Session,
codegen_results: &CodegenResults, codegen_results: &CodegenResults,
tmpdir: &Path) { tmpdir: &Path) {
info!("preparing {:?} to {:?}", crate_type, out_filename); info!("preparing {:?} to {:?}", crate_type, out_filename);
let (linker, flavor) = if let Ok((linker, flavor)) = linker_and_flavor(sess) { let (linker, flavor) = linker_and_flavor(sess);
(linker, flavor)
} else {
sess.abort_if_errors();
return;
};
// The invocations of cc share some flags across platforms // The invocations of cc share some flags across platforms
let (pname, mut cmd) = get_linker(sess, &linker, flavor); let (pname, mut cmd) = get_linker(sess, &linker, flavor);

View file

@ -1503,17 +1503,14 @@ fn start_executing_work(tcx: TyCtxt,
let assembler_cmd = if modules_config.no_integrated_as { let assembler_cmd = if modules_config.no_integrated_as {
// HACK: currently we use linker (gcc) as our assembler // HACK: currently we use linker (gcc) as our assembler
if let Ok((linker, flavor)) = link::linker_and_flavor(sess) { let (linker, flavor) = link::linker_and_flavor(sess);
let (name, mut cmd) = get_linker(sess, &linker, flavor);
cmd.args(&sess.target.target.options.asm_args); let (name, mut cmd) = get_linker(sess, &linker, flavor);
Some(Arc::new(AssemblerCommand { cmd.args(&sess.target.target.options.asm_args);
name, Some(Arc::new(AssemblerCommand {
cmd, name,
})) cmd,
} else { }))
sess.abort_if_errors();
None
}
} else { } else {
None None
}; };