Simplify temp path creation a bit

This commit is contained in:
Michael Goulet 2025-04-06 23:37:30 +00:00
parent e643f59f6d
commit effef88ac7
13 changed files with 70 additions and 92 deletions

View file

@ -169,8 +169,8 @@ fn produce_final_output_artifacts(
if codegen_results.modules.len() == 1 {
// 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`.
let module_name = Some(&codegen_results.modules[0].name[..]);
let path = crate_output.temp_path(output_type, module_name);
let path =
crate_output.temp_path_for_cgu(output_type, &codegen_results.modules[0].name);
let output = crate_output.path(output_type);
if !output_type.is_text_output() && output.is_tty() {
sess.dcx()
@ -183,22 +183,16 @@ fn produce_final_output_artifacts(
ensure_removed(sess.dcx(), &path);
}
} else {
let extension = crate_output
.temp_path(output_type, None)
.extension()
.unwrap()
.to_str()
.unwrap()
.to_owned();
if crate_output.outputs.contains_explicit_name(&output_type) {
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
// no good solution for this case, so warn the user.
sess.dcx().emit_warn(ssa_errors::IgnoringEmitPath { extension });
sess.dcx()
.emit_warn(ssa_errors::IgnoringEmitPath { extension: output_type.extension() });
} else if crate_output.single_output_file.is_some() {
// 3) Multiple codegen units, with `-o some_name`. We have
// no good solution for this case, so warn the user.
sess.dcx().emit_warn(ssa_errors::IgnoringOutput { extension });
sess.dcx()
.emit_warn(ssa_errors::IgnoringOutput { extension: output_type.extension() });
} else {
// 4) Multiple codegen units, but no explicit name. We
// just leave the `foo.0.x` files in place.
@ -409,7 +403,7 @@ fn emit_module(
object.set_section_data(comment_section, producer, 1);
}
let tmp_file = output_filenames.temp_path(OutputType::Object, Some(&name));
let tmp_file = output_filenames.temp_path_for_cgu(OutputType::Object, &name);
let file = match File::create(&tmp_file) {
Ok(file) => file,
Err(err) => return Err(format!("error creating object file: {}", err)),
@ -450,7 +444,7 @@ fn reuse_workproduct_for_cgu(
) -> Result<ModuleCodegenResult, String> {
let work_product = cgu.previous_work_product(tcx);
let obj_out_regular =
tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
tcx.output_filenames(()).temp_path_for_cgu(OutputType::Object, cgu.name().as_str());
let source_file_regular = rustc_incremental::in_incr_comp_dir_sess(
&tcx.sess,
&work_product.saved_files.get("o").expect("no saved object file in work product"),
@ -627,7 +621,7 @@ fn emit_metadata_module(tcx: TyCtxt<'_>, metadata: &EncodedMetadata) -> Compiled
.to_string();
let tmp_file =
tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
tcx.output_filenames(()).temp_path_for_cgu(OutputType::Metadata, &metadata_cgu_name);
let symbol_name = rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx);
let obj = create_compressed_metadata_file(tcx.sess, metadata, &symbol_name);

View file

@ -146,7 +146,7 @@ pub(crate) fn compile_global_asm(
global_asm.push('\n');
let global_asm_object_file = add_file_stem_postfix(
config.output_filenames.temp_path(OutputType::Object, Some(cgu_name)),
config.output_filenames.temp_path_for_cgu(OutputType::Object, cgu_name),
".asm",
);

View file

@ -24,19 +24,15 @@ pub(crate) unsafe fn codegen(
{
let context = &module.module_llvm.context;
let module_name = module.name.clone();
let should_combine_object_files = module.module_llvm.should_combine_object_files;
let module_name = Some(&module_name[..]);
// NOTE: Only generate object files with GIMPLE when this environment variable is set for
// now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit).
// TODO(antoyo): remove this environment variable.
let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1");
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
let bc_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Bitcode, &module.name);
let obj_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Object, &module.name);
if config.bitcode_needed() {
if fat_lto {
@ -117,14 +113,15 @@ pub(crate) unsafe fn codegen(
}
if config.emit_ir {
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
let out =
cgcx.output_filenames.temp_path_for_cgu(OutputType::LlvmAssembly, &module.name);
std::fs::write(out, "").expect("write file");
}
if config.emit_asm {
let _timer =
cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name);
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
let path = cgcx.output_filenames.temp_path_for_cgu(OutputType::Assembly, &module.name);
context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str"));
}

View file

@ -119,14 +119,14 @@ pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTar
tcx.output_filenames(()).split_dwarf_path(
tcx.sess.split_debuginfo(),
tcx.sess.opts.unstable_opts.split_dwarf_kind,
Some(mod_name),
mod_name,
)
} else {
None
};
let output_obj_file =
Some(tcx.output_filenames(()).temp_path(OutputType::Object, Some(mod_name)));
Some(tcx.output_filenames(()).temp_path_for_cgu(OutputType::Object, mod_name));
let config = TargetMachineFactoryConfig { split_dwarf_file, output_obj_file };
target_machine_factory(
@ -330,8 +330,7 @@ pub(crate) fn save_temp_bitcode(
return;
}
let ext = format!("{name}.bc");
let cgu = Some(&module.name[..]);
let path = cgcx.output_filenames.temp_path_ext(&ext, cgu);
let path = cgcx.output_filenames.temp_path_ext_for_cgu(&ext, &module.name);
write_bitcode_to_file(module, &path)
}
@ -694,11 +693,8 @@ pub(crate) unsafe fn optimize(
let llcx = &*module.module_llvm.llcx;
let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt);
let module_name = module.name.clone();
let module_name = Some(&module_name[..]);
if config.emit_no_opt_bc {
let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
let out = cgcx.output_filenames.temp_path_ext_for_cgu("no-opt.bc", &module.name);
write_bitcode_to_file(module, &out)
}
@ -744,7 +740,7 @@ pub(crate) unsafe fn optimize(
let thin_lto_buffer = unsafe { ThinBuffer::from_raw_ptr(thin_lto_buffer) };
module.thin_lto_buffer = Some(thin_lto_buffer.data().to_vec());
let bc_summary_out =
cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name);
cgcx.output_filenames.temp_path_for_cgu(OutputType::ThinLinkBitcode, &module.name);
if config.emit_thin_lto_summary
&& let Some(thin_link_bitcode_filename) = bc_summary_out.file_name()
{
@ -801,8 +797,6 @@ pub(crate) unsafe fn codegen(
let llmod = module.module_llvm.llmod();
let llcx = &*module.module_llvm.llcx;
let tm = &*module.module_llvm.tm;
let module_name = module.name.clone();
let module_name = Some(&module_name[..]);
let _handlers =
DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::Codegen);
@ -814,8 +808,8 @@ pub(crate) unsafe fn codegen(
// copy it to the .o file, and delete the bitcode if it wasn't
// otherwise requested.
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
let bc_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Bitcode, &module.name);
let obj_out = cgcx.output_filenames.temp_path_for_cgu(OutputType::Object, &module.name);
if config.bitcode_needed() {
if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
@ -857,7 +851,8 @@ pub(crate) unsafe fn codegen(
if config.emit_ir {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &*module.name);
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
let out =
cgcx.output_filenames.temp_path_for_cgu(OutputType::LlvmAssembly, &module.name);
let out_c = path_to_c_string(&out);
extern "C" fn demangle_callback(
@ -899,7 +894,7 @@ pub(crate) unsafe fn codegen(
if config.emit_asm {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name);
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
let path = cgcx.output_filenames.temp_path_for_cgu(OutputType::Assembly, &module.name);
// We can't use the same module for asm and object code output,
// because that triggers various errors like invalid IR or broken
@ -929,7 +924,7 @@ pub(crate) unsafe fn codegen(
.prof
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name);
let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name);
let dwo_out = cgcx.output_filenames.temp_path_dwo_for_cgu(&module.name);
let dwo_out = match (cgcx.split_debuginfo, cgcx.split_dwarf_kind) {
// Don't change how DWARF is emitted when disabled.
(SplitDebuginfo::Off, _) => None,

View file

@ -910,7 +910,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
&& let Some(f) = output_filenames.split_dwarf_path(
tcx.sess.split_debuginfo(),
tcx.sess.opts.unstable_opts.split_dwarf_kind,
Some(codegen_unit_name),
codegen_unit_name,
) {
// We get a path relative to the working directory from split_dwarf_path
Some(tcx.sess.source_map().path_mapping().to_real_filename(f))

View file

@ -112,8 +112,7 @@ pub fn link_binary(
codegen_results.crate_info.local_crate_name,
);
let crate_name = format!("{}", codegen_results.crate_info.local_crate_name);
let out_filename =
output.file_for_writing(outputs, OutputType::Exe, Some(crate_name.as_str()));
let out_filename = output.file_for_writing(outputs, OutputType::Exe, &crate_name);
match crate_type {
CrateType::Rlib => {
let _timer = sess.timer("link_rlib");

View file

@ -306,14 +306,14 @@ impl TargetMachineFactoryConfig {
cgcx.output_filenames.split_dwarf_path(
cgcx.split_debuginfo,
cgcx.split_dwarf_kind,
Some(module_name),
module_name,
)
} else {
None
};
let output_obj_file =
Some(cgcx.output_filenames.temp_path(OutputType::Object, Some(module_name)));
Some(cgcx.output_filenames.temp_path_for_cgu(OutputType::Object, module_name));
TargetMachineFactoryConfig { split_dwarf_file, output_obj_file }
}
}
@ -582,8 +582,7 @@ fn produce_final_output_artifacts(
if let [module] = &compiled_modules.modules[..] {
// 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`.
let module_name = Some(&module.name[..]);
let path = crate_output.temp_path(output_type, module_name);
let path = crate_output.temp_path_for_cgu(output_type, &module.name);
let output = crate_output.path(output_type);
if !output_type.is_text_output() && output.is_tty() {
sess.dcx()
@ -596,22 +595,15 @@ fn produce_final_output_artifacts(
ensure_removed(sess.dcx(), &path);
}
} else {
let extension = crate_output
.temp_path(output_type, None)
.extension()
.unwrap()
.to_str()
.unwrap()
.to_owned();
if crate_output.outputs.contains_explicit_name(&output_type) {
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
// no good solution for this case, so warn the user.
sess.dcx().emit_warn(errors::IgnoringEmitPath { extension });
sess.dcx()
.emit_warn(errors::IgnoringEmitPath { extension: output_type.extension() });
} else if crate_output.single_output_file.is_some() {
// 3) Multiple codegen units, with `-o some_name`. We have
// no good solution for this case, so warn the user.
sess.dcx().emit_warn(errors::IgnoringOutput { extension });
sess.dcx().emit_warn(errors::IgnoringOutput { extension: output_type.extension() });
} else {
// 4) Multiple codegen units, but no explicit name. We
// just leave the `foo.0.x` files in place.
@ -967,7 +959,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| {
let dwarf_obj_out = cgcx
.output_filenames
.split_dwarf_path(cgcx.split_debuginfo, cgcx.split_dwarf_kind, Some(&module.name))
.split_dwarf_path(cgcx.split_debuginfo, cgcx.split_dwarf_kind, &module.name)
.expect(
"saved dwarf object in work product but `split_dwarf_path` returned `None`",
);
@ -977,7 +969,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
let mut load_from_incr_cache = |perform, output_type: OutputType| {
if perform {
let saved_file = module.source.saved_files.get(output_type.extension())?;
let output_path = cgcx.output_filenames.temp_path(output_type, Some(&module.name));
let output_path = cgcx.output_filenames.temp_path_for_cgu(output_type, &module.name);
load_from_incr_comp_dir(output_path, &saved_file)
} else {
None

View file

@ -640,8 +640,9 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
let metadata_cgu_name =
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string();
tcx.sess.time("write_compressed_metadata", || {
let file_name =
tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
let file_name = tcx
.output_filenames(())
.temp_path_for_cgu(OutputType::Metadata, &metadata_cgu_name);
let data = create_compressed_metadata_file(
tcx.sess,
&metadata,

View file

@ -277,13 +277,13 @@ pub struct BinaryOutputToTty {
#[derive(Diagnostic)]
#[diag(codegen_ssa_ignoring_emit_path)]
pub struct IgnoringEmitPath {
pub extension: String,
pub extension: &'static str,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_ignoring_output)]
pub struct IgnoringOutput {
pub extension: String,
pub extension: &'static str,
}
#[derive(Diagnostic)]

View file

@ -106,12 +106,13 @@ impl<M> ModuleCodegen<M> {
emit_ir: bool,
outputs: &OutputFilenames,
) -> CompiledModule {
let object = emit_obj.then(|| outputs.temp_path(OutputType::Object, Some(&self.name)));
let dwarf_object = emit_dwarf_obj.then(|| outputs.temp_path_dwo(Some(&self.name)));
let bytecode = emit_bc.then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name)));
let assembly = emit_asm.then(|| outputs.temp_path(OutputType::Assembly, Some(&self.name)));
let object = emit_obj.then(|| outputs.temp_path_for_cgu(OutputType::Object, &self.name));
let dwarf_object = emit_dwarf_obj.then(|| outputs.temp_path_dwo_for_cgu(&self.name));
let bytecode = emit_bc.then(|| outputs.temp_path_for_cgu(OutputType::Bitcode, &self.name));
let assembly =
emit_asm.then(|| outputs.temp_path_for_cgu(OutputType::Assembly, &self.name));
let llvm_ir =
emit_ir.then(|| outputs.temp_path(OutputType::LlvmAssembly, Some(&self.name)));
emit_ir.then(|| outputs.temp_path_for_cgu(OutputType::LlvmAssembly, &self.name));
CompiledModule {
name: self.name.clone(),

View file

@ -279,7 +279,7 @@ impl<'tcx> TyCtxt<'tcx> {
p.hash(&mut s);
let hash = s.finish();
*path = Some(path.take().unwrap_or_else(|| {
self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
self.output_filenames(()).temp_path_for_diagnostic(&format!("long-type-{hash}.txt"))
}));
let Ok(mut file) =
File::options().create(true).read(true).append(true).open(&path.as_ref().unwrap())

View file

@ -382,7 +382,7 @@ pub fn shrunk_instance_name<'tcx>(
return (s, None);
}
let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
let path = tcx.output_filenames(()).temp_path_for_diagnostic("long-type.txt");
let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
(shrunk, written_to_path)

View file

@ -1015,11 +1015,11 @@ impl OutFileName {
&self,
outputs: &OutputFilenames,
flavor: OutputType,
codegen_unit_name: Option<&str>,
codegen_unit_name: &str,
) -> PathBuf {
match *self {
OutFileName::Real(ref path) => path.clone(),
OutFileName::Stdout => outputs.temp_path(flavor, codegen_unit_name),
OutFileName::Stdout => outputs.temp_path_for_cgu(flavor, codegen_unit_name),
}
}
@ -1094,40 +1094,39 @@ impl OutputFilenames {
/// Gets the path where a compilation artifact of the given type for the
/// given codegen unit should be placed on disk. If codegen_unit_name is
/// None, a path distinct from those of any codegen unit will be generated.
pub fn temp_path(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf {
pub fn temp_path_for_cgu(&self, flavor: OutputType, codegen_unit_name: &str) -> PathBuf {
let extension = flavor.extension();
self.temp_path_ext(extension, codegen_unit_name)
self.temp_path_ext_for_cgu(extension, codegen_unit_name)
}
/// Like `temp_path`, but specifically for dwarf objects.
pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf {
self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name)
pub fn temp_path_dwo_for_cgu(&self, codegen_unit_name: &str) -> PathBuf {
self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name)
}
/// Like `temp_path`, but also supports things where there is no corresponding
/// OutputType, like noopt-bitcode or lto-bitcode.
pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
let mut extension = String::new();
if let Some(codegen_unit_name) = codegen_unit_name {
extension.push_str(codegen_unit_name);
}
pub fn temp_path_ext_for_cgu(&self, ext: &str, codegen_unit_name: &str) -> PathBuf {
let mut extension = codegen_unit_name.to_string();
// FIXME: This is sketchy that we're not appending `.rcgu` when the ext is empty.
// Append `.rcgu.{ext}`.
if !ext.is_empty() {
if !extension.is_empty() {
extension.push('.');
extension.push_str(RUST_CGU_EXT);
extension.push('.');
}
extension.push('.');
extension.push_str(RUST_CGU_EXT);
extension.push('.');
extension.push_str(ext);
}
let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
self.with_directory_and_extension(temps_directory, &extension)
}
pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
self.with_directory_and_extension(temps_directory, &ext)
}
pub fn with_extension(&self, extension: &str) -> PathBuf {
self.with_directory_and_extension(&self.out_directory, extension)
}
@ -1144,10 +1143,10 @@ impl OutputFilenames {
&self,
split_debuginfo_kind: SplitDebuginfo,
split_dwarf_kind: SplitDwarfKind,
cgu_name: Option<&str>,
cgu_name: &str,
) -> Option<PathBuf> {
let obj_out = self.temp_path(OutputType::Object, cgu_name);
let dwo_out = self.temp_path_dwo(cgu_name);
let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name);
let dwo_out = self.temp_path_dwo_for_cgu(cgu_name);
match (split_debuginfo_kind, split_dwarf_kind) {
(SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
// Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes