Auto merge of #115735 - bjorn3:better_list_crate_metadata, r=wesleywiser
Extend rustc -Zls This makes it show a lot more things and thus a lot more useful.
This commit is contained in:
commit
7e0261e7ea
9 changed files with 204 additions and 29 deletions
|
@ -700,12 +700,14 @@ pub fn list_metadata(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
metadata_loader: &dyn MetadataLoader,
|
metadata_loader: &dyn MetadataLoader,
|
||||||
) -> Compilation {
|
) -> Compilation {
|
||||||
if sess.opts.unstable_opts.ls {
|
let ls_kinds = &sess.opts.unstable_opts.ls;
|
||||||
|
if !ls_kinds.is_empty() {
|
||||||
match sess.io.input {
|
match sess.io.input {
|
||||||
Input::File(ref ifile) => {
|
Input::File(ref ifile) => {
|
||||||
let path = &(*ifile);
|
let path = &(*ifile);
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v).unwrap();
|
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v, ls_kinds)
|
||||||
|
.unwrap();
|
||||||
safe_println!("{}", String::from_utf8(v).unwrap());
|
safe_println!("{}", String::from_utf8(v).unwrap());
|
||||||
}
|
}
|
||||||
Input::Str { .. } => {
|
Input::Str { .. } => {
|
||||||
|
|
|
@ -704,7 +704,7 @@ fn test_unstable_options_tracking_hash() {
|
||||||
untracked!(keep_hygiene_data, true);
|
untracked!(keep_hygiene_data, true);
|
||||||
untracked!(link_native_libraries, false);
|
untracked!(link_native_libraries, false);
|
||||||
untracked!(llvm_time_trace, true);
|
untracked!(llvm_time_trace, true);
|
||||||
untracked!(ls, true);
|
untracked!(ls, vec!["all".to_owned()]);
|
||||||
untracked!(macro_backtrace, true);
|
untracked!(macro_backtrace, true);
|
||||||
untracked!(meta_stats, true);
|
untracked!(meta_stats, true);
|
||||||
untracked!(mir_include_spans, true);
|
untracked!(mir_include_spans, true);
|
||||||
|
|
|
@ -903,10 +903,11 @@ pub fn list_file_metadata(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
metadata_loader: &dyn MetadataLoader,
|
metadata_loader: &dyn MetadataLoader,
|
||||||
out: &mut dyn Write,
|
out: &mut dyn Write,
|
||||||
|
ls_kinds: &[String],
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
let flavor = get_flavor_from_path(path);
|
let flavor = get_flavor_from_path(path);
|
||||||
match get_metadata_section(target, flavor, path, metadata_loader) {
|
match get_metadata_section(target, flavor, path, metadata_loader) {
|
||||||
Ok(metadata) => metadata.list_crate_metadata(out),
|
Ok(metadata) => metadata.list_crate_metadata(out, ls_kinds),
|
||||||
Err(msg) => write!(out, "{msg}\n"),
|
Err(msg) => write!(out, "{msg}\n"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,25 +725,196 @@ impl MetadataBlob {
|
||||||
LazyValue::<CrateRoot>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
|
LazyValue::<CrateRoot>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
|
pub(crate) fn list_crate_metadata(
|
||||||
|
&self,
|
||||||
|
out: &mut dyn io::Write,
|
||||||
|
ls_kinds: &[String],
|
||||||
|
) -> io::Result<()> {
|
||||||
let root = self.get_root();
|
let root = self.get_root();
|
||||||
|
|
||||||
|
let all_ls_kinds = vec![
|
||||||
|
"root".to_owned(),
|
||||||
|
"lang_items".to_owned(),
|
||||||
|
"features".to_owned(),
|
||||||
|
"items".to_owned(),
|
||||||
|
];
|
||||||
|
let ls_kinds = if ls_kinds.contains(&"all".to_owned()) { &all_ls_kinds } else { ls_kinds };
|
||||||
|
|
||||||
|
for kind in ls_kinds {
|
||||||
|
match &**kind {
|
||||||
|
"root" => {
|
||||||
writeln!(out, "Crate info:")?;
|
writeln!(out, "Crate info:")?;
|
||||||
writeln!(out, "name {}{}", root.name(), root.extra_filename)?;
|
writeln!(out, "name {}{}", root.name(), root.extra_filename)?;
|
||||||
writeln!(out, "hash {} stable_crate_id {:?}", root.hash(), root.stable_crate_id)?;
|
writeln!(
|
||||||
|
out,
|
||||||
|
"hash {} stable_crate_id {:?}",
|
||||||
|
root.hash(),
|
||||||
|
root.stable_crate_id
|
||||||
|
)?;
|
||||||
writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
|
writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
|
||||||
writeln!(out, "=External Dependencies=")?;
|
writeln!(out, "triple {}", root.header.triple.triple())?;
|
||||||
|
writeln!(out, "edition {}", root.edition)?;
|
||||||
|
writeln!(out, "symbol_mangling_version {:?}", root.symbol_mangling_version)?;
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
"required_panic_strategy {:?} panic_in_drop_strategy {:?}",
|
||||||
|
root.required_panic_strategy, root.panic_in_drop_strategy
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
"has_global_allocator {} has_alloc_error_handler {} has_panic_handler {} has_default_lib_allocator {}",
|
||||||
|
root.has_global_allocator,
|
||||||
|
root.has_alloc_error_handler,
|
||||||
|
root.has_panic_handler,
|
||||||
|
root.has_default_lib_allocator
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
"compiler_builtins {} needs_allocator {} needs_panic_runtime {} no_builtins {} panic_runtime {} profiler_runtime {}",
|
||||||
|
root.compiler_builtins,
|
||||||
|
root.needs_allocator,
|
||||||
|
root.needs_panic_runtime,
|
||||||
|
root.no_builtins,
|
||||||
|
root.panic_runtime,
|
||||||
|
root.profiler_runtime
|
||||||
|
)?;
|
||||||
|
|
||||||
|
writeln!(out, "=External Dependencies=")?;
|
||||||
|
let dylib_dependency_formats =
|
||||||
|
root.dylib_dependency_formats.decode(self).collect::<Vec<_>>();
|
||||||
for (i, dep) in root.crate_deps.decode(self).enumerate() {
|
for (i, dep) in root.crate_deps.decode(self).enumerate() {
|
||||||
let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } = dep;
|
let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } =
|
||||||
|
dep;
|
||||||
let number = i + 1;
|
let number = i + 1;
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
"{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}",
|
"{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}{linkage}",
|
||||||
privacy = if is_private { "private" } else { "public" }
|
privacy = if is_private { "private" } else { "public" },
|
||||||
|
linkage = if dylib_dependency_formats.is_empty() {
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
format!(" linkage {:?}", dylib_dependency_formats[i])
|
||||||
|
}
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
write!(out, "\n")?;
|
write!(out, "\n")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
"lang_items" => {
|
||||||
|
writeln!(out, "=Lang items=")?;
|
||||||
|
for (id, lang_item) in root.lang_items.decode(self) {
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
"{} = crate{}",
|
||||||
|
lang_item.name(),
|
||||||
|
DefPath::make(LOCAL_CRATE, id, |parent| root
|
||||||
|
.tables
|
||||||
|
.def_keys
|
||||||
|
.get(self, parent)
|
||||||
|
.unwrap()
|
||||||
|
.decode(self))
|
||||||
|
.to_string_no_crate_verbose()
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
for lang_item in root.lang_items_missing.decode(self) {
|
||||||
|
writeln!(out, "{} = <missing>", lang_item.name())?;
|
||||||
|
}
|
||||||
|
write!(out, "\n")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
"features" => {
|
||||||
|
writeln!(out, "=Lib features=")?;
|
||||||
|
for (feature, since) in root.lib_features.decode(self) {
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
"{}{}",
|
||||||
|
feature,
|
||||||
|
if let Some(since) = since {
|
||||||
|
format!(" since {since}")
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
write!(out, "\n")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
"items" => {
|
||||||
|
writeln!(out, "=Items=")?;
|
||||||
|
|
||||||
|
fn print_item(
|
||||||
|
blob: &MetadataBlob,
|
||||||
|
out: &mut dyn io::Write,
|
||||||
|
item: DefIndex,
|
||||||
|
indent: usize,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
let root = blob.get_root();
|
||||||
|
|
||||||
|
let def_kind = root.tables.opt_def_kind.get(blob, item).unwrap();
|
||||||
|
let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob);
|
||||||
|
let def_name = if item == CRATE_DEF_INDEX {
|
||||||
|
rustc_span::symbol::kw::Crate
|
||||||
|
} else {
|
||||||
|
def_key
|
||||||
|
.disambiguated_data
|
||||||
|
.data
|
||||||
|
.get_opt_name()
|
||||||
|
.unwrap_or_else(|| Symbol::intern("???"))
|
||||||
|
};
|
||||||
|
let visibility =
|
||||||
|
root.tables.visibility.get(blob, item).unwrap().decode(blob).map_id(
|
||||||
|
|index| {
|
||||||
|
format!(
|
||||||
|
"crate{}",
|
||||||
|
DefPath::make(LOCAL_CRATE, index, |parent| root
|
||||||
|
.tables
|
||||||
|
.def_keys
|
||||||
|
.get(blob, parent)
|
||||||
|
.unwrap()
|
||||||
|
.decode(blob))
|
||||||
|
.to_string_no_crate_verbose()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
write!(
|
||||||
|
out,
|
||||||
|
"{nil: <indent$}{:?} {:?} {} {{",
|
||||||
|
visibility,
|
||||||
|
def_kind,
|
||||||
|
def_name,
|
||||||
|
nil = "",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if let Some(children) =
|
||||||
|
root.tables.module_children_non_reexports.get(blob, item)
|
||||||
|
{
|
||||||
|
write!(out, "\n")?;
|
||||||
|
for child in children.decode(blob) {
|
||||||
|
print_item(blob, out, child, indent + 4)?;
|
||||||
|
}
|
||||||
|
writeln!(out, "{nil: <indent$}}}", nil = "")?;
|
||||||
|
} else {
|
||||||
|
writeln!(out, "}}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
print_item(self, out, CRATE_DEF_INDEX, 0)?;
|
||||||
|
|
||||||
|
write!(out, "\n")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
"unknown -Zls kind. allowed values are: all, root, lang_items, features, items"
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1086,7 +1086,7 @@ impl Options {
|
||||||
/// Returns `true` if there will be an output file generated.
|
/// Returns `true` if there will be an output file generated.
|
||||||
pub fn will_create_output_file(&self) -> bool {
|
pub fn will_create_output_file(&self) -> bool {
|
||||||
!self.unstable_opts.parse_only && // The file is just being parsed
|
!self.unstable_opts.parse_only && // The file is just being parsed
|
||||||
!self.unstable_opts.ls // The file is just being queried
|
self.unstable_opts.ls.is_empty() // The file is just being queried
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1594,8 +1594,9 @@ options! {
|
||||||
"what location details should be tracked when using caller_location, either \
|
"what location details should be tracked when using caller_location, either \
|
||||||
`none`, or a comma separated list of location details, for which \
|
`none`, or a comma separated list of location details, for which \
|
||||||
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
|
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
|
||||||
ls: bool = (false, parse_bool, [UNTRACKED],
|
ls: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
|
||||||
"list the symbols defined by a library crate (default: no)"),
|
"decode and print various parts of the crate metadata for a library crate \
|
||||||
|
(space separated)"),
|
||||||
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"show macro backtraces (default: no)"),
|
"show macro backtraces (default: no)"),
|
||||||
maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED],
|
maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED],
|
||||||
|
|
|
@ -5,10 +5,10 @@ OUT=$(TMPDIR)/emit
|
||||||
# --emit KIND=PATH should not affect crate hash vs --emit KIND
|
# --emit KIND=PATH should not affect crate hash vs --emit KIND
|
||||||
all: $(OUT)/a/libfoo.rlib $(OUT)/b/libfoo.rlib $(OUT)/c/libfoo.rlib \
|
all: $(OUT)/a/libfoo.rlib $(OUT)/b/libfoo.rlib $(OUT)/c/libfoo.rlib \
|
||||||
$(TMPDIR)/libfoo.rlib
|
$(TMPDIR)/libfoo.rlib
|
||||||
$(RUSTC) -Zls $(TMPDIR)/libfoo.rlib > $(TMPDIR)/base.txt
|
$(RUSTC) -Zls=root $(TMPDIR)/libfoo.rlib > $(TMPDIR)/base.txt
|
||||||
$(RUSTC) -Zls $(OUT)/a/libfoo.rlib > $(TMPDIR)/a.txt
|
$(RUSTC) -Zls=root $(OUT)/a/libfoo.rlib > $(TMPDIR)/a.txt
|
||||||
$(RUSTC) -Zls $(OUT)/b/libfoo.rlib > $(TMPDIR)/b.txt
|
$(RUSTC) -Zls=root $(OUT)/b/libfoo.rlib > $(TMPDIR)/b.txt
|
||||||
$(RUSTC) -Zls $(OUT)/c/libfoo.rlib > $(TMPDIR)/c.txt
|
$(RUSTC) -Zls=root $(OUT)/c/libfoo.rlib > $(TMPDIR)/c.txt
|
||||||
|
|
||||||
diff $(TMPDIR)/base.txt $(TMPDIR)/a.txt
|
diff $(TMPDIR)/base.txt $(TMPDIR)/a.txt
|
||||||
diff $(TMPDIR)/base.txt $(TMPDIR)/b.txt
|
diff $(TMPDIR)/base.txt $(TMPDIR)/b.txt
|
||||||
|
|
|
@ -3,6 +3,6 @@ include ../tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(RUSTC) foo.rs
|
$(RUSTC) foo.rs
|
||||||
$(RUSTC) -Z ls $(TMPDIR)/foo
|
$(RUSTC) -Z ls=root $(TMPDIR)/foo
|
||||||
touch $(TMPDIR)/bar
|
touch $(TMPDIR)/bar
|
||||||
$(RUSTC) -Z ls $(TMPDIR)/bar
|
$(RUSTC) -Z ls=root $(TMPDIR)/bar
|
||||||
|
|
|
@ -8,7 +8,7 @@ all:
|
||||||
cp bar.rs $(TMPDIR)/bar.rlib
|
cp bar.rs $(TMPDIR)/bar.rlib
|
||||||
$(RUSTC) $(TMPDIR)/bar.rlib -o $(TMPDIR)/bar.rlib 2>&1 \
|
$(RUSTC) $(TMPDIR)/bar.rlib -o $(TMPDIR)/bar.rlib 2>&1 \
|
||||||
| $(CGREP) -e "the input file \".*bar.rlib\" would be overwritten by the generated executable"
|
| $(CGREP) -e "the input file \".*bar.rlib\" would be overwritten by the generated executable"
|
||||||
$(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls $(TMPDIR)/foo 2>&1
|
$(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls=root $(TMPDIR)/foo 2>&1
|
||||||
cp foo.rs $(TMPDIR)/foo.rs
|
cp foo.rs $(TMPDIR)/foo.rs
|
||||||
$(RUSTC) $(TMPDIR)/foo.rs -o $(TMPDIR)/foo.rs 2>&1 \
|
$(RUSTC) $(TMPDIR)/foo.rs -o $(TMPDIR)/foo.rs 2>&1 \
|
||||||
| $(CGREP) -e "the input file \".*foo.rs\" would be overwritten by the generated executable"
|
| $(CGREP) -e "the input file \".*foo.rs\" would be overwritten by the generated executable"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue