External tools
One of the goals of Cargo is simple integration with third-party tools, like IDEs and other build systems. To make integration easier, Cargo has several facilities:
-
a
cargo metadatacommand, which outputs package structure and dependencies information in JSON, -
a
--message-formatflag, which outputs information about a particular build, and -
support for custom subcommands.
Information about package structure
You can use cargo metadata command to get information about package
structure and dependencies. See the cargo metadata documentation
for details on the format of the output.
The format is stable and versioned. When calling cargo metadata, you should
pass --format-version flag explicitly to avoid forward incompatibility
hazard.
If you are using Rust, the cargo_metadata crate can be used to parse the output.
JSON messages
When passing --message-format=json, Cargo will output the following
information during the build:
-
compiler errors and warnings,
-
produced artifacts,
-
results of the build scripts (for example, native dependencies).
The output goes to stdout in the JSON object per line format. The reason field
distinguishes different kinds of messages.
The package_id field is a unique identifier for referring to the package, and
as the --package argument to many commands. The syntax grammar can be found in
chapter Package ID Specifications.
Note:
--message-format=jsononly controls Cargo and Rustc's output. This cannot control the output of other tools, e.g.cargo run --message-format=json, or arbitrary output from procedural macros. A possible workaround in these situations is to only interpret a line as JSON if it starts with{.
The --message-format option can also take additional formatting values which
alter the way the JSON messages are computed and rendered. See the description
of the --message-format option in the build command documentation for more
details.
If you are using Rust, the cargo_metadata crate can be used to parse these messages.
MSRV: 1.77 is required for
package_idto be a Package ID Specification. Before that, it was opaque.
Compiler messages
The "compiler-message" message includes output from the compiler, such as
warnings and errors. See the rustc JSON chapter for
details on rustc's message format, which is embedded in the following
structure:
Artifact messages
For every compilation step, a "compiler-artifact" message is emitted with the following structure:
Build script output
The "build-script-executed" message includes the parsed output of a build script. Note that this is emitted even if the build script is not run; it will display the previously cached value. More details about build script output may be found in the chapter on build scripts.
Build finished
The "build-finished" message is emitted at the end of the build.
This message can be helpful for tools to know when to stop reading JSON
messages. Commands such as cargo test or cargo run can produce additional
output after the build has finished. This message lets a tool know that Cargo
will not produce additional JSON messages, but there may be additional output
that may be generated afterwards (such as the output generated by the program
executed by cargo run).
Note: There is experimental nightly-only support for JSON output for tests, so additional test-specific JSON messages may begin arriving after the "build-finished" message if that is enabled.
Custom subcommands
Cargo is designed to be extensible with new subcommands without having to modify
Cargo itself. This is achieved by translating a cargo invocation of the form
cargo (?<command>[^ ]+) into an invocation of an external tool
cargo-${command}. The external tool must be present in one of the user's
$PATH directories.
Note: Cargo defaults to prioritizing external tools in
$CARGO_HOME/binover$PATH. Users can override this precedence by adding$CARGO_HOME/binto$PATH.
When Cargo invokes a custom subcommand, the first argument to the subcommand
will be the filename of the custom subcommand, as usual. The second argument
will be the subcommand name itself. For example, the second argument would be
${command} when invoking cargo-${command}. Any additional arguments on the
command line will be forwarded unchanged.
Cargo can also display the help output of a custom subcommand with cargo help ${command}. Cargo assumes that the subcommand will print a help message if its
third argument is --help. So, cargo help ${command} would invoke
cargo-${command} ${command} --help.
Custom subcommands may use the CARGO environment variable to call back to
Cargo. Alternatively, it can link to cargo crate as a library, but this
approach has drawbacks:
- Cargo as a library is unstable: the API may change without deprecation
- versions of the linked Cargo library may be different from the Cargo binary
Instead, it is encouraged to use the CLI interface to drive Cargo. The cargo metadata command can be used to obtain information about the current project
(the cargo_metadata crate provides a Rust interface to this command).