External tools

One of the goals of Cargo is simple integration with third-party tools, likeIDEs and other build systems. To make integration easier, Cargo has severalfacilities:

  • a cargo metadata command, which outputs package structure and dependenciesinformation in JSON,

  • a —message-format flag, 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 structureand dependencies. The output of the command looks like this:

  1. {
  2. // Integer version number of the format.
  3. "version": integer,
  4. // List of packages for this workspace, including dependencies.
  5. "packages": [
  6. {
  7. // Opaque package identifier.
  8. "id": PackageId,
  9. "name": string,
  10. "version": string,
  11. "source": SourceId,
  12. // A list of declared dependencies, see `resolve` field for actual dependencies.
  13. "dependencies": [ Dependency ],
  14. "targets: [ Target ],
  15. // Path to Cargo.toml
  16. "manifest_path": string,
  17. }
  18. ],
  19. "workspace_members": [ PackageId ],
  20. // Dependencies graph.
  21. "resolve": {
  22. "nodes": [
  23. {
  24. "id": PackageId,
  25. "dependencies": [ PackageId ]
  26. }
  27. ]
  28. }
  29. }

The format is stable and versioned. When calling cargo metadata, you shouldpass —format-version flag explicitly to avoid forward incompatibilityhazard.

If you are using Rust, there is cargo_metadata crate.

Information about build

When passing —message-format=json, Cargo will output the followinginformation 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 fielddistinguishes different kinds of messages.

Information about dependencies in the Makefile-compatible format is stored inthe .d files alongside the artifacts.

Custom subcommands

Cargo is designed to be extensible with new subcommands without having to modifyCargo itself. This is achieved by translating a cargo invocation of the formcargo (?<command>[^ ]+) into an invocation of an external toolcargo-${command}. The external tool must be present in one of the user's$PATH directories.

When Cargo invokes a custom subcommand, the first argument to the subcommandwill be the filename of the custom subcommand, as usual. The second argumentwill be the subcommand name itself. For example, the second argument would be${command} when invoking cargo-${command}. Any additional arguments on thecommand 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 itsthird argument is —help. So, cargo help ${command} would invokecargo-${command} ${command} —help.

Custom subcommands may use the CARGO environment variable to call back toCargo. Alternatively, it can link to cargo crate as a library, but thisapproach 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