Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NatVis support in Cargo #9027

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,15 @@ fn build_base_args(
.env("RUSTC_BOOTSTRAP", "1");
}

// If the target is using the MSVC toolchain, then pass any NatVis files to it.
let target_config = bcx.target_data.target_config(unit.kind);
let is_msvc = target_config.triple.ends_with("-msvc");
if is_msvc {
for natvis_file in unit.pkg.manifest().natvis_files().iter() {
cmd.arg(format!("-Clink-arg=/natvis:{}", natvis_file));
}
}

// Add `CARGO_BIN_` environment variables for building tests.
if unit.target.is_test() || unit.target.is_bench() {
for bin_target in unit
Expand Down
7 changes: 7 additions & 0 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub struct Manifest {
default_run: Option<String>,
metabuild: Option<Vec<String>>,
resolve_behavior: Option<ResolveBehavior>,
natvis_files: Vec<String>,
}

/// When parsing `Cargo.toml`, some warnings should silenced
Expand Down Expand Up @@ -384,6 +385,7 @@ impl Manifest {
original: Rc<TomlManifest>,
metabuild: Option<Vec<String>>,
resolve_behavior: Option<ResolveBehavior>,
natvis_files: Vec<String>,
) -> Manifest {
Manifest {
summary,
Expand All @@ -407,6 +409,7 @@ impl Manifest {
publish_lockfile,
metabuild,
resolve_behavior,
natvis_files,
}
}

Expand Down Expand Up @@ -539,6 +542,10 @@ impl Manifest {
.join(".metabuild")
.join(format!("metabuild-{}-{}.rs", self.name(), hash))
}

pub fn natvis_files(&self) -> &[String] {
&self.natvis_files
}
}

impl VirtualManifest {
Expand Down
7 changes: 7 additions & 0 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub struct SerializedPackage {
links: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
metabuild: Option<Vec<String>>,
#[serde(skip_serializing_if = "Vec::is_empty")]
natvis_files: Vec<String>,
}

impl Package {
Expand Down Expand Up @@ -259,8 +261,13 @@ impl Package {
links: self.manifest().links().map(|s| s.to_owned()),
metabuild: self.manifest().metabuild().cloned(),
publish: self.publish().as_ref().cloned(),
natvis_files: self.natvis_files().to_vec(),
}
}

pub fn natvis_files(&self) -> &[String] {
self.inner.manifest.natvis_files()
}
}

impl fmt::Display for Package {
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/util/config/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct TargetConfig {
/// running its build script and instead use the given output from the
/// config file.
pub links_overrides: BTreeMap<String, BuildOutput>,
pub triple: String,
}

/// Loads all of the `target.'cfg()'` tables.
Expand Down Expand Up @@ -85,6 +86,7 @@ pub(super) fn load_target_triple(config: &Config, triple: &str) -> CargoResult<T
rustflags,
linker,
links_overrides,
triple: triple.to_string(),
})
}

Expand Down
68 changes: 67 additions & 1 deletion src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,8 @@ pub struct TomlProject {
repository: Option<String>,
metadata: Option<toml::Value>,
resolver: Option<String>,
#[serde(rename = "natvis-files")]
natvis_files: Option<Vec<String>>,
}

#[derive(Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -867,7 +869,7 @@ struct Context<'a, 'b> {
}

impl TomlManifest {
/// Prepares the manfiest for publishing.
/// Prepares the manifest for publishing.
// - Path and git components of dependency specifications are removed.
// - License path is updated to point within the package.
pub fn prepare_for_publish(
Expand Down Expand Up @@ -1297,6 +1299,15 @@ impl TomlManifest {
}
}

// Handle NatVis files. If the TomlManifest specifies a set of NatVis files, then we use
// exactly that set and we do not inspect the filesystem. (We do require that the paths
// specified in the manifest be relative paths.) If the manifest does not specify any
// NatVis files, then we look for `natvis/*.natvis` files.
let natvis_files = resolve_natvis_files(
project.natvis_files.as_ref().map(|s| s.as_slice()),
package_root,
)?;

let custom_metadata = project.metadata.clone();
let mut manifest = Manifest::new(
summary,
Expand All @@ -1319,6 +1330,7 @@ impl TomlManifest {
Rc::clone(me),
project.metabuild.clone().map(|sov| sov.0),
resolve_behavior,
natvis_files,
);
if project.license_file.is_some() && project.license.is_some() {
manifest.warnings_mut().add_warning(
Expand Down Expand Up @@ -1892,3 +1904,57 @@ impl fmt::Debug for PathValue {
self.0.fmt(f)
}
}

fn resolve_natvis_files(
toml_natvis_files: Option<&[String]>,
package_root: &Path,
) -> CargoResult<Vec<String>> {
if let Some(toml_natvis_files) = toml_natvis_files {
let mut natvis_files = Vec::with_capacity(toml_natvis_files.len());
for toml_natvis_file in toml_natvis_files.iter() {
let natvis_file_path = Path::new(toml_natvis_file);
if !natvis_file_path.is_relative() {
bail!(
"`natvis-files` contains absolute path `{}`; \
all paths in `natvis-files` are required to be relative paths.",
toml_natvis_file
);
}
natvis_files.push(
package_root
.join(natvis_file_path)
.to_str()
.unwrap()
.to_string(),
);
}
Ok(natvis_files)
} else {
// The manifest file did not specify any natvis files.
// By convention, we look for `natvis\*.natvis` files.
if let Ok(nv) = find_natvis_files(package_root) {
Ok(nv)
} else {
Ok(Vec::new())
}
}
}

fn find_natvis_files(package_root: &Path) -> std::io::Result<Vec<String>> {
use std::ffi::OsStr;

let mut natvis_files = Vec::new();
let natvis_dir = package_root.join("natvis");
for entry in std::fs::read_dir(&natvis_dir)? {
let entry = entry?;
let filename = PathBuf::from(entry.file_name().to_str().unwrap());
if filename.extension() == Some(OsStr::new("natvis")) {
if let Ok(md) = entry.metadata() {
if md.is_file() {
natvis_files.push(entry.path().to_str().unwrap().to_string());
}
}
}
}
Ok(natvis_files)
}
1 change: 1 addition & 0 deletions tests/testsuite/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ mod metabuild;
mod metadata;
mod minimal_versions;
mod multitarget;
mod natvis;
mod net_config;
mod new;
mod offline;
Expand Down
Loading