External Tools - The Cargo Book

## 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 metadata` command, which outputs project structure and dependencies information in JSON,

- a `--message-format` flag, which outputs information about a particular build, and

- support for custom subcommands.

### Information about project structure

You can use `cargo metadata` command to get information about project structure and dependencies. The output of the command looks like this:

    {
      // Integer version number of the format.
      "version": integer,

      // List of packages for this workspace, including dependencies.
      "packages": [
        {
          // Opaque package identifier.
          "id": PackageId,

          "name": string,

          "version": string,

          "source": SourceId,

          // A list of declared dependencies, see `resolve` field for actual dependencies.
          "dependencies": [ Dependency ],

          "targets: [ Target ],

          // Path to Cargo.toml
          "manifest_path": string,
        }
      ],

      "workspace_members": [ PackageId ],

      // Dependencies graph.
      "resolve": {
         "nodes": [
           {
             "id": PackageId,
             "dependencies": [ PackageId ]
           }
         ]
      }
    }

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, there is cargo_metadata crate.

### Information about build

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.

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

### 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}` that then needs to be present in one of the user's `$PATH` directories.

Custom subcommand may use `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, API changes without deprecation,

- versions of Cargo library and Cargo binary may be different.