# Pre-RFC: Split \`CARGO\_HOME\`

**URL:** <https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747>\
**Category:** cargo\
**Created:** [October 23, 2023, 8:28pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747 "2023-10-23T20:28:39Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [October 30, 2023, 4:01pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/21 "2023-10-30T16:01:44Z")

</div>

That file has no meaning on macOS. macOS does not follow Linux conventions (to the point of seeming spiteful about not following them on purpose).

AFAIK officially you're just not supposed to put cache directories anywhere except path [given by foundation framework when queried for an `NSCachesDirectory`](https://developer.apple.com/documentation/foundation/nsfilemanager/1407693-urlfordirectory). The undocumented way is to rename the directory to have a `.noindex` suffix, e.g. `~/.cargo.noindex`.

BTW: macOS also doesn't follow `.nobackup` convention. I had to add Apple-specific library call to Cargo to exclude the `target/` directories from backups (sadly there's no similar API for disk search). Apple strongly prefers exposing high-level library APIs over using any conventions or anything in the file system directly.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [October 30, 2023, 4:14pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/22 "2023-10-30T16:14:08Z")

</div>

There is whatever these translate to as well (I assume xattrs but I haven’t checked):

> **[isExcludedFromBackupKey | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/urlresourcekey/1408756-isexcludedfrombackupkey)**
>
> A key for indicating whether the system excludes the resource from all backups of app data.

> **[isPurgeableKey | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/urlresourcekey/3616044-ispurgeablekey)**
>
> The key for a Boolean value that indicates whether the file system can delete a file when the system needs to free space.

(that second one doesn’t say if it works on whole directories though)

Neither of these directly say they turn off indexing though.

---

<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:** [October 30, 2023, 4:24pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/23 "2023-10-30T16:24:11Z")

</div>

FYI I've updated the original post based on feedback. For more fine-grained updates, see [my branch's history](https://github.com/epage/rfcs/commits/split-home/text/0000-split-home.md).

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [October 30, 2023, 7:07pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/24 "2023-10-30T19:07:47Z")

</div>

> [@epage](#):
>
> For example, the determining of what targets exists to build is taken from a `Cargo.toml` on disk.

Can just `Cargo.toml` files be expanded instead of the whole tree? Or it could be some trait over the storage and turn into `git cat-file` or a traversal of the `.crate` file to get the relevant information.

> [@kornel](#):
>
> I had to add Apple-specific library call to Cargo to exclude the `target/` directories from backups

Sounds like a use case mirroring my own usage of `target` as symlinks off into a uniform location for such things (including build trees of non-Rust software).

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [October 30, 2023, 9:59pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/25 "2023-10-30T21:59:27Z")

</div>

For clarity, I didn't say not to use an app data folder, just that there's no specific reason to use Roaming instead of Local.

And actually the most proper way to retrieve the app data folder isn't the environment variable, it's the [Known Folders API](https://learn.microsoft.com/en-us/windows/win32/shell/known-folders) with `FOLDERID_LocalAppData`.

---

<div class="post-metadata">

**Author:** ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)\
**Post date:** [October 30, 2023, 10:32pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/26 "2023-10-30T22:32:33Z")

</div>

> [@epage](#):
>
> We'll add to the confusingly named [`home` package](https://crates.io/crates/home), the following
> 
> [...]
> 
> - `cargo_data_home`: Returns the first match
> 1. `CARGO_DATA_HOME`, if set
> 2. `home::cargo_home()`

I thought I'd note that `cargo-audit` uses the `home` crate to obtain `cargo_home()` from which it constructs e.g. `~/.cargo/advisory-db` as a cache of the advisory DB to scan against. However, it seems like we should have no trouble migrating to e.g. `cargo_data_home()` in future releases.

---

<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:** [October 31, 2023, 12:25am UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/27 "2023-10-31T00:25:50Z")

</div>

The reason to use Roaming rather than Local is because of convention, and because Microsoft recommends it. Local is for less important data. People may, for instance, back up Roaming but not Local.

---

<div class="post-metadata">

**Author:** ![djc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/djc/32/1592_2.png) [@djc](https://internals.rust-lang.org/u/djc)\
**Post date:** [November 1, 2023, 11:14am UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/28 "2023-11-01T11:14:27Z")

</div>

The advisory database seems like it belongs in the cache dir more than it belongs in the data dir.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [November 1, 2023, 12:37pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/29 "2023-11-01T12:37:11Z")

</div>

Agreed, given that it's caching a network resource that can be re-downloaded.

---

<div class="post-metadata">

**Author:** ![jan\_hudec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jan_hudec/32/4100_2.png) [@jan\_hudec](https://internals.rust-lang.org/u/jan_hudec)\
**Post date:** [November 6, 2023, 4:20pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/30 "2023-11-06T16:20:25Z")

</div>

There already is a [directories](https://crates.io/crates/directories) crate that understands the appropriate layout for each platform. I suggest just using it. Some thought was already spent mapping the respective recommendations to each other, no need to do it again.

> [@epage](#):
>
> macOS: This favors XDG over the platform-specific application directories to be more consistent with other CLI developer tooling.

I don't know which “other CLI developer tooling”, but it would be best if all _rust_-related tools converged on using [directories](https://crates.io/crates/directories) and then they'd behave consistently. And if tools for other languages differ, that's not a good reason to repeat their mistakes.

---

<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:** [November 6, 2023, 4:27pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/31 "2023-11-06T16:27:18Z")

</div>

Just because a package in the ecosystem did something is not justification for us to blindly follow it. Having a decision document from them would be the most relevant from any existing packages.

---

<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:** [November 7, 2023, 7:36pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/32 "2023-11-07T19:36:51Z")

</div>

I've done another update of the Pre-RFC.

This went all in on the fallback scheme approach though I do wonder if there is a way to make a hard-split work as it'd make old + new rust Just Work. The details to work out are around

- rustup setting CARGO\_HOME
- ~~rustup not supporting layered config~~ except there wouldn't be concurrent rustup versions, only cargo
- if rustup / cargo can handle multiple bin dir

---

<div class="post-metadata">

**Author:** ![eode](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eode/32/11730_2.png) [@eode](https://internals.rust-lang.org/u/eode)\
**Post date:** [January 26, 2024, 4:53pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/33 "2024-01-26T16:53:05Z")

</div>

Thanks for all of your work on this, and for keeping the broader, cross-platform issues in mind. It eases the mind and is good to see progress in this area.

With `rustup` assuming complete control of its bin dir, what effects could that have on `~/.local/bin` (the XDG spec location on Linux for installing binaries)? Does rustup, for example, delete/move binaries other than those it created, or do blanket deletions?

When there's a shared ~/.local/bin folder, with programs dropping binaries into it, there's always a potential for conflict, though conflicts are fairly rare. Partly, the rarity is because developers know that if they're making a program for general use, they must find an executable name that's unique in the `/bin, /usr/bin, /usr/local/bin` namespace -- which also typically means they'll be unique when the `~/.local/bin` namespace is added in as well.

Is it possible, though, that a`rustup` could be (reasonably) modified to only assume ownership of its own files placed in the folder, rather than the entire `bin` folder?

---

<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:** [January 26, 2024, 4:56pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/34 "2024-01-26T16:56:49Z")

</div>

Its been a while since I've looked into the rustup side of things. However, solving that is likely not a blocker for this milestone of the work so long as we decide to have a `CARGO_BIN_HOME` because this provides an opt-in mechanism for people to put the folders wherever they want and that can give us an opportunity to try things out and explore improvements throughout the toolchain, including rustup. Hopefully we can iterate and improve rustup to resolve any blockers to allow `XDG_BIN_HOME` but that can all come later when its easier to directly vet the work.

---

<div class="post-metadata">

**Author:** ![eode](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eode/32/11730_2.png) [@eode](https://internals.rust-lang.org/u/eode)\
**Post date:** [January 26, 2024, 6:35pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/35 "2024-01-26T18:35:55Z")

</div>

100%.

---

<div class="post-metadata">

**Author:** ![Managor](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/managor/32/11753_2.png) [@Managor](https://internals.rust-lang.org/u/Managor)\
**Post date:** [February 4, 2024, 12:06am UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/36 "2024-02-04T00:06:28Z")

</div>

Could the legacy location be set to be the first matching target? As in:

- `cargo_data_home`: Returns the first match

1. `~/.cargo`, if exists
2. `CARGO_DATA_HOME`, if set
3. `CARGO_HOME`, if set
4. `cargo_home()`, if present
5. linux or macOS:
6. `$XDG_DATA_HOME/cargo`, if set
7. `~/.local/share/cargo`

This might remove any need to migrate old users

---

<div class="post-metadata">

**Author:** ![LucasFA](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lucasfa/32/11794_2.png) [@LucasFA](https://internals.rust-lang.org/u/LucasFA)\
**Post date:** [February 13, 2024, 4:32pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/37 "2024-02-13T16:32:09Z")

</div>

If I understand correctly, if the `CARGO_DATA_HOME` varible is unset, there is no change in behaviour nor any need for any migration, either. This being because step 3, "`cargo_home()`, if it exists", acts as fallback to the default legacy value of `~/.cargo`. (And if it does not exist then it does go through to the XDG directories)

As implementation note, `cargo_home()` already checks `CARGO_HOME` before `~/.cargo`, so no need to check it manually. This does not affect the RFC though.

All in all, seems well though out. @epage, typo warning: you have repeated `CARGO_CONFIG_HOME` in the guide-level explanation. I suppose you meant `CARGO_CACHE_HOME` in one of them.

---

<div class="post-metadata">

**Author:** ![soloturn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/soloturn/32/10740_2.png) [@soloturn](https://internals.rust-lang.org/u/soloturn)\
**Post date:** [July 21, 2024, 4:12am UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/38 "2024-07-21T04:12:45Z")

</div>

epage, very cool to consider using cache, config and data directories. can you please abstain from inventing new variable names? just use existing xdg base directory specification, and one of the suggestion to have it on windows and macos, like the go implementation of xdg: [xdg/README.md at master · adrg/xdg · GitHub](https://github.com/adrg/xdg/blob/master/README.md)

then, it is not a cargo or rustup topic any more.

---

<div class="post-metadata">

**Author:** ![WhyNotHugo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/whynothugo/32/11085_2.png) [@WhyNotHugo](https://internals.rust-lang.org/u/WhyNotHugo)\
**Post date:** [July 24, 2024, 4:02pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/39 "2024-07-24T16:02:31Z")

</div>

The main issue with using custom variables instead of the standard ones, is that cargo/rustup would require explicit user configuration in order to not pollute the user's home with a mix of cache and runtime data.

I don't think that an application should place files in the wrong place and require explicit configuration to _not_ do so.

As a developer who uses Rust, configuring this is not a big deal, but folks who are downloading someone else's code don't really care about configuring Rustup and/or Cargo, they just want it to "not litter junk in the home directory".

_I mention this because somebody downloaded a project of mine recently and complained about all the crap that ended up in their home directory after building._

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [July 24, 2024, 5:20pm UTC](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747/40 "2024-07-24T17:20:50Z")

</div>

This is a first step. First, we split out the various different facets of Cargo's directories. Then, we figure out how to migrate without breaking backwards compatibility.

[Previous page](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747.md?page=1)

[Next page](https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747.md?page=3)
