diff options
| author | Cassandra Fridkin <cass@swag.lgbt> | 2020-10-05 18:49:51 -0400 |
|---|---|---|
| committer | Cassandra Fridkin <cass@swag.lgbt> | 2020-10-05 18:49:51 -0400 |
| commit | 44af74f6ddf9102b358f271b371697c4b4e6dd2f (patch) | |
| tree | fd20034f9565a59750cdd1781a6a6e5f20d15a94 /compiler/rustc_codegen_ssa/src/back | |
| parent | a009e2838b25df2761093d727d322a59f69d8f68 (diff) | |
| parent | a1dfd2490a6cb456b92e469fa550dc217e20ad6d (diff) | |
| download | rust-44af74f6ddf9102b358f271b371697c4b4e6dd2f.tar.gz rust-44af74f6ddf9102b358f271b371697c4b4e6dd2f.zip | |
Merge branch 'master' into hooks
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/command.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 94 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/write.rs | 59 |
3 files changed, 143 insertions, 16 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index 0208bb73abd..503c51d24b6 100644 --- a/compiler/rustc_codegen_ssa/src/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs @@ -111,6 +111,12 @@ impl Command { LldFlavor::Link => "link", LldFlavor::Ld64 => "darwin", }); + if let LldFlavor::Wasm = flavor { + // LLVM expects host-specific formatting for @file + // arguments, but we always generate posix formatted files + // at this time. Indicate as such. + c.arg("--rsp-quoting=posix"); + } c } }; diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c044020d930..010fd4e9c5a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1076,7 +1076,7 @@ fn exec_linker( } .to_string(), ); - args.push_str("\n"); + args.push('\n'); } let file = tmpdir.join("linker-arguments"); let bytes = if sess.target.target.options.is_like_msvc { @@ -1333,9 +1333,6 @@ fn add_late_link_args( crate_type: CrateType, codegen_results: &CodegenResults, ) { - if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { - cmd.args(args); - } let any_dynamic_crate = crate_type == CrateType::Dylib || codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| { *ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic) @@ -1349,6 +1346,9 @@ fn add_late_link_args( cmd.args(args); } } + if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { + cmd.args(args); + } } /// Add arbitrary "post-link" args defined by the target spec. @@ -1524,6 +1524,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT add_pre_link_args(cmd, sess, flavor); + // NO-OPT-OUT, OBJECT-FILES-NO + add_apple_sdk(cmd, sess, flavor); + // NO-OPT-OUT add_link_script(cmd, sess, tmpdir, crate_type); @@ -2083,3 +2086,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool { config::Lto::No | config::Lto::ThinLocal => false, } } + +fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { + let arch = &sess.target.target.arch; + let os = &sess.target.target.target_os; + let llvm_target = &sess.target.target.llvm_target; + if sess.target.target.target_vendor != "apple" + || !matches!(os.as_str(), "ios" | "tvos") + || flavor != LinkerFlavor::Gcc + { + return; + } + let sdk_name = match (arch.as_str(), os.as_str()) { + ("aarch64", "tvos") => "appletvos", + ("x86_64", "tvos") => "appletvsimulator", + ("arm", "ios") => "iphoneos", + ("aarch64", "ios") => "iphoneos", + ("x86", "ios") => "iphonesimulator", + ("x86_64", "ios") if llvm_target.contains("macabi") => "macosx10.15", + ("x86_64", "ios") => "iphonesimulator", + _ => { + sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os)); + return; + } + }; + let sdk_root = match get_apple_sdk_root(sdk_name) { + Ok(s) => s, + Err(e) => { + sess.err(&e); + return; + } + }; + let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen"); + cmd.args(&["-arch", arch_name, "-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]); +} + +fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> { + // Following what clang does + // (https://github.com/llvm/llvm-project/blob/ + // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678) + // to allow the SDK path to be set. (For clang, xcrun sets + // SDKROOT; for rustc, the user or build system can set it, or we + // can fall back to checking for xcrun on PATH.) + if let Ok(sdkroot) = env::var("SDKROOT") { + let p = Path::new(&sdkroot); + match sdk_name { + // Ignore `SDKROOT` if it's clearly set for the wrong platform. + "appletvos" + if sdkroot.contains("TVSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "appletvsimulator" + if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => {} + "iphoneos" + if sdkroot.contains("iPhoneSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "iphonesimulator" + if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") => { + } + "macosx10.15" + if sdkroot.contains("iPhoneOS.platform") + || sdkroot.contains("iPhoneSimulator.platform") => {} + // Ignore `SDKROOT` if it's not a valid path. + _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} + _ => return Ok(sdkroot), + } + } + let res = + Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then( + |output| { + if output.status.success() { + Ok(String::from_utf8(output.stdout).unwrap()) + } else { + let error = String::from_utf8(output.stderr); + let error = format!("process exit with error: {}", error.unwrap()); + Err(io::Error::new(io::ErrorKind::Other, &error[..])) + } + }, + ); + + match res { + Ok(output) => Ok(output.trim().to_string()), + Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)), + } +} diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7d69bb983dd..0edf0fcd1a2 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -702,6 +702,7 @@ impl<B: WriteBackendMethods> WorkItem<B> { enum WorkItemResult<B: WriteBackendMethods> { Compiled(CompiledModule), + NeedsLink(ModuleCodegen<B::Module>), NeedsFatLTO(FatLTOInput<B>), NeedsThinLTO(String, B::ThinBuffer), } @@ -801,11 +802,8 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>( None }; - Ok(match lto_type { - ComputedLtoType::No => { - let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config)? }; - WorkItemResult::Compiled(module) - } + match lto_type { + ComputedLtoType::No => finish_intra_module_work(cgcx, module, module_config), ComputedLtoType::Thin => { let (name, thin_buffer) = B::prepare_thin(module); if let Some(path) = bitcode { @@ -813,7 +811,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>( panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e); }); } - WorkItemResult::NeedsThinLTO(name, thin_buffer) + Ok(WorkItemResult::NeedsThinLTO(name, thin_buffer)) } ComputedLtoType::Fat => match bitcode { Some(path) => { @@ -821,11 +819,11 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>( fs::write(&path, buffer.data()).unwrap_or_else(|e| { panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e); }); - WorkItemResult::NeedsFatLTO(FatLTOInput::Serialized { name, buffer }) + Ok(WorkItemResult::NeedsFatLTO(FatLTOInput::Serialized { name, buffer })) } - None => WorkItemResult::NeedsFatLTO(FatLTOInput::InMemory(module)), + None => Ok(WorkItemResult::NeedsFatLTO(FatLTOInput::InMemory(module))), }, - }) + } } fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( @@ -871,12 +869,25 @@ fn execute_lto_work_item<B: ExtraBackendMethods>( mut module: lto::LtoModuleCodegen<B>, module_config: &ModuleConfig, ) -> Result<WorkItemResult<B>, FatalError> { + let module = unsafe { module.optimize(cgcx)? }; + finish_intra_module_work(cgcx, module, module_config) +} + +fn finish_intra_module_work<B: ExtraBackendMethods>( + cgcx: &CodegenContext<B>, + module: ModuleCodegen<B::Module>, + module_config: &ModuleConfig, +) -> Result<WorkItemResult<B>, FatalError> { let diag_handler = cgcx.create_diag_handler(); - unsafe { - let module = module.optimize(cgcx)?; - let module = B::codegen(cgcx, &diag_handler, module, module_config)?; + if !cgcx.opts.debugging_opts.combine_cgu + || module.kind == ModuleKind::Metadata + || module.kind == ModuleKind::Allocator + { + let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config)? }; Ok(WorkItemResult::Compiled(module)) + } else { + Ok(WorkItemResult::NeedsLink(module)) } } @@ -891,6 +902,10 @@ pub enum Message<B: WriteBackendMethods> { thin_buffer: B::ThinBuffer, worker_id: usize, }, + NeedsLink { + module: ModuleCodegen<B::Module>, + worker_id: usize, + }, Done { result: Result<CompiledModule, Option<WorkerFatalError>>, worker_id: usize, @@ -1178,6 +1193,7 @@ fn start_executing_work<B: ExtraBackendMethods>( let mut compiled_modules = vec![]; let mut compiled_metadata_module = None; let mut compiled_allocator_module = None; + let mut needs_link = Vec::new(); let mut needs_fat_lto = Vec::new(); let mut needs_thin_lto = Vec::new(); let mut lto_import_only_modules = Vec::new(); @@ -1434,6 +1450,10 @@ fn start_executing_work<B: ExtraBackendMethods>( } } } + Message::NeedsLink { module, worker_id } => { + free_worker(worker_id); + needs_link.push(module); + } Message::NeedsFatLTO { result, worker_id } => { assert!(!started_lto); free_worker(worker_id); @@ -1462,6 +1482,18 @@ fn start_executing_work<B: ExtraBackendMethods>( } } + let needs_link = mem::take(&mut needs_link); + if !needs_link.is_empty() { + assert!(compiled_modules.is_empty()); + let diag_handler = cgcx.create_diag_handler(); + let module = B::run_link(&cgcx, &diag_handler, needs_link).map_err(|_| ())?; + let module = unsafe { + B::codegen(&cgcx, &diag_handler, module, cgcx.config(ModuleKind::Regular)) + .map_err(|_| ())? + }; + compiled_modules.push(module); + } + // Drop to print timings drop(llvm_start_time); @@ -1521,6 +1553,9 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B> Some(Ok(WorkItemResult::Compiled(m))) => { Message::Done::<B> { result: Ok(m), worker_id } } + Some(Ok(WorkItemResult::NeedsLink(m))) => { + Message::NeedsLink::<B> { module: m, worker_id } + } Some(Ok(WorkItemResult::NeedsFatLTO(m))) => { Message::NeedsFatLTO::<B> { result: m, worker_id } } |
