GitHub
1# Adding a new target23These are a set of steps to add support for a new target.4There are numerous end states and paths to get there, so not all sections may be5relevant to your desired goal.67See also the associated documentation in the [target tier policy].89[target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target1011## Specifying a new LLVM1213For very new targets, you may need to use a different fork of LLVM14than what is currently shipped with Rust.15In that case, navigate to the `src/llvm-project` git submodule (you might need to run `./x16check` at least once so the submodule is updated), check out the17appropriate commit for your fork, then commit that new submodule18reference in the main Rust repository.1920An example would be:2122```23cd src/llvm-project24git remote add my-target-llvm some-llvm-repository25git checkout my-target-llvm/my-branch26cd ..27git add llvm-project28git commit -m 'Use my custom LLVM'29```3031### Using pre-built LLVM3233If you have a local LLVM checkout that is already built, you may be34able to configure Rust to treat your build as the system LLVM to avoid redundant builds.3536You can tell Rust to use a pre-built version of LLVM using the `target` section of `bootstrap.toml`:3738```toml39[target.x86_64-unknown-linux-gnu]40llvm-config = "/path/to/llvm/llvm-7.0.1/bin/llvm-config"41```4243If you are attempting to use a system LLVM, we have observed the following paths44before, though they may be different from your system:4546- `/usr/bin/llvm-config-8`47- `/usr/lib/llvm-8/bin/llvm-config`4849Note that you need to have the LLVM `FileCheck` tool installed, which is used for codegen tests.50This tool is normally built with LLVM, but if you use your51own preinstalled LLVM, you will need to provide `FileCheck` in some other way.52On Debian-based systems, you can install the `llvm-N-tools` package (where `N`53is the LLVM version number, e.g. `llvm-8-tools`). Alternately, you can specify54the path to `FileCheck` with the `llvm-filecheck` config item in `bootstrap.toml`55or you can disable codegen test with the `rust.codegen-tests` item in `bootstrap.toml`.5657## Creating a target specification5859You should start with a target JSON file.60You can see the specification for an existing target using `--print target-spec-json`:6162```63rustc -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json64```6566Save that JSON to a file and modify it as appropriate for your target.6768### Adding a target specification6970Once you have filled out a JSON specification and been able to compile71somewhat successfully, you can copy the specification into the compiler itself.7273You will need to add a line to the big table inside of the74`supported_targets` macro in the `rustc_target::spec` module.75You will then add a corresponding file for your new target containing a `target` function.7677Look for existing targets to use as examples.7879To use this target in bootstrap, we need to explicitly add the target triple to80the `STAGE0_MISSING_TARGETS` list in `src/bootstrap/src/core/sanity.rs`.81This is necessary because the default bootstrap compiler (typically a beta compiler)82does not recognize the new target we just added.83Therefore, it should be added to84`STAGE0_MISSING_TARGETS` so that the bootstrap is aware that this target is not85yet supported by the stage0 compiler.8687```diff88const STAGE0_MISSING_TARGETS: &[&str] = &[89+ "NEW_TARGET_TRIPLE"90];91```9293## Patching crates9495You may need to make changes to crates that the compiler depends on,96such as [`libc`][] or [`cc`][].97If so, you can use Cargo's [`[patch]`][patch] ability.98For example, if you want to use an unreleased version of `libc`, you can add it to the top-level99`Cargo.toml` file:100101```diff102diff --git a/Cargo.toml b/Cargo.toml103index 1e83f05e0ca..4d0172071c1 100644104--- a/Cargo.toml105+++ b/Cargo.toml106@@ -113,6 +113,8 @@ cargo-util = { path = "src/tools/cargo/crates/cargo-util" }107 [patch.crates-io]108+libc = { git = "https://github.com/rust-lang/libc", rev = "0bf7ce340699dcbacabdf5f16a242d2219a49ee0" }109110 # See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on111 # here112 rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }113```114115After this, run `cargo update -p libc` to update the lockfiles.116117Beware that if you patch to a local `path` dependency, this will enable118warnings for that dependency.119Some dependencies are not warning-free, and due120to the `rust.deny-warnings` setting in `bootstrap.toml`, the build may suddenly start to fail.121To work around warnings, you may want to:122- Modify the dependency to remove the warnings123- Or for local development purposes, suppress the warnings by setting `rust.deny-warnings = false` in bootstrap.toml.124125[`libc`]: https://crates.io/crates/libc126[`cc`]: https://crates.io/crates/cc127[patch]: https://doc.rust-lang.org/stable/cargo/reference/overriding-dependencies.html#the-patch-section128129## Cross-compiling130131Once you have a target specification in JSON and in the code, you can cross-compile `rustc`:132133```134DESTDIR=/path/to/install/in \135./x install -i --stage 1 --host aarch64-apple-darwin.json --target aarch64-apple-darwin \136compiler/rustc library/std137```138139If your target specification is already available in the bootstrap140compiler, you can use it instead of the JSON file for both arguments.141142## Promoting a target from tier 2 (target) to tier 2 (host)143144There are two levels of tier 2 targets:145- Targets that are only cross-compiled (`rustup target add`)146- Targets that [have a native toolchain][tier2-native] (`rustup toolchain install`)147148[tier2-native]: https://doc.rust-lang.org/nightly/rustc/target-tier-policy.html#tier-2-with-host-tools149150For an example of promoting a target from cross-compiled to native,151see [#75914](https://github.com/rust-lang/rust/pull/75914).