Renaming Cargo "target"

Yeah. crate has a lot of problems and I almost brought it up but I think it shows up in enough places that we can't fix it as easily.

Cargo officially refers to a "crate" as a "target" (and those docs get into our sloppy use of the term build "target") though I think rustc uses the term to refer to a "build unit" which would include build scripts. .crate files and crates.io has people commonly assuming "crate" refers to a "package" which is a collection of crates, among other things.

1 Like

I agree, and if not for the many existing uses such as target_cpu and --target, I would agree that it'd be otherwise simpler to get used to such a change.

As I see it, “crate” has a well-defined formal meaning in the Rust language — crates are referred to in extern crate and crate:: and $crate::, and are the thing which trait coherence rules care about. The Rust language is the most explicitly stable part of the Rust, uh…“platform”, and therefore de-confusion efforts should move in the direction of making the tools agree with the language, not vice versa.

(But renaming crates.io would be too much breakage and not actually relevant. That's essentially a brand name, not a technical term except in the sense of being a domain name.)

1 Like

It absolutely is confusing. When I was building the cargo_toml crate, it was a nuisance to have multiple different types with a Target in the name, so I chose to use Product instead.

4 Likes

In regards to other ecosystems:

  • Xcode
    • uses "Products" for the files that have been built and directory where they're saved to, but also uses the term "Target" for the settings and build instructions how to make them. Xcode's equivalent of the target/ dir is called DerivedData, and there is DerivedData/Build/Products/{Debug,Release}/*.app.
1 Like

I for one, in the years I’ve known Cargo, always assumed that the target directory was named after target-as-in-platform.

After all, when cross-compiling, target/ is followed by the target name. And that’s what ‘target’ means in the context of --target, “target features”, “tier N targets”, et cetera. I did find it odd that in the more common use case of non-cross compiles, Cargo still uses target/ as the base path yet doesn’t put a target name under it. But I assumed this state of affairs was a a historical quirk. It never crossed my mind that the word “target” might be referring to something else entirely, until I read this thread. This is despite the fact that I’m familiar with other tools that use “target” to mean build product or rule. I expect different tools to use different terminology, but I don’t expect a single tool to use a single term in multiple different ways. (And I either didn’t know or had forgotten about --all-targets.)

My confusion was harmless, but I was confused.

6 Likes

:point_up_2: This seems like a better word to start with, rather than "artifacts".


Let's all remember that --all-targets works with cargo check, which does not build anything, mainly no artifacts. In that context, it means cargo check --sources-involved-in-producing[1]-all-artifacts.

  • Similarly, cargo test --all-artifacts would not be testing (among other things) the --lib artifact (since it's not an executable); it would be testing the test --lib --no-run-compiled artifact (the --lib with cfg!(test), dev-dependencies, and the test harness; speaking of which, this one is awfully difficult to name or talk about).

    And yet cargo build --all-artifacts does build the --lib artifact.

So let's try to aim for something closer to output/product, rather than artifact.

That being said:

This sentence does show that, especially w.r.t. cargo commands, --all-targets can be perceived as to be referring to, by metonymy, the source code that is or could be involved in producing/outputting that target artifact. So it's a way more "wobbly" term than something overly specific such as the word artifact.

In this regard, the word recipe seems also like a good candidate, since it's a less opinionated / more flexible term, much like target was.


  1. ↩︎

imo "output" is too generic. In discussing how to stabilize --out-dir, we renamed it to --artifact-dir because OUT_DIR is a term thats used for where build scripts should output to and having the two was confusing.

3 Likes

And --artifact-dir is indeed a great term! Because it directly interacts with the produced artifacts of cargo build commands. For instance, --artifact-dir would make no sense in the context of cargo checking.

What I am trying to get at, is:

When we say --lib, we refer to the source tree under src/lib.rs, hence why it can be cargo checked (no artifacts involved), cargo build[t] (library artifacts involved), or cargo tested (binary artifact of src/lib.rs source tree with cfg!(test) and dev-dependencies and test harness).

The only thing that --lib has in common in these three contexts is the src/lib.rs source tree, and its dependencies; or rather, the one thing these three contexts do not have in common is the artifact!

In other words, we can keep looking for the right word, but, regarding:

it's just plainly false that --lib refers to the output of a compilation process; cargo building it does.


target worked in all these contexts because it was a metonymical term; if we are to replace it, we need another one such. Recipe is the only one I have been able to come up with, but hopefully others can find other ideas :slightly_smiling_face:

2 Likes

It also doesn't produce any outputs (other than the build log), so --all-outputs wouldn't be accurate either.

Complete love to this proposal, don't care what we end up with, it just has to be two different words!

I actually thought up until this point that --all-targets meant some sort of compilation mode where all target triples were being considered at the same time (which, on further reflection, is the holy grail of rustdoc, and an unsolved problem, so obviously it's not that).

1 Like

I think the cargo check case is interesting, because selecting what to check refers to checking the inputs (recipes, blueprints, sources) rather than the outputs (products, artifacts, binaries).

Cargo currently has a single term for both the inputs and the outputs. Choosing a new term that refers specifically to the outputs could make talking about the inputs side weirder.

I feel this pain every time I touch Cargo's definition of Cargo.toml.

I would say we've misused our output term to also refer to inputs through use of it as a metonym (thanks @dhm as I've been trying to remember this word for years!). Referring to an input as a "target' makes as much sense as referring to the input as an "artifact" or "output". They are all about what you produce.

3 Likes

With the benefit of 100% hindsight, I wish we had used "platform" and "target" from the beginning. Having to use "target" and "artifact" is a path-dependent less-optimal solution. But it's where we are, if we're not willing to create massive user confusion in the course of addressing this.

3 Likes

Since I haven't heard the suggestion, yet: What about --everything (since --all is already used as a (deprecated) alias for --workspace)? Another option could be to shorten it to -a, though that may be too concise (or combine them: -a alias to --everything).

Rationale for --everything (or reusing --all):

Cargo currently allows listing integration tests, libs, bins, examples, ... in the Cargo.toml. If they are not present it auto-detects them. I think this should [1] be extended to also include the --target x those artifacts should be built for. There already is a way to specify which features are needed for that [2], so why shouldn't the same thing exist for the target platform? This would allow specifying everything needed to build, check and test all artifacts that are needed using a single command.

If that is added --everything clearly indicates that everything that is relevant for production, CI and the project in general [3] and having the ability to do cargo check --everything to check for multiple targets + feature flag combinations would be useful [4] (and there is a place that lists everything that is supposed to compile).

This could even be extended to a --group x where the above mentioned list contains all groups one "target"/artifact/output should be included in.


  1. Probably later, not as part of this rename ↩︎

  2. Though you still need to list them when invoking cargo build ↩︎

  3. I'm not sure if --everything should imply --workspace, if it does it may even be possible to reuse --all ↩︎

  4. Without that you need an external tool or (multiple) custom bash scripts: Checking everything in the CI, compiling everything for a release ↩︎

Does it have to be a single English word? Can't it be either multiple English words (e.g. "build target" or "cargo target") or a single non-English word (e.g. "btarget" or "carget")?

I can see how those options will result in a worse user experience (more characters to type or less intuitive words), but maybe there's a solution in this space that reaches a better trade-off. For example, it could ease the transition, because "build target" or "carget" is closer to "target" than "artifact" is. Not trying to argue for any option (I hate choosing names), just making sure the search space is not unintentionally constrained.

4 Likes

[quote="DragonDev1906, post:35, topic:21585"] I think this should [1]be extended to also include the --target x those artifacts should be built for. [/quote]

Yes, we have issues for and are interested in

  • Specifying what platform-targets a package supports
  • Specifying what platform-targets your build-targets support

There is various amounts of design work needed for each.

This reminds me of a command I ran yesterday

$ cargo check --all --all-targets --all-features

which felt repetitive

As for a flag to run "everything", I feel like that would be tailored to very specific applications and not work otherwise. For libraries, there really isn't a concept of an "everything" and instead you need cargo hack --feature-powerset. For cross-platform applications, building for every platform at once would be suboptimal both in CI and locally. If you had a specific application that had pieces that only worked on one target each, then I could see that working.

1 Like

This could be partially fixed by changing the documentation and messages to consistently use the term "target platform" and then pretend that the CLI flags are an abbreviation of that.

4 Likes

I don't think “platform” is the right replacement term for the target triple[1]. “Platform” is generally used to mean some mutually exclusive choice of — the OS, or OS and physical CPU architecture, or some bundle of attributes like that, but in any case something the users of the computer are likely aware of. But a given platform can often run programs with many possible target-triples:

  • Windows -msvc vs. -gnu
  • Linux -musl alternative
  • 32-bit programs running on 64-bit kernels
  • macOS has, over many years of history, often had two completely different architectures runnable via some form of transparent emulation (68k to PowerPC, then PowerPC to x86, then x86 to ARM).

Overall, I like the idea of renaming “Cargo target” and not renaming “target [triple/tuple]” (unless a better term comes along).


  1. yes, “triple” is also a misnomer ↩︎

3 Likes

I believe it's actually using both while also confounding profiles with targets..

for cross compilation, you will often get target/x86_64-unknown-linux-musl/debug and similar.

1 Like