Skip to content

Add -C <DIR> flag to cargo to change directory before invoking #10098

@lilyball

Description

@lilyball

Problem

Cargo infers the manifest path and reads config based on the current directory. Plugins may potentially locate other config this same way. Cargo commands offer a --manifest-path flag to override the manifest, but this doesn't override config.

For example, given the following:

> cat bin/foo/.cargo/config.toml
[build]
target = "wasm32-unknown-unknown"
target-dir = "../../target"
> cargo build --manifest-path bin/foo/Cargo.toml

The resulting build will use the host platform instead of wasm32-unknown-unknown and the build artifacts will end up in bin/foo/target. But were I to run cd bin/foo && cargo build it would use the correct target and target dir.

Proposed Solution

Cargo should have a flag -C <DIR> (or --directory <DIR>) that exists at the top level rather than in the subcommands. This flag would cause cargo to change its working directory to the specified one before processing any commands or loading any config. It would be roughly equivalent to ( cd <DIR> && cargo … ).

Besides fixing the issue of loading cargo config, this is also a simpler interface for end users than --manifest-path as it means they don't have to worry about where the specific Cargo.toml file is, they can just run cargo as though it were in a specific directory.

This flag is inspired by both make and git which offer the same -C <DIR> (make has the long --directory form, I don't believe git has a long form). The desired behavior here should be based on git as it also defines how multiple -C flags interact (subsequent ones are interpreted relative to the earlier ones). Like git, any other flags or parameters that take relative paths should then be interpreted relative to the working directory caused by the -C option.

Notes

Regarding rustup and rust-toolchain.toml overrides, I'm inclined to say rustup should honor this flag as well and interpret it prior to locating an override file. The idea here is that saying cargo -C $path … should behave indistinguishably from running cargo within that path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-cliArea: Command-line interface, option parsing, etc.A-configurationArea: cargo config files and env varsC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions