Pre-RFC: Build Tool Support Policy (aka Tool Tier Policy)

I've been putting together some thoughts on creating a support policy for build tools, as suggested in https://github.com/rust-lang/rust/issues/129307

What tools?

The most obvious is the linker, since rustc invokes it (directly or via a driver) to build a final binary (dylib, cdylib, bin, test, etc.).

It also makes sense to include a C/C++ compiler since this is used while building the compiler (to build LLVM), the standard library (for compiler-builtins) and may be used when building a Rust project if it depends on cc-rs (not technically part of the Rust toolchain, but it is owned by the Rust project and commonly used by Rust code).

There are also a bunch of other tools that rustc invokes for special purposes, for example dlltool is used to generate import libraries on Windows -gnu targets for the raw-dylib feature.

There are tools that are used for Rust development that I would suggest are out-of-scope for this support policy. For example, IDEs, text editors and (although some may disagree) debuggers.

This can be summarized as: a linker, a C/C++ Compiler and any other tool that rustc may directly call itself.

Toolchains and individual tools

I propose that we talk about tools in two different groups:

  • "Toolchains" - these are sets of tools that contain everything needed to build the Rust toolchain itself and Rust binaries for at least ONE target. For example, GCC (cc1, cc1plus, ld, dlltool), LLVM (clang, clang++, lld) and MSVC (cl, link).
  • "Individual Tools" - these are single tools that can either be used to replace a tool from a toolchain or are used by Rust for special purposes. For example, the mold linker.

Being able to talk about entire toolchains is easier and more convenient that always having to list every single tool. It also better represents how these tools are used both within Rust's CI and in general.

To be clear, not every toolchain or tool needs to be able to build every target. For example, MSVC cannot build non-Windows targets and doesn't completely work for the Windows -gnu targets since it is missing dlltool. It is up to the individual targets in their documentation to note which toolchains may be used to build them.

Tiers of support

There are tools that are very well tested and supported as they are used within Rust's own CI system, thus are verified before every change is merged.

For tools that are not regularly tested, I suggest that calling them "supported" is based on the criteria that ChrisDenton called out when we dropped support for VS 2012: if someone were to report a bug when using this tool, would we actively investigate and fix it?

Mapping this onto the existing Platform Support tier model gives us these tiers:

  • Tier 1: "Guaranteed to Work". The Rust project uses these tools to produce official binaries for at least one Tier 1 platform.
  • Tier 2: "Guaranteed to Build". The Rust project uses these tools to produce official binaries for at least one Tier 2 platform.
  • Tier 3: "Supported". The Rust project does not use these tools to produce any official binaries for Tier 1 or Tier 2 platforms, but they should still work. Issues and incompatibilities with these tools may be introduced when changes are made to Rust, but this would be considered a bug and will be investigated when reported.

Note on tool versions

When documenting required tools, it's common to require a specific version "or later" with the assumption that a tool vendor has not introduced regressions in later versions of their tool. That said, it's also common for breaking changes to be introduced between major versions of tools.

To handle different versions of a tool, I propose the following policy:

Unless otherwise noted for a given tool, different versions of a tool will have the following tiers:

  • The same major version, but a later minor version will have the same tier. (Assume forward compatibility)
  • The same major version, but an earlier minor version will be Tier 3. (Assume bug fixes)
  • A later major version will be Tier 3. (Assume breaking changes)
  • An earlier major version will not automatically be given a tier. (Assume nothing)

Adding and promoting tools

The process for adding and promoting tools would follow the existing target tier policy: filing an MCP, agreeing to the terms in the policy, etc.

Some promoting would happen simultaneously between tools and targets, for example if a Tier 2 target is being promoted to Tier 1 then if the associated tooling is Tier 2 it will also be promoted to Tier 1. Promoting may also happen independently if a new CI job is added that builds a higher tier target using a lower tier tool.

3 Likes

The C compiler is actually invoked as the linker driver, which in turn invokes the linker. At least on ELF targets (can't claim much knowledge about windows targets, which based on the rest of your post you seem to be basing your post on).

Only on Windows GNU targets presumably, e.g. x86_64-unknown-linux-gnu doesnt use dlltool.

Good clarifications - thanks!

Sounds like a good idea!

I would be careful to make a distinction between what is needed to build rustc versus what is needed to use rustc. Those might be very different (and also the audience for the latter is much larger).

It not only makes a difference in which tools are needed (building rustc needs a lot of stuff), but also potentially which versions. For example, in CI we use Visual Studio Enterprise 2022 for Windows. That's the only thing we can currently say we use to produce official binaries. But users of rustc certainly aren't required to use that, and I wouldn't want the documentation to imply that. It's a bit of a subtle thing that we don't necessarily test against many different C compilers, but we do expect them to work.

I think the documentation could be more restrictive for what is needed to build rustc versus what is needed to use it.

There's also a bit of lie in our target tier policy that we have certain versions that we support (like macOS 11) with automated testing, when in reality we generally only test one version. Making guarantees about the versions of tooling supported could also extend that if we say something like Visual Studio 2019 is tier 1, when we don't test that (but I think we do expect to work). It might be good to have some clarity around the difference between "we actually test" and "we expect to work as a first-class thing".

I don't mind separating out "what's used to build rustc" from "what rustc requires to build" - honestly the former is probably best documented in the rustc dev guide and kept in-sync with the CI runners.

As for:

It's a bit of a subtle thing that we don't necessarily test against many different C compilers, but we do expect them to work.

and

It might be good to have some clarity around the difference between "we actually test" and "we expect to work as a first-class thing".

That's the point of the different tier levels.

  • Tier 1: We built using these tools and tested that the final binaries work.
  • Tier 2: We built using these tools but did NOT test the final binaries.
  • Tier 3: We expect these tools to work and will fix reported bugs BUT have not tried them in any automated way.

I don't think we can really call something "tier 1" and then have no automation to verify it.

One could imagine extending the current CI system to have nightly (or even weekly) tests that pull down the nightly/beta/stable Rust toolchain and then use all of the tier 1/2 tools to build (and run) some set of tests.

2 Likes