cargo_samply/lib.rs
1//! # cargo-samply
2//!
3//! Profile Rust code with [`samply`](https://github.com/mstange/samply), without
4//! remembering the build/run ceremony.
5//!
6//! This crate provides both:
7//! - a Cargo subcommand (`cargo samply` / `cargo-samply`)
8//! - a small Rust API surface (mainly for CLI parsing / helpers)
9//!
10//! > Note: This project is **not affiliated** with upstream `samply`.
11//!
12//! ## Installation
13//!
14//! ```console
15//! $ cargo install cargo-samply
16//! $ cargo install samply
17//! ```
18//!
19//! ## Usage
20//!
21//! Profile the default binary target:
22//!
23//! ```console
24//! $ cargo samply
25//! ```
26//!
27//! Select a specific target:
28//!
29//! ```console
30//! $ cargo samply --bin my-binary
31//! $ cargo samply --example my-example
32//! $ cargo samply --bench throughput -- --sample-size 10
33//! $ cargo samply --test integration_suite
34//! ```
35//!
36//! Bench targets must be referenced using their exact Cargo target names (no
37//! suffix rewriting / aliasing).
38//!
39//! ### Passing arguments
40//!
41//! Arguments after `--` are passed to the program being profiled:
42//!
43//! ```console
44//! $ cargo samply --bin my-binary -- --input file.txt --verbose
45//! ```
46//!
47//! You can also pass arguments directly to `samply` itself:
48//!
49//! ```console
50//! $ cargo samply --samply-args "--rate 2000" --bin my-binary
51//! ```
52//!
53//! ### Workspaces
54//!
55//! In a workspace, you can pick the package to profile:
56//!
57//! ```console
58//! $ cargo samply -p my-package --bin my-binary
59//! ```
60//!
61//! ### Bench flag injection
62//!
63//! By default, when profiling a benchmark via `--bench <name>`, `cargo-samply`
64//! will run the final benchmark binary with `--bench` (mirroring `cargo bench`).
65//! You can customize this for non-Criterion harnesses:
66//!
67//! ```console
68//! $ cargo samply --bench throughput --bench-flag=--my-custom-flag
69//! $ cargo samply --bench throughput --bench-flag=none
70//! ```
71//!
72//! ### Dry-run and target listing
73//!
74//! `--dry-run` prints the `cargo build` and final execution command without
75//! running them. The output is intended to be copy-pasteable in a shell.
76//!
77//! ```console
78//! $ cargo samply --dry-run --bin my-binary -- --arg value
79//! ```
80//!
81//! `--list-targets` prints discovered targets and exits:
82//!
83//! ```console
84//! $ cargo samply --list-targets
85//! ```
86//!
87//! ## Environment variables
88//!
89//! - `CARGO_SAMPLY_SAMPLY_PATH`: override the path to the `samply` binary.
90//! - `CARGO_SAMPLY_NO_PROFILE_INJECT`: disable automatic modification of
91//! `Cargo.toml` (equivalent to `--no-profile-inject`).
92//! - `CARGO_SAMPLY_NO_SYSROOT_INJECTION`: disable automatic injection of Rust
93//! sysroot library paths into the runtime loader path.
94//! (Linux: `LD_LIBRARY_PATH`, macOS: `DYLD_LIBRARY_PATH`, Windows: `PATH`).
95//!
96//! ## How it works (high level)
97//!
98//! 1. Locates the Cargo project (`cargo locate-project`).
99//! 2. Ensures a `[profile.samply]` exists (unless disabled).
100//! 3. Builds the selected target with `cargo build`.
101//! 4. Resolves the produced artifact path from Cargo metadata/messages.
102//! 5. Optionally configures runtime library paths (including Rust sysroot) so
103//! binaries with dynamic Rust dependencies run reliably.
104//! 6. Runs either the binary directly (`--no-samply`) or under
105//! `samply record -- <artifact> ...`.
106//!
107//! ## The `samply` Cargo profile
108//!
109//! When profile injection is enabled, `cargo-samply` ensures your manifest
110//! contains:
111//!
112//! ```toml
113//! [profile.samply]
114//! inherits = "release"
115//! debug = true
116//! ```
117
118pub mod cli;
119pub mod error;
120pub mod util;
121
122pub use cli::{CargoCli, Config};
123pub use error::{Error, Result};