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

Update to stabilized -C instrument-coverage #130

Merged
merged 1 commit into from
Feb 6, 2022
Merged
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com

## [Unreleased]

- Update to stabilized `-C instrument-coverage`. ([#130](https://github.com/taiki-e/cargo-llvm-cov/pull/130))

Support for `-Z instrument-coverage` in the old nightly will also be kept for compatibility.

**Compatibility Note:** In 0.1, if `-C instrument-coverage` or `-Z instrument-coverage` is not available in the default toolchain, running `cargo llvm-cov` will find and use nightly. This behavior will be changed in 0.2 to always select the default toolchain. If you are likely to be affected by the change in 0.2, cargo-llvm-cov will emit a warning.

## [0.1.16] - 2022-01-21

- Alleviate an issue where "File name or extension is too long" error occurs in Windows. ([#126](https://github.com/taiki-e/cargo-llvm-cov/pull/126), thanks @aganders3)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords = ["cargo", "coverage", "subcommand", "testing"]
categories = ["command-line-utilities", "development-tools", "development-tools::cargo-plugins", "development-tools::testing"]
exclude = ["/.*", "/tools"]
description = """
Cargo subcommand to easily use LLVM source-based code coverage (-Z instrument-coverage).
Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).
"""

[package.metadata.docs.rs]
Expand Down
16 changes: 6 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

Cargo subcommand to easily use LLVM source-based code coverage.

This is a wrapper around rustc [`-Z instrument-coverage`][instrument-coverage] and provides:
This is a wrapper around rustc [`-C instrument-coverage`][instrument-coverage] and provides:

- Generate very precise coverage data. (line coverage and region coverage)
- Support both `cargo test` and `cargo run`.
- Support for proc-macro, including coverage of UI tests.
- Support for doc tests. (this is currently optional, see [#2] for more)
- Support for doc tests. (this is currently optional and requires nightly, see [#2] for more)
- Command-line interface compatible with cargo.

**Table of Contents:**
Expand All @@ -34,7 +34,7 @@ This is a wrapper around rustc [`-Z instrument-coverage`][instrument-coverage] a
```console
$ cargo llvm-cov --help
cargo-llvm-cov
Cargo subcommand to easily use LLVM source-based code coverage (-Z instrument-coverage).
Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).

Use -h for short descriptions and --help for more details.

Expand Down Expand Up @@ -382,11 +382,7 @@ rustup component add llvm-tools-preview --toolchain nightly
cargo install cargo-llvm-cov
```

cargo-llvm-cov relies on unstable compiler flags so it requires a nightly
toolchain to be installed, though does not require nightly to be the default
toolchain or the one with which cargo-llvm-cov itself is executed. If the
default toolchain is one other than nightly, running `cargo llvm-cov` will find
and use nightly.
If `-C instrument-coverage` or `-Z instrument-coverage` is not available in the default toolchain, running `cargo llvm-cov` will find and use nightly. This behavior will be changed in 0.2 to always select the default toolchain.

Currently, installing cargo-llvm-cov requires rustc 1.54+.

Expand All @@ -409,7 +405,7 @@ This makes the installation faster and may avoid the impact of [problems caused
<!-- omit in toc -->
### Via Homebrew

You can install cargo-llvm-cov using [Homebrew tap on macOS and Linux](https://github.com/taiki-e/homebrew-tap/blob/main/Formula/cargo-llvm-cov.rb):
You can install cargo-llvm-cov using [Homebrew tap on macOS and Linux](https://github.com/taiki-e/homebrew-tap/blob/HEAD/Formula/cargo-llvm-cov.rb):

```sh
brew install taiki-e/tap/cargo-llvm-cov
Expand Down Expand Up @@ -446,7 +442,7 @@ See also [the code-coverage-related issues reported in rust-lang/rust](https://g
[cargo-hack]: https://github.com/taiki-e/cargo-hack
[cargo-minimal-versions]: https://github.com/taiki-e/cargo-minimal-versions
[codecov]: https://codecov.io
[instrument-coverage]: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/instrument-coverage.html
[instrument-coverage]: https://doc.rust-lang.org/nightly/rustc/instrument-coverage.html
[rust-lang/rust#79417]: https://github.com/rust-lang/rust/issues/79417
[rust-lang/rust#79649]: https://github.com/rust-lang/rust/issues/79649
[rust-lang/rust#84605]: https://github.com/rust-lang/rust/issues/84605
Expand Down
42 changes: 37 additions & 5 deletions src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,53 @@ pub(crate) struct Workspace {

cargo: PathBuf,
rustc: PathBuf,
pub(crate) nightly: bool,
/// Whether use `cargo +nightly`.
pub(crate) force_nightly: bool,
/// Whether `-C instrument-coverage` is available.
pub(crate) stable_coverage: bool,
}

impl Workspace {
pub(crate) fn new(
options: &ManifestOptions,
target: Option<&str>,
doctests: bool,
show_env: bool,
) -> Result<Self> {
let cargo = env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
let rustc = rustc_path(&cargo);
let (nightly, ref host) = rustc_version(&rustc)?;

let stable_coverage;
let force_nightly;
if (nightly || !doctests)
&& cmd!(&rustc, "-C", "help").read()?.contains("instrument-coverage")
{
stable_coverage = true;
force_nightly = false;
} else if nightly {
stable_coverage = false;
force_nightly = false;
} else if cmd!("rustc", "+nightly", "-C", "help").read()?.contains("instrument-coverage") {
stable_coverage = true;
force_nightly = true;
} else {
stable_coverage = false;
force_nightly = true;
}
if force_nightly && doctests {
warn!(
"cargo-llvm-cov will be changed to always select default toolchain in the future \
major version, but --doctests requires nightly toolchain; \
consider using `cargo +nightly llvm-cov`"
)
}

// Metadata and config
let current_manifest = package_root(&cargo, options.manifest_path.as_deref())?;
let metadata = metadata(&cargo, &current_manifest, options)?;
let config = Config::new(
if nightly { cmd!(&cargo) } else { cmd!("cargo", "+nightly") },
if force_nightly { cmd!("cargo", "+nightly") } else { cmd!(&cargo) },
&metadata.workspace_root,
target,
Some(host),
Expand Down Expand Up @@ -76,12 +105,14 @@ impl Workspace {
profdata_file,
cargo: cargo.into(),
rustc,
nightly,
force_nightly,
stable_coverage,
})
}

pub(crate) fn cargo(&self, verbose: u8) -> ProcessBuilder {
let mut cmd = if self.nightly { cmd!(&self.cargo) } else { cmd!("cargo", "+nightly") };
let mut cmd =
if self.force_nightly { cmd!("cargo", "+nightly") } else { cmd!(&self.cargo) };
cmd.dir(&self.metadata.workspace_root);
// cargo displays env vars only with -vv.
if verbose > 1 {
Expand All @@ -91,7 +122,8 @@ impl Workspace {
}

pub(crate) fn rustc(&self) -> ProcessBuilder {
let mut cmd = if self.nightly { cmd!(&self.rustc) } else { cmd!("rustc", "+nightly") };
let mut cmd =
if self.force_nightly { cmd!("rustc", "+nightly") } else { cmd!(&self.rustc) };
cmd.dir(&self.metadata.workspace_root);
cmd
}
Expand Down
2 changes: 1 addition & 1 deletion src/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
};

pub(crate) fn run(mut options: CleanOptions) -> Result<()> {
let ws = Workspace::new(&options.manifest, None, false)?;
let ws = Workspace::new(&options.manifest, None, false, false)?;
ws.config.merge_to_args(&mut None, &mut options.verbose, &mut options.color);
term::set_coloring(&mut options.color);

Expand Down
2 changes: 1 addition & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use clap::{AppSettings, ArgSettings, Parser};
use crate::{process::ProcessBuilder, term::Coloring};

const ABOUT: &str =
"Cargo subcommand to easily use LLVM source-based code coverage (-Z instrument-coverage).
"Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).

Use -h for short descriptions and --help for more details.";

Expand Down
5 changes: 3 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ impl Config {
// https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#cargo-config
// https://github.com/rust-lang/cargo/issues/9301
cargo
.args(["-Z", "unstable-options", "config", "get", "--format", "json"])
.dir(workspace_root);
.args(&["-Z", "unstable-options", "config", "get", "--format", "json"])
.dir(workspace_root)
.env("RUSTC_BOOTSTRAP", "1");
let mut config = match cargo.read() {
Ok(s) => serde_json::from_str(&s)
.with_context(|| format!("failed to parse output from {}", cargo))?,
Expand Down
4 changes: 2 additions & 2 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl Context {
no_run: bool,
show_env: bool,
) -> Result<Self> {
let ws = Workspace::new(&manifest, build.target.as_deref(), show_env)?;
let ws = Workspace::new(&manifest, build.target.as_deref(), doctests, show_env)?;
ws.config.merge_to_args(&mut build.target, &mut build.verbose, &mut build.color);
term::set_coloring(&mut build.color);
term::verbose::set(build.verbose != 0);
Expand Down Expand Up @@ -95,7 +95,7 @@ impl Context {
if !llvm_cov.exists() || !llvm_profdata.exists() {
bail!(
"failed to find llvm-tools-preview, please install llvm-tools-preview with `rustup component add llvm-tools-preview{}`",
if ws.nightly { "" } else { " --toolchain nightly" }
if ws.force_nightly { " --toolchain nightly" } else { "" }
);
}

Expand Down
41 changes: 25 additions & 16 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![warn(clippy::default_trait_access, clippy::wildcard_imports)]

// Refs:
// - https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/instrument-coverage.html
// - https://doc.rust-lang.org/nightly/rustc/instrument-coverage.html
// - https://llvm.org/docs/CommandGuide/llvm-profdata.html
// - https://llvm.org/docs/CommandGuide/llvm-cov.html

Expand Down Expand Up @@ -196,17 +196,22 @@ fn set_env(cx: &Context, target: &mut impl EnvTarget) {
let llvm_profile_file = cx.ws.target_dir.join(format!("{}-%m.profraw", cx.ws.name));

let rustflags = &mut cx.ws.config.rustflags().unwrap_or_default();
rustflags.push_str(" -Z instrument-coverage");
if cx.ws.stable_coverage {
rustflags.push_str(" -C instrument-coverage");
} else {
// TODO: drop support for `-Z instrument-coverage` in 0.2.
rustflags.push_str(" -Z instrument-coverage");
if cfg!(windows) {
// `-C codegen-units=1` is needed to work around link error on windows
// https://github.com/rust-lang/rust/issues/85461
// https://github.com/microsoft/windows-rs/issues/1006#issuecomment-887789950
// This has been fixed in https://github.com/rust-lang/rust/pull/91470,
// but old nightly compilers still need this.
rustflags.push_str(" -C codegen-units=1");
}
}
// --remap-path-prefix is needed because sometimes macros are displayed with absolute path
rustflags.push_str(&format!(" --remap-path-prefix {}/=", cx.ws.metadata.workspace_root));
if cfg!(windows) {
// `-C codegen-units=1` is needed to work around link error on windows
// https://github.com/rust-lang/rust/issues/85461
// https://github.com/microsoft/windows-rs/issues/1006#issuecomment-887789950
// This has been fixed in https://github.com/rust-lang/rust/pull/91470,
// but old nightly compilers still need this.
rustflags.push_str(" -C codegen-units=1");
}
if !cx.cov.no_cfg_coverage {
rustflags.push_str(" --cfg coverage");
}
Expand All @@ -217,14 +222,18 @@ fn set_env(cx: &Context, target: &mut impl EnvTarget) {
rustflags.push_str(" --cfg trybuild_no_target");
}

// https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/instrument-coverage.html#including-doc-tests
// https://doc.rust-lang.org/nightly/rustc/instrument-coverage.html#including-doc-tests
let rustdocflags = &mut cx.ws.config.rustdocflags();
if cx.doctests {
let rustdocflags = rustdocflags.get_or_insert_with(String::new);
rustdocflags.push_str(&format!(
" -Z instrument-coverage -Z unstable-options --persist-doctests {}",
cx.ws.doctests_dir
));
if cx.ws.stable_coverage {
rustdocflags.push_str(" -C instrument-coverage");
} else {
// TODO: drop support for `-Z instrument-coverage` in 0.2.
rustdocflags.push_str(" -Z instrument-coverage");
}
rustdocflags
.push_str(&format!(" -Z unstable-options --persist-doctests {}", cx.ws.doctests_dir));
if cfg!(windows) {
rustdocflags.push_str(" -C codegen-units=1");
}
Expand Down Expand Up @@ -360,7 +369,7 @@ fn object_files(cx: &Context) -> Result<Vec<OsString>> {
// To support testing binary crate like tests that use the CARGO_BIN_EXE
// environment variable, pass all compiled executables.
// This is not the ideal way, but the way unstable book says it is cannot support them.
// https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/instrument-coverage.html#tips-for-listing-the-binaries-automatically
// https://doc.rust-lang.org/nightly/rustc/instrument-coverage.html#tips-for-listing-the-binaries-automatically
let mut target_dir = cx.ws.target_dir.clone();
// https://doc.rust-lang.org/nightly/cargo/guide/build-cache.html
if let Some(target) = &cx.build.target {
Expand Down
2 changes: 1 addition & 1 deletion tests/long-help.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cargo-llvm-cov
Cargo subcommand to easily use LLVM source-based code coverage (-Z instrument-coverage).
Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).

Use -h for short descriptions and --help for more details.

Expand Down
2 changes: 1 addition & 1 deletion tests/short-help.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cargo-llvm-cov
Cargo subcommand to easily use LLVM source-based code coverage (-Z instrument-coverage).
Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).

Use -h for short descriptions and --help for more details.

Expand Down