mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Add unit-graph JSON output.
This commit is contained in:
parent
94093c270b
commit
aa80a984c0
@ -44,6 +44,7 @@ pub fn cli() -> App {
|
||||
"no-fail-fast",
|
||||
"Run all benchmarks regardless of failure",
|
||||
))
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
The benchmark filtering argument BENCHNAME and all the arguments following the
|
||||
|
@ -41,6 +41,7 @@ pub fn cli() -> App {
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_build_plan()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
All packages in the workspace are built if the `--workspace` flag is supplied. The
|
||||
|
@ -33,6 +33,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
If the `--package` argument is given, then SPEC is a package ID specification
|
||||
|
@ -30,6 +30,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
By default the documentation for the local package and all dependencies is
|
||||
|
@ -24,6 +24,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
If neither `--bin` nor `--example` are given, then if the package only has one
|
||||
|
@ -29,6 +29,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
The specified target for the current package (or package specified by SPEC if
|
||||
|
@ -33,6 +33,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
The specified target for the current package (or package specified by SPEC if
|
||||
|
@ -54,6 +54,7 @@ pub fn cli() -> App {
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg_message_format()
|
||||
.arg_unit_graph()
|
||||
.after_help(
|
||||
"\
|
||||
The test filtering argument TESTNAME and all the arguments following the
|
||||
|
@ -22,6 +22,8 @@ pub struct BuildConfig {
|
||||
pub force_rebuild: bool,
|
||||
/// Output a build plan to stdout instead of actually compiling.
|
||||
pub build_plan: bool,
|
||||
/// Output the unit graph to stdout instead of actually compiling.
|
||||
pub unit_graph: bool,
|
||||
/// An optional override of the rustc process for primary units
|
||||
pub primary_unit_rustc: Option<ProcessBuilder>,
|
||||
pub rustfix_diagnostic_server: RefCell<Option<RustfixDiagnosticServer>>,
|
||||
@ -79,6 +81,7 @@ impl BuildConfig {
|
||||
message_format: MessageFormat::Human,
|
||||
force_rebuild: false,
|
||||
build_plan: false,
|
||||
unit_graph: false,
|
||||
primary_unit_rustc: None,
|
||||
rustfix_diagnostic_server: RefCell::new(None),
|
||||
})
|
||||
|
@ -9,7 +9,7 @@ use std::path::Path;
|
||||
/// compilations, where cross compilations happen at the request of `--target`
|
||||
/// and host compilations happen for things like build scripts and procedural
|
||||
/// macros.
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord, Serialize)]
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord)]
|
||||
pub enum CompileKind {
|
||||
/// Attached to a unit that is compiled for the "host" system or otherwise
|
||||
/// is compiled without a `--target` flag. This is used for procedural
|
||||
@ -41,6 +41,18 @@ impl CompileKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::Serialize for CompileKind {
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
{
|
||||
match self {
|
||||
CompileKind::Host => None::<&str>.serialize(s),
|
||||
CompileKind::Target(t) => Some(t.name).serialize(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstraction for the representation of a compilation target that Cargo has.
|
||||
///
|
||||
/// Compilation targets are one of two things right now:
|
||||
|
@ -16,7 +16,7 @@ use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
|
||||
use super::fingerprint::Fingerprint;
|
||||
use super::job_queue::JobQueue;
|
||||
use super::layout::Layout;
|
||||
use super::unit_dependencies::{UnitDep, UnitGraph};
|
||||
use super::unit_graph::{UnitDep, UnitGraph};
|
||||
use super::{BuildContext, Compilation, CompileKind, CompileMode, Executor, FileFlavor};
|
||||
|
||||
mod compilation_files;
|
||||
|
@ -202,7 +202,7 @@ use serde::de;
|
||||
use serde::ser;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::core::compiler::unit_dependencies::UnitDep;
|
||||
use crate::core::compiler::unit_graph::UnitDep;
|
||||
use crate::core::{InternedString, Package};
|
||||
use crate::util;
|
||||
use crate::util::errors::{CargoResult, CargoResultExt};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::unit_dependencies::UnitGraph;
|
||||
use super::unit_graph::UnitGraph;
|
||||
use crate::core::{PackageId, Resolve};
|
||||
use crate::util::errors::CargoResult;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
@ -15,6 +15,7 @@ pub mod standard_lib;
|
||||
mod timings;
|
||||
mod unit;
|
||||
pub mod unit_dependencies;
|
||||
pub mod unit_graph;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
@ -38,7 +39,7 @@ pub use self::job::Freshness;
|
||||
use self::job::{Job, Work};
|
||||
use self::job_queue::{JobQueue, JobState};
|
||||
use self::output_depinfo::output_depinfo;
|
||||
use self::unit_dependencies::UnitDep;
|
||||
use self::unit_graph::UnitDep;
|
||||
pub use crate::core::compiler::unit::{Unit, UnitInterner};
|
||||
use crate::core::manifest::TargetSourcePath;
|
||||
use crate::core::profiles::{Lto, PanicStrategy, Profile};
|
||||
|
@ -15,6 +15,7 @@
|
||||
//! (for example, with and without tests), so we actually build a dependency
|
||||
//! graph of `Unit`s, which capture these properties.
|
||||
|
||||
use crate::core::compiler::unit_graph::{UnitDep, UnitGraph};
|
||||
use crate::core::compiler::Unit;
|
||||
use crate::core::compiler::{BuildContext, CompileKind, CompileMode};
|
||||
use crate::core::dependency::DepKind;
|
||||
@ -27,25 +28,6 @@ use crate::CargoResult;
|
||||
use log::trace;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
/// The dependency graph of Units.
|
||||
pub type UnitGraph<'a> = HashMap<Unit<'a>, Vec<UnitDep<'a>>>;
|
||||
|
||||
/// A unit dependency.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct UnitDep<'a> {
|
||||
/// The dependency unit.
|
||||
pub unit: Unit<'a>,
|
||||
/// The purpose of this dependency (a dependency for a test, or a build
|
||||
/// script, etc.).
|
||||
pub unit_for: UnitFor,
|
||||
/// The name the parent uses to refer to this dependency.
|
||||
pub extern_crate_name: InternedString,
|
||||
/// Whether or not this is a public dependency.
|
||||
pub public: bool,
|
||||
/// If `true`, the dependency should not be added to Rust's prelude.
|
||||
pub noprelude: bool,
|
||||
}
|
||||
|
||||
/// Collection of stuff used while creating the `UnitGraph`.
|
||||
struct State<'a, 'cfg> {
|
||||
bcx: &'a BuildContext<'a, 'cfg>,
|
||||
|
121
src/cargo/core/compiler/unit_graph.rs
Normal file
121
src/cargo/core/compiler/unit_graph.rs
Normal file
@ -0,0 +1,121 @@
|
||||
use crate::core::compiler::Unit;
|
||||
use crate::core::compiler::{CompileKind, CompileMode};
|
||||
use crate::core::profiles::{Profile, UnitFor};
|
||||
use crate::core::{nightly_features_allowed, InternedString, PackageId, Target};
|
||||
use crate::util::CargoResult;
|
||||
use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
|
||||
/// The dependency graph of Units.
|
||||
pub type UnitGraph<'a> = HashMap<Unit<'a>, Vec<UnitDep<'a>>>;
|
||||
|
||||
/// A unit dependency.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct UnitDep<'a> {
|
||||
/// The dependency unit.
|
||||
pub unit: Unit<'a>,
|
||||
/// The purpose of this dependency (a dependency for a test, or a build
|
||||
/// script, etc.).
|
||||
pub unit_for: UnitFor,
|
||||
/// The name the parent uses to refer to this dependency.
|
||||
pub extern_crate_name: InternedString,
|
||||
/// Whether or not this is a public dependency.
|
||||
pub public: bool,
|
||||
/// If `true`, the dependency should not be added to Rust's prelude.
|
||||
pub noprelude: bool,
|
||||
}
|
||||
|
||||
const VERSION: u32 = 1;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct SerializedUnitGraph<'a> {
|
||||
version: u32,
|
||||
units: Vec<SerializedUnit<'a>>,
|
||||
roots: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct SerializedUnit<'a> {
|
||||
pkg_id: PackageId,
|
||||
target: &'a Target,
|
||||
profile: &'a Profile,
|
||||
platform: CompileKind,
|
||||
mode: CompileMode,
|
||||
features: &'a Vec<InternedString>,
|
||||
#[serde(skip_serializing_if = "std::ops::Not::not")] // hide for unstable build-std
|
||||
is_std: bool,
|
||||
dependencies: Vec<SerializedUnitDep>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct SerializedUnitDep {
|
||||
index: usize,
|
||||
extern_crate_name: InternedString,
|
||||
// This is only set on nightly since it is unstable.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
public: Option<bool>,
|
||||
// This is only set on nightly since it is unstable.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
noprelude: Option<bool>,
|
||||
// Intentionally not including `unit_for` because it is a low-level
|
||||
// internal detail that is mostly used for building the graph.
|
||||
}
|
||||
|
||||
pub fn emit_serialized_unit_graph(
|
||||
root_units: &[Unit<'_>],
|
||||
unit_graph: &UnitGraph<'_>,
|
||||
) -> CargoResult<()> {
|
||||
let is_nightly = nightly_features_allowed();
|
||||
let mut units: Vec<(&Unit<'_>, &Vec<UnitDep<'_>>)> = unit_graph.iter().collect();
|
||||
units.sort_unstable();
|
||||
// Create a map for quick lookup for dependencies.
|
||||
let indices: HashMap<&Unit<'_>, usize> = units
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, val)| (val.0, i))
|
||||
.collect();
|
||||
let roots = root_units.iter().map(|root| indices[root]).collect();
|
||||
let ser_units = units
|
||||
.iter()
|
||||
.map(|(unit, unit_deps)| {
|
||||
let dependencies = unit_deps
|
||||
.iter()
|
||||
.map(|unit_dep| {
|
||||
// https://github.com/rust-lang/rust/issues/64260 when stabilized.
|
||||
let (public, noprelude) = if is_nightly {
|
||||
(Some(unit_dep.public), Some(unit_dep.noprelude))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
SerializedUnitDep {
|
||||
index: indices[&unit_dep.unit],
|
||||
extern_crate_name: unit_dep.extern_crate_name,
|
||||
public,
|
||||
noprelude,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
SerializedUnit {
|
||||
pkg_id: unit.pkg.package_id(),
|
||||
target: unit.target,
|
||||
profile: &unit.profile,
|
||||
platform: unit.kind,
|
||||
mode: unit.mode,
|
||||
features: &unit.features,
|
||||
is_std: unit.is_std,
|
||||
dependencies,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let s = SerializedUnitGraph {
|
||||
version: VERSION,
|
||||
units: ser_units,
|
||||
roots,
|
||||
};
|
||||
|
||||
let stdout = std::io::stdout();
|
||||
let mut lock = stdout.lock();
|
||||
serde_json::to_writer(&mut lock, &s)?;
|
||||
write!(lock, "\n")?;
|
||||
Ok(())
|
||||
}
|
@ -374,6 +374,7 @@ impl Profiles {
|
||||
/// times).
|
||||
pub fn get_profile_run_custom_build(&self, for_unit_profile: &Profile) -> Profile {
|
||||
let mut result = Profile::default();
|
||||
result.name = for_unit_profile.name;
|
||||
result.root = for_unit_profile.root;
|
||||
result.debuginfo = for_unit_profile.debuginfo;
|
||||
result.opt_level = for_unit_profile.opt_level;
|
||||
@ -578,10 +579,11 @@ pub enum ProfileRoot {
|
||||
|
||||
/// Profile settings used to determine which compiler flags to use for a
|
||||
/// target.
|
||||
#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
|
||||
#[derive(Clone, Copy, Eq, PartialOrd, Ord, serde::Serialize)]
|
||||
pub struct Profile {
|
||||
pub name: InternedString,
|
||||
pub opt_level: InternedString,
|
||||
#[serde(skip)] // named profiles are unstable
|
||||
pub root: ProfileRoot,
|
||||
pub lto: Lto,
|
||||
// `None` means use rustc default.
|
||||
@ -743,8 +745,21 @@ pub enum Lto {
|
||||
Named(InternedString),
|
||||
}
|
||||
|
||||
impl serde::ser::Serialize for Lto {
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
{
|
||||
match self {
|
||||
Lto::Bool(b) => b.to_string().serialize(s),
|
||||
Lto::Named(n) => n.serialize(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The `panic` setting.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, PartialOrd, Ord, serde::Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum PanicStrategy {
|
||||
Unwind,
|
||||
Abort,
|
||||
|
@ -30,6 +30,7 @@ use std::sync::Arc;
|
||||
|
||||
use crate::core::compiler::standard_lib;
|
||||
use crate::core::compiler::unit_dependencies::build_unit_dependencies;
|
||||
use crate::core::compiler::unit_graph;
|
||||
use crate::core::compiler::{BuildConfig, BuildContext, Compilation, Context};
|
||||
use crate::core::compiler::{CompileKind, CompileMode, RustcTargetData, Unit};
|
||||
use crate::core::compiler::{DefaultExecutor, Executor, UnitInterner};
|
||||
@ -490,6 +491,11 @@ pub fn compile_ws<'a>(
|
||||
&std_roots,
|
||||
)?;
|
||||
|
||||
if bcx.build_config.unit_graph {
|
||||
unit_graph::emit_serialized_unit_graph(&units, &unit_dependencies)?;
|
||||
return Ok(Compilation::new(&bcx, build_config.requested_kind)?);
|
||||
}
|
||||
|
||||
let ret = {
|
||||
let _p = profile::start("compiling");
|
||||
let cx = Context::new(config, &bcx, unit_dependencies, build_config.requested_kind)?;
|
||||
|
@ -150,6 +150,10 @@ pub trait AppExt: Sized {
|
||||
))
|
||||
}
|
||||
|
||||
fn arg_unit_graph(self) -> Self {
|
||||
self._arg(opt("unit-graph", "Output build graph in JSON (unstable)").hidden(true))
|
||||
}
|
||||
|
||||
fn arg_new_opts(self) -> Self {
|
||||
self._arg(
|
||||
opt(
|
||||
@ -438,11 +442,17 @@ pub trait ArgMatchesExt {
|
||||
build_config.message_format = message_format.unwrap_or(MessageFormat::Human);
|
||||
build_config.requested_profile = self.get_profile_name(config, "dev", profile_checking)?;
|
||||
build_config.build_plan = self._is_present("build-plan");
|
||||
build_config.unit_graph = self._is_present("unit-graph");
|
||||
if build_config.build_plan {
|
||||
config
|
||||
.cli_unstable()
|
||||
.fail_if_stable_opt("--build-plan", 5579)?;
|
||||
};
|
||||
if build_config.unit_graph {
|
||||
config
|
||||
.cli_unstable()
|
||||
.fail_if_stable_opt("--unit-graph", 0)?;
|
||||
}
|
||||
|
||||
let opts = CompileOptions {
|
||||
config,
|
||||
|
@ -552,3 +552,127 @@ The available options are:
|
||||
The `-Z crate-versions` flag will make `cargo doc` include appropriate crate versions for the current crate and all of its dependencies (unless `--no-deps` was provided) in the compiled documentation.
|
||||
|
||||
You can find an example screenshot for the cargo itself in the tracking issue.
|
||||
|
||||
### unit-graph
|
||||
* Tracking Issue: TODO
|
||||
|
||||
The `--unit-graph` flag can be passed to any build command (`build`, `check`,
|
||||
`run`, `test`, `bench`, `doc`, etc.) to emit a JSON object to stdout which
|
||||
represents Cargo's internal unit graph. Nothing is actually built, and the
|
||||
command returns immediately after printing. Each "unit" corresponds to an
|
||||
execution of the compiler. These objects also include which unit each unit
|
||||
depends on.
|
||||
|
||||
```
|
||||
cargo +nightly build --unit-graph -Z unstable-options
|
||||
```
|
||||
|
||||
The following is a description of the JSON structure:
|
||||
|
||||
```javascript
|
||||
{
|
||||
/* Version of the JSON output structure. If any backwards incompatible
|
||||
changes are made, this value will be increased.
|
||||
*/
|
||||
"version": 1,
|
||||
/* Array of all build units. */
|
||||
"units": [
|
||||
{
|
||||
/* An opaque string which indicates the package.
|
||||
Information about the package can be obtained from `cargo metadata`.
|
||||
*/
|
||||
"pkg_id": "my-package 0.1.0 (path+file:///path/to/my-package)",
|
||||
/* The Cargo target. See the `cargo metadata` documentation for more
|
||||
information about these fields.
|
||||
https://doc.rust-lang.org/cargo/commands/cargo-metadata.html
|
||||
*/
|
||||
"target": {
|
||||
"kind": ["lib"],
|
||||
"crate_types": ["lib"],
|
||||
"name": "my-package",
|
||||
"src_path": "/path/to/my-package/src/lib.rs",
|
||||
"edition": "2018",
|
||||
"doctest": true
|
||||
},
|
||||
/* The profile settings for this unit.
|
||||
These values may not match the profile defined in the manifest.
|
||||
Units can use modified profile settings. For example, the "panic"
|
||||
setting can be overridden for tests to force it to "unwind".
|
||||
*/
|
||||
"profile": {
|
||||
/* The profile name these settings are derived from. */
|
||||
"name": "dev",
|
||||
/* The optimization level as a string. */
|
||||
"opt_level": "0",
|
||||
/* The LTO setting as a string. */
|
||||
"lto": "false",
|
||||
/* The codegen units as an integer.
|
||||
`null` if it should use the compiler's default.
|
||||
*/
|
||||
"codegen_units": null,
|
||||
/* The debug information level as an integer.
|
||||
`null` if it should use the compiler's default (0).
|
||||
*/
|
||||
"debuginfo": 2,
|
||||
/* Whether or not debug-assertions are enabled. */
|
||||
"debug_assertions": true,
|
||||
/* Whether or not overflow-checks are enabled. */
|
||||
"overflow_checks": true,
|
||||
/* Whether or not rpath is enabled. */
|
||||
"rpath": false,
|
||||
/* Whether or not incremental is enabled. */
|
||||
"incremental": true,
|
||||
/* The panic strategy, "unwind" or "abort". */
|
||||
"panic": "unwind"
|
||||
},
|
||||
/* Which platform this target is being built for.
|
||||
A value of `null` indicates it is for the host.
|
||||
Otherwise it is a string of the target triple (such as
|
||||
"x86_64-unknown-linux-gnu").
|
||||
*/
|
||||
"platform": null,
|
||||
/* The "mode" for this unit. Valid values:
|
||||
|
||||
* "test" — Build using `rustc` as a test.
|
||||
* "build" — Build using `rustc`.
|
||||
* "check" — Build using `rustc` in "check" mode.
|
||||
* "doc" — Build using `rustdoc`.
|
||||
* "doctest" — Test using `rustdoc`.
|
||||
* "run-custom-build" — Represents the execution of a build script.
|
||||
*/
|
||||
"mode": "build",
|
||||
/* Array of features enabled on this unit as strings. */
|
||||
"features": ["somefeat"],
|
||||
/* Whether or not this is a standard-library unit,
|
||||
part of the unstable build-std feature.
|
||||
If not set, treat as `false`.
|
||||
*/
|
||||
"is_std": false,
|
||||
/* Array of dependencies of this unit. */
|
||||
"dependencies": [
|
||||
{
|
||||
/* Index in the "units" array for the dependency. */
|
||||
"index": 1,
|
||||
/* The name that this dependency will be referred as. */
|
||||
"extern_crate_name": "unicode_xid",
|
||||
/* Whether or not this dependency is "public",
|
||||
part of the unstable public-dependency feature.
|
||||
If not set, the public-dependency feature is not enabled.
|
||||
*/
|
||||
"public": false,
|
||||
/* Whether or not this dependency is injected into the prelude,
|
||||
currently used by the build-std feature.
|
||||
If not set, treat as `false`.
|
||||
*/
|
||||
"noprelude": false
|
||||
}
|
||||
]
|
||||
},
|
||||
// ...
|
||||
],
|
||||
/* Array of indices in the "units" array that are the "roots" of the
|
||||
dependency graph.
|
||||
*/
|
||||
"roots": [0],
|
||||
}
|
||||
```
|
||||
|
@ -24,7 +24,7 @@ fn cargo_build_plan_simple() {
|
||||
"cwd": "[..]/cit/[..]/foo",
|
||||
"deps": [],
|
||||
"env": "{...}",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"links": "{...}",
|
||||
"outputs": "{...}",
|
||||
"package_name": "foo",
|
||||
@ -84,7 +84,7 @@ fn cargo_build_plan_single_dep() {
|
||||
"cwd": "[..]/cit/[..]/foo",
|
||||
"deps": [],
|
||||
"env": "{...}",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"links": "{...}",
|
||||
"outputs": [
|
||||
"[..]/foo/target/debug/deps/libbar-[..].rlib",
|
||||
@ -101,7 +101,7 @@ fn cargo_build_plan_single_dep() {
|
||||
"cwd": "[..]/cit/[..]/foo",
|
||||
"deps": [0],
|
||||
"env": "{...}",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"links": "{...}",
|
||||
"outputs": [
|
||||
"[..]/foo/target/debug/deps/libfoo-[..].rlib",
|
||||
@ -152,7 +152,7 @@ fn cargo_build_plan_build_script() {
|
||||
"cwd": "[..]/cit/[..]/foo",
|
||||
"deps": [],
|
||||
"env": "{...}",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"links": "{...}",
|
||||
"outputs": [
|
||||
"[..]/foo/target/debug/build/[..]/build_script_build-[..]"
|
||||
@ -168,7 +168,7 @@ fn cargo_build_plan_build_script() {
|
||||
"cwd": "[..]/cit/[..]/foo",
|
||||
"deps": [0],
|
||||
"env": "{...}",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"links": "{...}",
|
||||
"outputs": [],
|
||||
"package_name": "foo",
|
||||
@ -182,7 +182,7 @@ fn cargo_build_plan_build_script() {
|
||||
"cwd": "[..]/cit/[..]/foo",
|
||||
"deps": [1],
|
||||
"env": "{...}",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"links": "{...}",
|
||||
"outputs": "{...}",
|
||||
"package_name": "foo",
|
||||
|
@ -103,6 +103,7 @@ mod standard_lib;
|
||||
mod test;
|
||||
mod timings;
|
||||
mod tool_paths;
|
||||
mod unit_graph;
|
||||
mod update;
|
||||
mod vendor;
|
||||
mod verify_project;
|
||||
|
@ -461,7 +461,7 @@ fn metabuild_build_plan() {
|
||||
"package_version": "0.5.0",
|
||||
"target_kind": ["lib"],
|
||||
"compile_mode": "build",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"deps": [],
|
||||
"outputs": [
|
||||
"[..]/target/debug/deps/libmb-[..].rlib",
|
||||
@ -478,7 +478,7 @@ fn metabuild_build_plan() {
|
||||
"package_version": "0.0.1",
|
||||
"target_kind": ["lib"],
|
||||
"compile_mode": "build",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"deps": [],
|
||||
"outputs": [
|
||||
"[..]/target/debug/deps/libmb_other-[..].rlib",
|
||||
@ -495,7 +495,7 @@ fn metabuild_build_plan() {
|
||||
"package_version": "0.0.1",
|
||||
"target_kind": ["custom-build"],
|
||||
"compile_mode": "build",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"deps": [0, 1],
|
||||
"outputs": ["[..]/target/debug/build/foo-[..]/metabuild_foo-[..][EXE]"],
|
||||
"links": "{...}",
|
||||
@ -509,7 +509,7 @@ fn metabuild_build_plan() {
|
||||
"package_version": "0.0.1",
|
||||
"target_kind": ["custom-build"],
|
||||
"compile_mode": "run-custom-build",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"deps": [2],
|
||||
"outputs": [],
|
||||
"links": {},
|
||||
@ -523,7 +523,7 @@ fn metabuild_build_plan() {
|
||||
"package_version": "0.0.1",
|
||||
"target_kind": ["lib"],
|
||||
"compile_mode": "build",
|
||||
"kind": "Host",
|
||||
"kind": null,
|
||||
"deps": [3],
|
||||
"outputs": [
|
||||
"[..]/foo/target/debug/deps/libfoo-[..].rlib",
|
||||
|
211
tests/testsuite/unit_graph.rs
Normal file
211
tests/testsuite/unit_graph.rs
Normal file
@ -0,0 +1,211 @@
|
||||
//! Tests for --unit-graph option.
|
||||
|
||||
use cargo_test_support::project;
|
||||
use cargo_test_support::registry::Package;
|
||||
|
||||
#[cargo_test]
|
||||
fn gated() {
|
||||
let p = project().file("src/lib.rs", "").build();
|
||||
p.cargo("build --unit-graph")
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] the `--unit-graph` flag is unstable[..]
|
||||
See [..]
|
||||
See [..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn simple() {
|
||||
Package::new("a", "1.0.0")
|
||||
.dep("b", "1.0")
|
||||
.feature("feata", &["b/featb"])
|
||||
.publish();
|
||||
Package::new("b", "1.0.0")
|
||||
.dep("c", "1.0")
|
||||
.feature("featb", &["c/featc"])
|
||||
.publish();
|
||||
Package::new("c", "1.0.0").feature("featc", &[]).publish();
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
a = "1.0"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("build --features a/feata --unit-graph -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo()
|
||||
.with_json(
|
||||
r#"{
|
||||
"version": 1,
|
||||
"units": [
|
||||
{
|
||||
"pkg_id": "a 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target": {
|
||||
"kind": [
|
||||
"lib"
|
||||
],
|
||||
"crate_types": [
|
||||
"lib"
|
||||
],
|
||||
"name": "a",
|
||||
"src_path": "[..]/a-1.0.0/src/lib.rs",
|
||||
"edition": "2015",
|
||||
"doctest": true
|
||||
},
|
||||
"profile": {
|
||||
"name": "dev",
|
||||
"opt_level": "0",
|
||||
"lto": "false",
|
||||
"codegen_units": null,
|
||||
"debuginfo": 2,
|
||||
"debug_assertions": true,
|
||||
"overflow_checks": true,
|
||||
"rpath": false,
|
||||
"incremental": false,
|
||||
"panic": "unwind"
|
||||
},
|
||||
"platform": null,
|
||||
"mode": "build",
|
||||
"features": [
|
||||
"feata"
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"index": 1,
|
||||
"extern_crate_name": "b",
|
||||
"public": false,
|
||||
"noprelude": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pkg_id": "b 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target": {
|
||||
"kind": [
|
||||
"lib"
|
||||
],
|
||||
"crate_types": [
|
||||
"lib"
|
||||
],
|
||||
"name": "b",
|
||||
"src_path": "[..]/b-1.0.0/src/lib.rs",
|
||||
"edition": "2015",
|
||||
"doctest": true
|
||||
},
|
||||
"profile": {
|
||||
"name": "dev",
|
||||
"opt_level": "0",
|
||||
"lto": "false",
|
||||
"codegen_units": null,
|
||||
"debuginfo": 2,
|
||||
"debug_assertions": true,
|
||||
"overflow_checks": true,
|
||||
"rpath": false,
|
||||
"incremental": false,
|
||||
"panic": "unwind"
|
||||
},
|
||||
"platform": null,
|
||||
"mode": "build",
|
||||
"features": [
|
||||
"featb"
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"index": 2,
|
||||
"extern_crate_name": "c",
|
||||
"public": false,
|
||||
"noprelude": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pkg_id": "c 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target": {
|
||||
"kind": [
|
||||
"lib"
|
||||
],
|
||||
"crate_types": [
|
||||
"lib"
|
||||
],
|
||||
"name": "c",
|
||||
"src_path": "[..]/c-1.0.0/src/lib.rs",
|
||||
"edition": "2015",
|
||||
"doctest": true
|
||||
},
|
||||
"profile": {
|
||||
"name": "dev",
|
||||
"opt_level": "0",
|
||||
"lto": "false",
|
||||
"codegen_units": null,
|
||||
"debuginfo": 2,
|
||||
"debug_assertions": true,
|
||||
"overflow_checks": true,
|
||||
"rpath": false,
|
||||
"incremental": false,
|
||||
"panic": "unwind"
|
||||
},
|
||||
"platform": null,
|
||||
"mode": "build",
|
||||
"features": [
|
||||
"featc"
|
||||
],
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"pkg_id": "foo 0.1.0 (path+file://[..]/foo)",
|
||||
"target": {
|
||||
"kind": [
|
||||
"lib"
|
||||
],
|
||||
"crate_types": [
|
||||
"lib"
|
||||
],
|
||||
"name": "foo",
|
||||
"src_path": "[..]/foo/src/lib.rs",
|
||||
"edition": "2015",
|
||||
"doctest": true
|
||||
},
|
||||
"profile": {
|
||||
"name": "dev",
|
||||
"opt_level": "0",
|
||||
"lto": "false",
|
||||
"codegen_units": null,
|
||||
"debuginfo": 2,
|
||||
"debug_assertions": true,
|
||||
"overflow_checks": true,
|
||||
"rpath": false,
|
||||
"incremental": false,
|
||||
"panic": "unwind"
|
||||
},
|
||||
"platform": null,
|
||||
"mode": "build",
|
||||
"features": [],
|
||||
"dependencies": [
|
||||
{
|
||||
"index": 0,
|
||||
"extern_crate_name": "a",
|
||||
"public": false,
|
||||
"noprelude": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"roots": [3]
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.run();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user