Auto merge of #125463 - GuillaumeGomez:rollup-287wx4y, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #125263 (rust-lld: fallback to rustc's sysroot if there's no path to the linker in the target sysroot) - #125345 (rustc_codegen_llvm: add support for writing summary bitcode) - #125362 (Actually use TAIT instead of emulating it) - #125412 (Don't suggest adding the unexpected cfgs to the build-script it-self) - #125445 (Migrate `run-make/rustdoc-with-short-out-dir-option` to `rmake.rs`) - #125452 (Cleanup check-cfg handling in core and std) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7601adcc76
32 changed files with 335 additions and 187 deletions
|
@ -200,7 +200,7 @@ fn produce_final_output_artifacts(
|
|||
// to get rid of it.
|
||||
for output_type in crate_output.outputs.keys() {
|
||||
match *output_type {
|
||||
OutputType::Bitcode => {
|
||||
OutputType::Bitcode | OutputType::ThinLinkBitcode => {
|
||||
// Cranelift doesn't have bitcode
|
||||
// user_wants_bitcode = true;
|
||||
// // Copy to .bc, but always keep the .0.bc. There is a later
|
||||
|
|
|
@ -335,6 +335,10 @@ impl ThinBufferMethods for ThinBuffer {
|
|||
fn data(&self) -> &[u8] {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn thin_link_data(&self) -> &[u8] {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GccContext {
|
||||
|
@ -414,7 +418,7 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
back::write::codegen(cgcx, dcx, module, config)
|
||||
}
|
||||
|
||||
fn prepare_thin(_module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
|
||||
fn prepare_thin(_module: ModuleCodegen<Self::Module>, _emit_summary: bool) -> (String, Self::ThinBuffer) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
|
|
@ -230,9 +230,12 @@ pub(crate) fn run_thin(
|
|||
thin_lto(cgcx, &dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold)
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
|
||||
pub(crate) fn prepare_thin(
|
||||
module: ModuleCodegen<ModuleLlvm>,
|
||||
emit_summary: bool,
|
||||
) -> (String, ThinBuffer) {
|
||||
let name = module.name;
|
||||
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true);
|
||||
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true, emit_summary);
|
||||
(name, buffer)
|
||||
}
|
||||
|
||||
|
@ -672,9 +675,9 @@ unsafe impl Send for ThinBuffer {}
|
|||
unsafe impl Sync for ThinBuffer {}
|
||||
|
||||
impl ThinBuffer {
|
||||
pub fn new(m: &llvm::Module, is_thin: bool) -> ThinBuffer {
|
||||
pub fn new(m: &llvm::Module, is_thin: bool, emit_summary: bool) -> ThinBuffer {
|
||||
unsafe {
|
||||
let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin);
|
||||
let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin, emit_summary);
|
||||
ThinBuffer(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -688,6 +691,14 @@ impl ThinBufferMethods for ThinBuffer {
|
|||
slice::from_raw_parts(ptr, len)
|
||||
}
|
||||
}
|
||||
|
||||
fn thin_link_data(&self) -> &[u8] {
|
||||
unsafe {
|
||||
let ptr = llvm::LLVMRustThinLTOBufferThinLinkDataPtr(self.0) as *const _;
|
||||
let len = llvm::LLVMRustThinLTOBufferThinLinkDataLen(self.0);
|
||||
slice::from_raw_parts(ptr, len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ThinBuffer {
|
||||
|
|
|
@ -709,13 +709,15 @@ pub(crate) unsafe fn codegen(
|
|||
// asm from LLVM and use `gcc` to create the object file.
|
||||
|
||||
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
|
||||
let bc_summary_out =
|
||||
cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name);
|
||||
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
|
||||
|
||||
if config.bitcode_needed() {
|
||||
let _timer = cgcx
|
||||
.prof
|
||||
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name);
|
||||
let thin = ThinBuffer::new(llmod, config.emit_thin_lto);
|
||||
let thin = ThinBuffer::new(llmod, config.emit_thin_lto, config.emit_thin_lto_summary);
|
||||
let data = thin.data();
|
||||
|
||||
if let Some(bitcode_filename) = bc_out.file_name() {
|
||||
|
@ -726,6 +728,25 @@ pub(crate) unsafe fn codegen(
|
|||
);
|
||||
}
|
||||
|
||||
if config.emit_thin_lto_summary
|
||||
&& let Some(thin_link_bitcode_filename) = bc_summary_out.file_name()
|
||||
{
|
||||
let summary_data = thin.thin_link_data();
|
||||
cgcx.prof.artifact_size(
|
||||
"llvm_bitcode_summary",
|
||||
thin_link_bitcode_filename.to_string_lossy(),
|
||||
summary_data.len() as u64,
|
||||
);
|
||||
|
||||
let _timer = cgcx.prof.generic_activity_with_arg(
|
||||
"LLVM_module_codegen_emit_bitcode_summary",
|
||||
&*module.name,
|
||||
);
|
||||
if let Err(err) = fs::write(&bc_summary_out, summary_data) {
|
||||
dcx.emit_err(WriteBytecode { path: &bc_summary_out, err });
|
||||
}
|
||||
}
|
||||
|
||||
if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
|
||||
let _timer = cgcx
|
||||
.prof
|
||||
|
|
|
@ -237,8 +237,11 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
) -> Result<CompiledModule, FatalError> {
|
||||
back::write::codegen(cgcx, dcx, module, config)
|
||||
}
|
||||
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
|
||||
back::lto::prepare_thin(module)
|
||||
fn prepare_thin(
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
emit_summary: bool,
|
||||
) -> (String, Self::ThinBuffer) {
|
||||
back::lto::prepare_thin(module, emit_summary)
|
||||
}
|
||||
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer) {
|
||||
(module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod()))
|
||||
|
|
|
@ -2350,10 +2350,16 @@ extern "C" {
|
|||
#[allow(improper_ctypes)]
|
||||
pub fn LLVMRustModuleInstructionStats(M: &Module, Str: &RustString);
|
||||
|
||||
pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool) -> &'static mut ThinLTOBuffer;
|
||||
pub fn LLVMRustThinLTOBufferCreate(
|
||||
M: &Module,
|
||||
is_thin: bool,
|
||||
emit_summary: bool,
|
||||
) -> &'static mut ThinLTOBuffer;
|
||||
pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer);
|
||||
pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char;
|
||||
pub fn LLVMRustThinLTOBufferLen(M: &ThinLTOBuffer) -> size_t;
|
||||
pub fn LLVMRustThinLTOBufferThinLinkDataPtr(M: &ThinLTOBuffer) -> *const c_char;
|
||||
pub fn LLVMRustThinLTOBufferThinLinkDataLen(M: &ThinLTOBuffer) -> size_t;
|
||||
pub fn LLVMRustCreateThinLTOData(
|
||||
Modules: *const ThinLTOModule,
|
||||
NumModules: c_uint,
|
||||
|
|
|
@ -212,6 +212,8 @@ codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, fo
|
|||
|
||||
codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
|
||||
|
||||
codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot
|
||||
|
||||
codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time
|
||||
|
||||
codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link
|
||||
|
|
|
@ -3141,13 +3141,21 @@ fn add_lld_args(
|
|||
|
||||
let self_contained_linker = self_contained_cli || self_contained_target;
|
||||
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
|
||||
let mut linker_path_exists = false;
|
||||
for path in sess.get_tools_search_paths(false) {
|
||||
let linker_path = path.join("gcc-ld");
|
||||
linker_path_exists |= linker_path.exists();
|
||||
cmd.arg({
|
||||
let mut arg = OsString::from("-B");
|
||||
arg.push(path.join("gcc-ld"));
|
||||
arg.push(linker_path);
|
||||
arg
|
||||
});
|
||||
}
|
||||
if !linker_path_exists {
|
||||
// As a sanity check, we emit an error if none of these paths exist: we want
|
||||
// self-contained linking and have no linker.
|
||||
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of
|
||||
|
|
|
@ -108,6 +108,7 @@ pub struct ModuleConfig {
|
|||
pub emit_asm: bool,
|
||||
pub emit_obj: EmitObj,
|
||||
pub emit_thin_lto: bool,
|
||||
pub emit_thin_lto_summary: bool,
|
||||
pub bc_cmdline: String,
|
||||
|
||||
// Miscellaneous flags. These are mostly copied from command-line
|
||||
|
@ -232,6 +233,10 @@ impl ModuleConfig {
|
|||
),
|
||||
emit_obj,
|
||||
emit_thin_lto: sess.opts.unstable_opts.emit_thin_lto,
|
||||
emit_thin_lto_summary: if_regular!(
|
||||
sess.opts.output_types.contains_key(&OutputType::ThinLinkBitcode),
|
||||
false
|
||||
),
|
||||
bc_cmdline: sess.target.bitcode_llvm_cmdline.to_string(),
|
||||
|
||||
verify_llvm_ir: sess.verify_llvm_ir(),
|
||||
|
@ -283,6 +288,7 @@ impl ModuleConfig {
|
|||
|
||||
pub fn bitcode_needed(&self) -> bool {
|
||||
self.emit_bc
|
||||
|| self.emit_thin_lto_summary
|
||||
|| self.emit_obj == EmitObj::Bitcode
|
||||
|| self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)
|
||||
}
|
||||
|
@ -630,6 +636,9 @@ fn produce_final_output_artifacts(
|
|||
// them for making an rlib.
|
||||
copy_if_one_unit(OutputType::Bitcode, true);
|
||||
}
|
||||
OutputType::ThinLinkBitcode => {
|
||||
copy_if_one_unit(OutputType::ThinLinkBitcode, false);
|
||||
}
|
||||
OutputType::LlvmAssembly => {
|
||||
copy_if_one_unit(OutputType::LlvmAssembly, false);
|
||||
}
|
||||
|
@ -883,7 +892,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
|
|||
match lto_type {
|
||||
ComputedLtoType::No => finish_intra_module_work(cgcx, module, module_config),
|
||||
ComputedLtoType::Thin => {
|
||||
let (name, thin_buffer) = B::prepare_thin(module);
|
||||
let (name, thin_buffer) = B::prepare_thin(module, false);
|
||||
if let Some(path) = bitcode {
|
||||
fs::write(&path, thin_buffer.data()).unwrap_or_else(|e| {
|
||||
panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e);
|
||||
|
|
|
@ -413,6 +413,10 @@ pub struct UnableToExeLinker {
|
|||
#[diag(codegen_ssa_msvc_missing_linker)]
|
||||
pub struct MsvcMissingLinker;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_self_contained_linker_missing)]
|
||||
pub struct SelfContainedLinkerMissing;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_check_installed_visual_studio)]
|
||||
pub struct CheckInstalledVisualStudio;
|
||||
|
|
|
@ -56,12 +56,16 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
|
|||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<CompiledModule, FatalError>;
|
||||
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer);
|
||||
fn prepare_thin(
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
want_summary: bool,
|
||||
) -> (String, Self::ThinBuffer);
|
||||
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer);
|
||||
}
|
||||
|
||||
pub trait ThinBufferMethods: Send + Sync {
|
||||
fn data(&self) -> &[u8];
|
||||
fn thin_link_data(&self) -> &[u8];
|
||||
}
|
||||
|
||||
pub trait ModuleBufferMethods: Send + Sync {
|
||||
|
|
|
@ -42,6 +42,22 @@ fn to_check_cfg_arg(name: Symbol, value: Option<Symbol>, quotes: EscapeQuotes) -
|
|||
}
|
||||
}
|
||||
|
||||
fn cargo_help_sub(
|
||||
sess: &Session,
|
||||
inst: &impl Fn(EscapeQuotes) -> String,
|
||||
) -> lints::UnexpectedCfgCargoHelp {
|
||||
// We don't want to suggest the `build.rs` way to expected cfgs if we are already in a
|
||||
// `build.rs`. We therefor do a best effort check (looking if the `--crate-name` is
|
||||
// `build_script_build`) to try to figure out if we are building a Cargo build script
|
||||
|
||||
let unescaped = &inst(EscapeQuotes::No);
|
||||
if matches!(&sess.opts.crate_name, Some(crate_name) if crate_name == "build_script_build") {
|
||||
lints::UnexpectedCfgCargoHelp::lint_cfg(unescaped)
|
||||
} else {
|
||||
lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn unexpected_cfg_name(
|
||||
sess: &Session,
|
||||
(name, name_span): (Symbol, Span),
|
||||
|
@ -162,14 +178,7 @@ pub(super) fn unexpected_cfg_name(
|
|||
let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);
|
||||
|
||||
let invocation_help = if is_from_cargo {
|
||||
let sub = if !is_feature_cfg {
|
||||
Some(lints::UnexpectedCfgCargoHelp::new(
|
||||
&inst(EscapeQuotes::No),
|
||||
&inst(EscapeQuotes::Yes),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None };
|
||||
lints::unexpected_cfg_name::InvocationHelp::Cargo { sub }
|
||||
} else {
|
||||
lints::unexpected_cfg_name::InvocationHelp::Rustc(lints::UnexpectedCfgRustcHelp::new(
|
||||
|
@ -267,10 +276,7 @@ pub(super) fn unexpected_cfg_value(
|
|||
Some(lints::unexpected_cfg_value::CargoHelp::DefineFeatures)
|
||||
}
|
||||
} else if !is_cfg_a_well_know_name {
|
||||
Some(lints::unexpected_cfg_value::CargoHelp::Other(lints::UnexpectedCfgCargoHelp::new(
|
||||
&inst(EscapeQuotes::No),
|
||||
&inst(EscapeQuotes::Yes),
|
||||
)))
|
||||
Some(lints::unexpected_cfg_value::CargoHelp::Other(cargo_help_sub(sess, &inst)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
@ -1962,21 +1962,33 @@ pub struct UnitBindingsDiag {
|
|||
pub struct BuiltinNamedAsmLabel;
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[help(lint_unexpected_cfg_add_cargo_feature)]
|
||||
#[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
|
||||
#[help(lint_unexpected_cfg_add_build_rs_println)]
|
||||
pub struct UnexpectedCfgCargoHelp {
|
||||
pub build_rs_println: String,
|
||||
pub cargo_toml_lint_cfg: String,
|
||||
pub enum UnexpectedCfgCargoHelp {
|
||||
#[help(lint_unexpected_cfg_add_cargo_feature)]
|
||||
#[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
|
||||
LintCfg { cargo_toml_lint_cfg: String },
|
||||
#[help(lint_unexpected_cfg_add_cargo_feature)]
|
||||
#[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
|
||||
#[help(lint_unexpected_cfg_add_build_rs_println)]
|
||||
LintCfgAndBuildRs { cargo_toml_lint_cfg: String, build_rs_println: String },
|
||||
}
|
||||
|
||||
impl UnexpectedCfgCargoHelp {
|
||||
pub fn new(unescaped: &str, escaped: &str) -> Self {
|
||||
Self {
|
||||
cargo_toml_lint_cfg: format!(
|
||||
"\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{unescaped}'] }}",
|
||||
),
|
||||
build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");",),
|
||||
fn cargo_toml_lint_cfg(unescaped: &str) -> String {
|
||||
format!(
|
||||
"\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{unescaped}'] }}"
|
||||
)
|
||||
}
|
||||
|
||||
pub fn lint_cfg(unescaped: &str) -> Self {
|
||||
UnexpectedCfgCargoHelp::LintCfg {
|
||||
cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self {
|
||||
UnexpectedCfgCargoHelp::LintCfgAndBuildRs {
|
||||
cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
|
||||
build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1488,13 +1488,15 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
|
|||
// a ThinLTO summary attached.
|
||||
struct LLVMRustThinLTOBuffer {
|
||||
std::string data;
|
||||
std::string thin_link_data;
|
||||
};
|
||||
|
||||
extern "C" LLVMRustThinLTOBuffer*
|
||||
LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
|
||||
LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) {
|
||||
auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
|
||||
{
|
||||
auto OS = raw_string_ostream(Ret->data);
|
||||
auto ThinLinkOS = raw_string_ostream(Ret->thin_link_data);
|
||||
{
|
||||
if (is_thin) {
|
||||
PassBuilder PB;
|
||||
|
@ -1508,7 +1510,10 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
|
|||
PB.registerLoopAnalyses(LAM);
|
||||
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
|
||||
ModulePassManager MPM;
|
||||
MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
|
||||
// We only pass ThinLinkOS to be filled in if we want the summary,
|
||||
// because otherwise LLVM does extra work and may double-emit some
|
||||
// errors or warnings.
|
||||
MPM.addPass(ThinLTOBitcodeWriterPass(OS, emit_summary ? &ThinLinkOS : nullptr));
|
||||
MPM.run(*unwrap(M), MAM);
|
||||
} else {
|
||||
WriteBitcodeToFile(*unwrap(M), OS);
|
||||
|
@ -1533,6 +1538,16 @@ LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
|
|||
return Buffer->data.length();
|
||||
}
|
||||
|
||||
extern "C" const void*
|
||||
LLVMRustThinLTOBufferThinLinkDataPtr(const LLVMRustThinLTOBuffer *Buffer) {
|
||||
return Buffer->thin_link_data.data();
|
||||
}
|
||||
|
||||
extern "C" size_t
|
||||
LLVMRustThinLTOBufferThinLinkDataLen(const LLVMRustThinLTOBuffer *Buffer) {
|
||||
return Buffer->thin_link_data.length();
|
||||
}
|
||||
|
||||
// This is what we used to parse upstream bitcode for actual ThinLTO
|
||||
// processing. We'll call this once per module optimized through ThinLTO, and
|
||||
// it'll be called concurrently on many threads.
|
||||
|
|
|
@ -465,6 +465,7 @@ impl FromStr for SplitDwarfKind {
|
|||
#[derive(Encodable, Decodable)]
|
||||
pub enum OutputType {
|
||||
Bitcode,
|
||||
ThinLinkBitcode,
|
||||
Assembly,
|
||||
LlvmAssembly,
|
||||
Mir,
|
||||
|
@ -492,6 +493,7 @@ impl OutputType {
|
|||
match *self {
|
||||
OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true,
|
||||
OutputType::Bitcode
|
||||
| OutputType::ThinLinkBitcode
|
||||
| OutputType::Assembly
|
||||
| OutputType::LlvmAssembly
|
||||
| OutputType::Mir
|
||||
|
@ -502,6 +504,7 @@ impl OutputType {
|
|||
pub fn shorthand(&self) -> &'static str {
|
||||
match *self {
|
||||
OutputType::Bitcode => "llvm-bc",
|
||||
OutputType::ThinLinkBitcode => "thin-link-bitcode",
|
||||
OutputType::Assembly => "asm",
|
||||
OutputType::LlvmAssembly => "llvm-ir",
|
||||
OutputType::Mir => "mir",
|
||||
|
@ -518,6 +521,7 @@ impl OutputType {
|
|||
"llvm-ir" => OutputType::LlvmAssembly,
|
||||
"mir" => OutputType::Mir,
|
||||
"llvm-bc" => OutputType::Bitcode,
|
||||
"thin-link-bitcode" => OutputType::ThinLinkBitcode,
|
||||
"obj" => OutputType::Object,
|
||||
"metadata" => OutputType::Metadata,
|
||||
"link" => OutputType::Exe,
|
||||
|
@ -528,8 +532,9 @@ impl OutputType {
|
|||
|
||||
fn shorthands_display() -> String {
|
||||
format!(
|
||||
"`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
|
||||
"`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
|
||||
OutputType::Bitcode.shorthand(),
|
||||
OutputType::ThinLinkBitcode.shorthand(),
|
||||
OutputType::Assembly.shorthand(),
|
||||
OutputType::LlvmAssembly.shorthand(),
|
||||
OutputType::Mir.shorthand(),
|
||||
|
@ -543,6 +548,7 @@ impl OutputType {
|
|||
pub fn extension(&self) -> &'static str {
|
||||
match *self {
|
||||
OutputType::Bitcode => "bc",
|
||||
OutputType::ThinLinkBitcode => "indexing.o",
|
||||
OutputType::Assembly => "s",
|
||||
OutputType::LlvmAssembly => "ll",
|
||||
OutputType::Mir => "mir",
|
||||
|
@ -559,9 +565,11 @@ impl OutputType {
|
|||
| OutputType::LlvmAssembly
|
||||
| OutputType::Mir
|
||||
| OutputType::DepInfo => true,
|
||||
OutputType::Bitcode | OutputType::Object | OutputType::Metadata | OutputType::Exe => {
|
||||
false
|
||||
}
|
||||
OutputType::Bitcode
|
||||
| OutputType::ThinLinkBitcode
|
||||
| OutputType::Object
|
||||
| OutputType::Metadata
|
||||
| OutputType::Exe => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -644,6 +652,7 @@ impl OutputTypes {
|
|||
pub fn should_codegen(&self) -> bool {
|
||||
self.0.keys().any(|k| match *k {
|
||||
OutputType::Bitcode
|
||||
| OutputType::ThinLinkBitcode
|
||||
| OutputType::Assembly
|
||||
| OutputType::LlvmAssembly
|
||||
| OutputType::Mir
|
||||
|
@ -657,6 +666,7 @@ impl OutputTypes {
|
|||
pub fn should_link(&self) -> bool {
|
||||
self.0.keys().any(|k| match *k {
|
||||
OutputType::Bitcode
|
||||
| OutputType::ThinLinkBitcode
|
||||
| OutputType::Assembly
|
||||
| OutputType::LlvmAssembly
|
||||
| OutputType::Mir
|
||||
|
@ -1769,6 +1779,12 @@ fn parse_output_types(
|
|||
display = OutputType::shorthands_display(),
|
||||
))
|
||||
});
|
||||
if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
|
||||
early_dcx.early_fatal(format!(
|
||||
"{} requested but -Zunstable-options not specified",
|
||||
OutputType::ThinLinkBitcode.shorthand()
|
||||
));
|
||||
}
|
||||
output_types.insert(output_type, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,14 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
|||
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
|
||||
}
|
||||
|
||||
/// Returns a path to the target's `bin` folder within its `rustlib` path in the sysroot. This is
|
||||
/// where binaries are usually installed, e.g. the self-contained linkers, lld-wrappers, LLVM tools,
|
||||
/// etc.
|
||||
pub fn make_target_bin_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
||||
let rustlib_path = rustc_target::target_rustlib_path(sysroot, target_triple);
|
||||
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("bin")])
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn current_dll_path() -> Result<PathBuf, String> {
|
||||
use std::ffi::{CStr, OsStr};
|
||||
|
|
|
@ -449,15 +449,24 @@ impl Session {
|
|||
)
|
||||
}
|
||||
|
||||
/// Returns a list of directories where target-specific tool binaries are located.
|
||||
/// Returns a list of directories where target-specific tool binaries are located. Some fallback
|
||||
/// directories are also returned, for example if `--sysroot` is used but tools are missing
|
||||
/// (#125246): we also add the bin directories to the sysroot where rustc is located.
|
||||
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
|
||||
let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, config::host_triple());
|
||||
let p = PathBuf::from_iter([
|
||||
Path::new(&self.sysroot),
|
||||
Path::new(&rustlib_path),
|
||||
Path::new("bin"),
|
||||
]);
|
||||
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
|
||||
let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple());
|
||||
let fallback_sysroot_paths = filesearch::sysroot_candidates()
|
||||
.into_iter()
|
||||
.map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple()));
|
||||
let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths);
|
||||
|
||||
if self_contained {
|
||||
// The self-contained tools are expected to be e.g. in `bin/self-contained` in the
|
||||
// sysroot's `rustlib` path, so we add such a subfolder to the bin path, and the
|
||||
// fallback paths.
|
||||
search_paths.flat_map(|path| [path.clone(), path.join("self-contained")]).collect()
|
||||
} else {
|
||||
search_paths.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue