Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic steps for a new target #805

Merged
merged 2 commits into from
Jul 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [Documenting Compiler](./building/compiler-documenting.md)
- [Rustdoc](./rustdoc.md)
- [ctags](./building/ctags.md)
- [Adding a new target](./building/new-target.md)
- [The compiler testing framework](./tests/intro.md)
- [Running tests](./tests/running.md)
- [Adding new tests](./tests/adding.md)
Expand Down
101 changes: 101 additions & 0 deletions src/building/new-target.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Adding a new target

These are a set of steps to add support for a new target. There are
numerous end states and paths to get there, so not all sections may be
relevant to your desired goal.

## Specifying a new LLVM

For very new targets, you may need to use a different fork of LLVM
than what is currently shipped with Rust. In that case, navigate to
the `src/llvm_project` git submodule (you might need to run `x.py
check` at least once so the submodule is updated), check out the
appropriate commit for your fork, then commit that new submodule
reference in the main Rust repository.

An example would be:

```
cd src/llvm_project
git remote add my-target-llvm some-llvm-repository
git checkout my-target-llvm/my-branch
cd ..
git add llvm_target
git commit -m 'Use my custom LLVM'
```

If you have a local LLVM checkout that is already built, you *may* be
able to configure Rust to treat your build as the [system
LLVM][sysllvm] to avoid redundant builds.

[sysllvm]: ./suggested.md#building-with-system-llvm

## Creating a target specification

You should start with a target JSON file. You can see the specification
for an existing target using `--print target-spec-json`:

```
rustc -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json
```

Save that JSON to a file and modify it as appropriate for your target.

### Adding a target specification

Once you have filled out a JSON specification and been able to compile
somewhat successfully, you can copy the specification into the
compiler itself.

You will need to add a line to the big table inside of the
`supported_targets` macro in the `librustc_target::spec` module. You
will then add a corresponding file for your new target containing a
`target` function.

Look for existing targets to use as examples

## Patching crates

You may need to make changes to crates that the compiler depends on,
such as [`libc`][] or [`cc`][]. If so, you can use Cargo's
[`[patch]`][patch] ability. For example, if you want to use an
unreleased version of `libc`, you can add it to the top-level
`Cargo.toml` file:

```diff
diff --git a/Cargo.toml b/Cargo.toml
index be15e50e2bc..4fb1248ba99 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -66,10 +66,11 @@ cargo = { path = "src/tools/cargo" }
[patch.crates-io]
# Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
# that we're shipping as well (to ensure that the rustfmt in RLS and the
# `rustfmt` executable are the same exact version).
rustfmt-nightly = { path = "src/tools/rustfmt" }
+libc = { git = "https://github.com/rust-lang/libc", rev = "0bf7ce340699dcbacabdf5f16a242d2219a49ee0" }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to describe when or why you might want to patch the libc used by the top-level Cargo.toml versus situations where you'd patch the libc dependency of rustc-std-workspace-{std,core,alloc} (assuming there are some)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be possible, but I don't know the reason. I only needed to patch the listed Cargo.toml.


# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
# here
rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
```

After this, run `cargo update -p libc` to update the lockfiles.

[`libc`]: https://crates.io/crates/libc
[`cc`]: https://crates.io/crates/cc
[patch]: https://doc.rust-lang.org/stable/cargo/reference/overriding-dependencies.html#the-patch-section

## Cross-compiling

Once you have a target specification in JSON and in the code, you can
cross-compile `rustc`:

```
DESTDIR=/path/to/install/in \
./x.py install -i --stage 1 --host aarch64-apple-darwin.json --target aarch64-apple-darwin \
src/librustc src/libstd
```

If your target specification is already available in the bootstrap
compiler, you can use it instead of the JSON file for both arguments.
JohnTitor marked this conversation as resolved.
Show resolved Hide resolved