# Pre-RFC: Presets for Cargo

**URL:** https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527
**Category:** cargo
**Created:** [March 23, 2024, 4:36pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527 "2024-03-23T16:36:41Z")
**Posts on this page:** 18
**Page:** 2

<div class="post-metadata">

### Author: ![Kobzol](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kobzol/32/8433_2.png) [@Kobzol](https://internals.rust-lang.org/u/Kobzol)
#### Post date: [March 26, 2024, 8:15am UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/21 "2024-03-26T08:15:29Z")

</div>

I wonder if this could be done completely outside of Cargo, e.g. by storing profile templates and other information in some configuration files on disk, for example through [GitHub - Kobzol/cargo-wizard: Cargo subcommand for configuring Cargo projects for best performance.](https://github.com/Kobzol/cargo-wizard).

---

<div class="post-metadata">

### Author: ![epage](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/epage/32/3171_2.png) [@epage](https://internals.rust-lang.org/u/epage)
#### Post date: [March 26, 2024, 1:17pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/22 "2024-03-26T13:17:27Z")

</div>

> [@crumblingstatue](#):
>
> The user setting what build configuration they want to use definitely does not belong in `Cargo.toml`, because that file is tracked by git, and you don't want the user to have to worry about accidentally committing their preferred build configuration.

For the use cases I've seen related to presets, it seems like they would be global to the project and not per-user. For example, your motivating vase is for `mybackend` vs `web` which seems tied to the project to be shared by everyone. Could you expand on the per-user side of this and why that is the default expectation?

If this were managed through config, there is the [config-include feature](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#config-include). One potential idea with that is the ability to include things if present, either through weak-includes or globs. If presets were in config, this would allow maintainers to manually build up support out of existing pieces to allow user-controlled config.

> [@crumblingstatue](#):
>
> It's much more tedious and error prone to have to go into Rust-analyzer's settings in your editor, and change the target string and write down the right feature configuration manually, rather than having to change a single name in a central place (The `default` field in `.cargo/presets.toml`)

It sounds like solutions like aliases would work here. You define an alias and have each of these tools invoke that instead, right?

> [@crumblingstatue](#):
>
> Well, they wouldn't be versioned by default. It would be up to the user if they want to version it or not, but it would be unwise to version in most cases, because it contains user preferences that aren't meant to be versioned. Just as it is unwise to version `.cargo/config.toml`, which can contain local paths, among other things

Frequently people do version `.cargo/config.toml` and it is versioned by default in the sense that `cargo new`s `.gitignore` doesn't exclude it.

---

<div class="post-metadata">

### Author: ![recatek](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/recatek/32/10626_2.png) [@recatek](https://internals.rust-lang.org/u/recatek)
#### Post date: [March 26, 2024, 3:32pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/23 "2024-03-26T15:32:52Z")

</div>

Want to link this old [feature request I wrote for rust-analyzer](https://github.com/rust-lang/rust-analyzer/issues/15386) because I think it's pretty relevant. With the gif from it:

![257986133-3a206644-e19a-4a5d-90c8-6d49f1fe200d](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/0/0eb4ce0a0100a312037dcbdcbfd2c65719dcc32d.gif)

To my knowledge, Rust tooling currently doesn't support this kind of IDE interaction for quick feature/target selection the way Visual Studio does for C++ and C#. This makes it rather painful to work for multiple targets, especially mutually exclusive targets (like client vs. server). Having some sort of .sln-like functionality in Rust cargo files that could be read and supported by tooling for fast pulldown toggling would close a usability gap.

In order for this to work, you probably need something more than a makefile. At least, if you want Rust tooling integration for the feature to be common across different IDEs.

---

<div class="post-metadata">

### Author: ![Kobzol](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kobzol/32/8433_2.png) [@Kobzol](https://internals.rust-lang.org/u/Kobzol)
#### Post date: [March 26, 2024, 3:44pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/24 "2024-03-26T15:44:44Z")

</div>

RustRover can do this, by the way ([https://twitter.com/rustrover/status/1717124628886245523](https://twitter.com/rustrover/status/1717124628886245523)), it allows you to both override the target and enabled features.

---

<div class="post-metadata">

### Author: ![crumblingstatue](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crumblingstatue/32/202_2.png) [@crumblingstatue](https://internals.rust-lang.org/u/crumblingstatue)
#### Post date: [March 26, 2024, 4:07pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/25 "2024-03-26T16:07:03Z")

</div>

> [@epage](#):
>
> For the use cases I've seen related to presets, it seems like they would be global to the project and not per-user. For example, your motivating vase is for `mybackend` vs `web` which seems tied to the project to be shared by everyone. Could you expand on the per-user side of this and why that is the default expectation?

Right now, the default way to select a specific build configuration is to manually define the right target and feature combination. If presets would need to be defined in `Cargo.toml`, it would make the usage of presets rely on `Cargo.toml` having the presets the user want to use defined. Or the user would have to make a pull request, or deal with merge conflicts, rebasing, etc. to maintain their presets in `Cargo.toml`. There might also be a feature/target combination that the authors of the crate simply didn't think of to include, or don't feel like listing every single possible valid combination as named presets. This again, would make presets unusable if the user couldn't define their desired target/feature combination on their own.

There is definitely an argument for being able to define presets in `Cargo.toml`, but there should be a way for the user (person building the project) to define their own independent of version tracked `Cargo.toml`.

Then there is the selection of the default preset. That one definitely does not belong in `Cargo.toml`, because the user should be able to define which preset they want to use at any time, without having to worry about changing version tracked files.

> [@epage](#):
>
> It sounds like solutions like aliases would work here. You define an alias and have each of these tools invoke that instead, right?

What do you mean by aliases? Shell aliases? Normal tooling does not invoke shell aliases, they invoke commands, which are not affected by shell aliases. Rust-analyzer for example is not aware of the shell you are using. It just runs `cargo` from `PATH`. You would need a cargo wrapper, like the one I made, for tooling to invoke cargo with the right flags.

> [@epage](#):
>
> Frequently people do version `.cargo/config.toml` and it is versioned by default in the sense that `cargo new`s `.gitignore` doesn't exclude it.

That's an argument against putting presets in `.cargo/config.toml` then. There should be a way to define local preferences without having to worry about changing version tracked files.

---

<div class="post-metadata">

### Author: ![recatek](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/recatek/32/10626_2.png) [@recatek](https://internals.rust-lang.org/u/recatek)
#### Post date: [March 26, 2024, 4:16pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/26 "2024-03-26T16:16:33Z")

</div>

AFAIK this is only for targets, not for build configurations (client vs. server vs. editor, etc.) on the same target. You would need a build configuration and collection of features, potentially including mutually exclusive features, for the latter, and that would require something like presets to support. Either that or it would come down to each IDE having their own custom tooling/extension to do so.

---

<div class="post-metadata">

### Author: ![epage](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/epage/32/3171_2.png) [@epage](https://internals.rust-lang.org/u/epage)
#### Post date: [March 26, 2024, 4:16pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/27 "2024-03-26T16:16:39Z")

</div>

> [@crumblingstatue](#):
>
> Right now, the default way to select a specific build configuration is to manually define the right target and feature combination. If presets would need to be defined in `Cargo.toml`, it would make the usage of presets rely on `Cargo.toml` having the presets the user want to use defined. Or the user would have to make a pull request, or deal with merge conflicts, rebasing, etc. to maintain their presets in `Cargo.toml`. There might also be a feature/target combination that the authors of the crate simply didn't think of to include, or don't feel like listing every single possible valid combination as named presets. This again, would make presets unusable if the user couldn't define their desired target/feature combination on their own.

Please give a concrete use cases where there are not project-common presets that is justifies itself over project-common ones.

> [@crumblingstatue](#):
>
> What do you mean by aliases? Shell aliases? Normal tooling does not invoke shell aliases, they invoke commands, which are not affected by shell aliases. Rust-analyzer for example is not aware of the shell you are using. It just runs `cargo` from `PATH`. You would need a cargo wrapper, like the one I made, for tooling to invoke cargo with the right flags.

Cargo aliases which where talked about both in Zulip and on this thread.

---

<div class="post-metadata">

### Author: ![recatek](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/recatek/32/10626_2.png) [@recatek](https://internals.rust-lang.org/u/recatek)
#### Post date: [March 26, 2024, 9:56pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/28 "2024-03-26T21:56:35Z")

</div>

Out of curiosity, are there existing RFCs or pre-RFCs/proposals to add feature support to profiles?

---

<div class="post-metadata">

### Author: ![crumblingstatue](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crumblingstatue/32/202_2.png) [@crumblingstatue](https://internals.rust-lang.org/u/crumblingstatue)
#### Post date: [March 27, 2024, 1:20pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/29 "2024-03-27T13:20:47Z")

</div>

> [@epage](#):
>
> Please give a concrete use cases where there are not project-common presets that is justifies itself over project-common ones.

What if a user wants to build for their own exotic target? It's unreasonable to expect project maintainers to make presets for every conceivable target in `Cargo.toml`

Second, you have to understand that this would be a new feature if it got implemented. Should people who want to use presets submit pull requests to every project not owned by them that they want to work on and use presets on, or have to deal with unmerged changes?

Third, it's not developer friendly to make developers have to deal with people instead of just being able to solve their own local problem and get onto solving real problems. Why force them to write a pull request, and potentially argue with people why they should merge their change, just as I am arguing here? The developer friendly thing to do is let them define their own local preferences, and get on with their lives, and solve real problems that interest them.

Fourth, you ignored my argument about setting defaults, which is an important part of this proposal, and allows the user to conveniently switch between presets. This does not belong to Cargo.toml. The developer should be able to switch between presets at their own convenience, without needing to care about versioned changes.

> [@epage](#):
>
> Cargo aliases which where talked about both in Zulip and on this thread.

Fair enough, I haven't really looked at what "cargo aliases" are exactly. Maybe they do help in solving the problem, but I am too exhausted of this topic right now to do research on it.

---

<div class="post-metadata">

### Author: ![crumblingstatue](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crumblingstatue/32/202_2.png) [@crumblingstatue](https://internals.rust-lang.org/u/crumblingstatue)
#### Post date: [March 27, 2024, 1:30pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/30 "2024-03-27T13:30:18Z")

</div>

> [@epage](#):
>
> Cargo aliases which where talked about both in Zulip and on this thread.

If you mean [Configuration - The Cargo Book](https://doc.rust-lang.org/cargo/reference/config.html#alias), then I don't see how that would help with the problem.

> Aliases are not allowed to redefine existing built-in commands.

So you mean define an alias like `cargo build-my-backend`? How would rust-analyzer know to invoke it? Should rust-analyzer have its own configuration for invoking different aliases of cargo? Sure, it would solve the problem of having the flags being centrally defined in an alias, but it doesn't solve the problem of being able to easily switch between presets, and automatically synchronizing it between all tools, like presets does with the default preset.

What people trying to argue for alternatives should keep in mind: **The user should be able to easily switch between presets without:**

1. Having to reconfigure each tool separately (yes, changing what alias it uses counts as reconfiguration)
2. The user shouldn't have to make a versioned change to switch between presets

**If your alternative does not meet these requirements, then it's not a solution for this RFC's motivation, please write a different RFC, thank you.**

---

<div class="post-metadata">

### Author: ![pitaj](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pitaj/32/11262_2.png) [@pitaj](https://internals.rust-lang.org/u/pitaj)
#### Post date: [March 27, 2024, 2:56pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/31 "2024-03-27T14:56:43Z")

</div>

I don't see how your RFC addresses the "set every tool independently" issue - you say it just uses the default preset, but that doesn't seem like a full solution.

You can set a custom check command in rust-analyzer, so you could just set that to the cargo alias. I know that requires some amount of configuration, but switching between presets would require changing the configuration as well.

---

<div class="post-metadata">

### Author: ![weihanglo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/weihanglo/32/3674_2.png) [@weihanglo](https://internals.rust-lang.org/u/weihanglo)
#### Post date: [March 27, 2024, 7:18pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/32 "2024-03-27T19:18:27Z")

</div>

Would it makes live easier for switching between different preset/custom commands, if Cargo supports loading arguments from files a.k.a argfile?

As far as I can tell, rustc supports [`@path`](https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path).

---

<div class="post-metadata">

### Author: ![recatek](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/recatek/32/10626_2.png) [@recatek](https://internals.rust-lang.org/u/recatek)
#### Post date: [March 28, 2024, 3:34am UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/33 "2024-03-28T03:34:51Z")

</div>

For the sake of tooling I imagine it's better to predefine the options and let the user switch between them as needed rather than having the entire file swap in and out.

---

<div class="post-metadata">

### Author: ![crumblingstatue](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crumblingstatue/32/202_2.png) [@crumblingstatue](https://internals.rust-lang.org/u/crumblingstatue)
#### Post date: [March 28, 2024, 10:55am UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/34 "2024-03-28T10:55:49Z")

</div>

It addresses the issue because the tools that use cargo don't have to do any special configuration, because cargo itself is configured to use a specific preset. Once you switch the default preset, any cargo invocation will use that preset. You don't have to do any tool-specific configuration.

Rust-analyzer for example reads the info for what features are active by invoking `cargo metadata`. When cargo is configured to use a specific preset by default, any invocation of `cargo metadata` will include the configured features, so you don't have to do any special configuration within Rust-analyzer.

---

<div class="post-metadata">

### Author: ![pitaj](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pitaj/32/11262_2.png) [@pitaj](https://internals.rust-lang.org/u/pitaj)
#### Post date: [March 28, 2024, 1:00pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/35 "2024-03-28T13:00:17Z")

</div>

If editing a file every time you want to change the preset for all tools is okay with you, a much simpler solution could be something like a `cargoflags` or `rustflags` file:

```rust
# mybackend present (default)
--no-default-features --features=window-backend-2

## web preset (disabled)
#--target wasm32-unknown-unknown --no-default-features --features=web-backend

```

Just toggle comments to change the "preset"

---

<div class="post-metadata">

### Author: ![crumblingstatue](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crumblingstatue/32/202_2.png) [@crumblingstatue](https://internals.rust-lang.org/u/crumblingstatue)
#### Post date: [March 28, 2024, 4:38pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/36 "2024-03-28T16:38:25Z")

</div>

Yeah, I agree that's a much less invasive change to Cargo, but it forms the core of a solution that would fit the motivation for this RFC.

And there could be a higher level third party solution on top of that to manage presets.

I might write an RFC for a `cargoflags` type solution in the future, although not right now, because I'm mentally exhausted from this one.

So if someone thinks that would be a good feature to add to cargo, feel free to write an RFC about it before me.

EDIT: I added an argfile alternative to the alternatives section of the RFC.

---

<div class="post-metadata">

### Author: ![crumblingstatue](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crumblingstatue/32/202_2.png) [@crumblingstatue](https://internals.rust-lang.org/u/crumblingstatue)
#### Post date: [April 2, 2024, 5:05pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/37 "2024-04-02T17:05:43Z")

</div>

Unfortunately, argfiles aren't a solution either, it seems.

> <https://github.com/rust-lang/cargo/issues/13690#issuecomment-2032508241>
>
> \### Problem
> 
> Currently, the only way to supply arguments to \`cargo\` is directl…y through the command line.
> For example if you want to build with a set of features, you always have to invoke cargo with \`(--no-default-features) --features=\[...\]\`.
> Furthermore, every single piece of tooling that invokes cargo (rust-analyzer, clippy, \[bacon\](https://github.com/Canop/bacon), etc.) has to also be configured to invoke cargo with the same flags, if the user wants to keep working with a specific feature combination.
> 
> If there was a way to tell cargo to load arguments from a file (through \`.cargo/config.toml\` for example), then all invocations of cargo would automatically load the specified flags, solving the problem of syncing various tooling, and having to needlessly repeat command line flags.
> 
> Also see \<https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527\> for what I'm trying to accomplish.
> Argfile support would greatly ease a third party implementation of presets, which currently requires a \[wrapper executable\](https://github.com/crumblingstatue/cargo-presets/) that rewrites arguments before executing cargo.
> 
> \### Proposed Solution
> 
> Have a way to configure cargo to load arguments from a specified file.
> This could be done in \`.cargo/config.toml\`.
> \`\`\`toml
> \[args\]
> file = "myargfile.txt" # Load command line flags from myargfile.txt
> \`\`\`
> Cargo would proceed to load the command line flags from the configured file, if it exists.
> 
> \- I think it would be reasonable if cargo printed a warning if the file doesn't exist, but would continue regardless.
> \- If any command line arguments conflict with the arguments specified in the argfile, I think it would make sense for the CLI flags to override the flags provided in the file, but stopping with an error is also reasonable, if that behavior is more desirable.
> 
> \### Notes
> 
> \- Rustc has support for argfiles via \[\`@argfile\`\](https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path), although for cargo, I want a solution that can be configured without having to specify \`@argfile\` on the command line to work.
> \- Zulip discussion: \<https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Argfile.20discussion\>

---

<div class="post-metadata">

### Author: ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)
#### Post date: [September 24, 2025, 5:06pm UTC](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527/38 "2025-09-24T17:06:12Z")

</div>

This topic was automatically closed 540 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/pre-rfc-presets-for-cargo/20527.md?page=1)
