コンパイラサポートに関する注記
この本では、組み込みのコンパイラターゲットである thumbv7m-none-eabi を利用しています。このターゲット向けには、Rust
チームが rust-std コンポーネントを配布しており、これは core
や std のようなクレートを事前コンパイルしたコレクションです。
この本の内容を別のターゲットアーキテクチャ向けに再現してみたい場合は、Rust が(コンパイル) ターゲットに対して提供しているサポートのレベルの違いを考慮する必要があります。
LLVM サポート
Rust 1.28 時点では、公式の Rust コンパイラである rustc は、(機械語)コード生成に LLVM を使用しています。Rust がアーキテクチャに対して提供する最小限のサポートレベルは、
rustc でその LLVM バックエンドが有効化されていることです。LLVM を通じて rustc がサポートしているすべてのアーキテクチャは、次のコマンドを実行することで確認できます。
$ # このコマンドを実行するには `cargo-binutils` がインストールされている必要があります
$ cargo objdump -- --version
LLVM (http://llvm.org/):
LLVM version 7.0.0svn
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_be - AArch64 (big endian)
arm - ARM
arm64 - ARM64 (little endian)
armeb - ARM (big endian)
hexagon - Hexagon
mips - Mips
mips64 - Mips64 [experimental]
mips64el - Mips64el [experimental]
mipsel - Mipsel
msp430 - MSP430 [experimental]
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
ppc32 - PowerPC 32
ppc64 - PowerPC 64
ppc64le - PowerPC 64 LE
sparc - Sparc
sparcel - Sparc LE
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
thumbeb - Thumb (big endian)
wasm32 - WebAssembly 32-bit
wasm64 - WebAssembly 64-bit
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
LLVM が目的のアーキテクチャをサポートしていても、rustc がそのバックエンドを無効にした状態でビルドされている場合(Rust 1.28 時点での AVR がこれに該当します)は、それを有効にするよう Rust のソースコードを変更する必要があります。PR rust-lang/rust#52787 の最初の 2 つのコミットを見ると、必要な変更のイメージがつかめます。
一方で、LLVM 自体はそのアーキテクチャをサポートしていないものの、LLVM のフォークがサポートしている場合は、rustc をビルドする前に元の LLVM をそのフォークに置き換える必要があります。Rust のビルドシステムはこれを許容しており、原則として llvm サブモジュールの参照先をそのフォークに変更するだけで済むはずです。
ターゲットアーキテクチャがベンダー提供の GCC でしかサポートされていない場合は、非公式の Rust コンパイラである mrustc を使って Rust プログラムを C コードに変換し、その後 GCC でコンパイルするという選択肢があります。
組み込みターゲット
コンパイルターゲットは、単なるアーキテクチャ以上のものです。各ターゲットには、それに対応する specification があり、そこには特に、そのアーキテクチャ、オペレーティングシステム、デフォルトのリンカーが記述されています。
Rust コンパイラは複数のターゲットを認識しています。これらはコンパイラに 組み込まれて おり、次のコマンドを実行すると一覧表示できます。
``` console
$ rustc --print target-list | column
aarch64-fuchsia mipsisa32r6el-unknown-linux-gnu
aarch64-linux-android mipsisa64r6-unknown-linux-gnuabi64
aarch64-pc-windows-msvc mipsisa64r6el-unknown-linux-gnuabi64
aarch64-unknown-cloudabi msp430-none-elf
aarch64-unknown-freebsd nvptx64-nvidia-cuda
aarch64-unknown-hermit powerpc-unknown-linux-gnu
aarch64-unknown-linux-gnu powerpc-unknown-linux-gnuspe
aarch64-unknown-linux-musl powerpc-unknown-linux-musl
aarch64-unknown-netbsd powerpc-unknown-netbsd
aarch64-unknown-none powerpc-wrs-vxworks
aarch64-unknown-none-softfloat powerpc-wrs-vxworks-spe
aarch64-unknown-openbsd powerpc64-unknown-freebsd
aarch64-unknown-redox powerpc64-unknown-linux-gnu
aarch64-uwp-windows-msvc powerpc64-unknown-linux-musl
aarch64-wrs-vxworks powerpc64-wrs-vxworks
arm-linux-androideabi powerpc64le-unknown-linux-gnu
arm-unknown-linux-gnueabi powerpc64le-unknown-linux-musl
arm-unknown-linux-gnueabihf riscv32i-unknown-none-elf
arm-unknown-linux-musleabi riscv32imac-unknown-none-elf
arm-unknown-linux-musleabihf riscv32imc-unknown-none-elf
armebv7r-none-eabi riscv64gc-unknown-linux-gnu
armebv7r-none-eabihf riscv64gc-unknown-none-elf
armv4t-unknown-linux-gnueabi riscv64imac-unknown-none-elf
armv5te-unknown-linux-gnueabi s390x-unknown-linux-gnu
armv5te-unknown-linux-musleabi sparc-unknown-linux-gnu
armv6-unknown-freebsd sparc64-unknown-linux-gnu
armv6-unknown-netbsd-eabihf sparc64-unknown-netbsd
armv7-linux-androideabi sparc64-unknown-openbsd
armv7-unknown-cloudabi-eabihf sparcv9-sun-solaris
armv7-unknown-freebsd thumbv6m-none-eabi
armv7-unknown-linux-gnueabi thumbv7a-pc-windows-msvc
armv7-unknown-linux-gnueabihf thumbv7em-none-eabi
armv7-unknown-linux-musleabi thumbv7em-none-eabihf
armv7-unknown-linux-musleabihf thumbv7m-none-eabi
armv7-unknown-netbsd-eabihf thumbv7neon-linux-androideabi
armv7-wrs-vxworks-eabihf thumbv7neon-unknown-linux-gnueabihf
armv7a-none-eabi thumbv7neon-unknown-linux-musleabihf
armv7a-none-eabihf thumbv8m.base-none-eabi
armv7r-none-eabi thumbv8m.main-none-eabi
armv7r-none-eabihf thumbv8m.main-none-eabihf
asmjs-unknown-emscripten wasm32-unknown-emscripten
hexagon-unknown-linux-musl wasm32-unknown-unknown
i586-pc-windows-msvc wasm32-wasi
i586-unknown-linux-gnu x86_64-apple-darwin
i586-unknown-linux-musl x86_64-fortanix-unknown-sgx
i686-apple-darwin x86_64-fuchsia
i686-linux-android x86_64-linux-android
i686-pc-windows-gnu x86_64-linux-kernel
i686-pc-windows-msvc x86_64-pc-solaris
i686-unknown-cloudabi x86_64-pc-windows-gnu
i686-unknown-freebsd x86_64-pc-windows-msvc
i686-unknown-haiku x86_64-rumprun-netbsd
i686-unknown-linux-gnu x86_64-sun-solaris
i686-unknown-linux-musl x86_64-unknown-cloudabi
i686-unknown-netbsd x86_64-unknown-dragonfly
i686-unknown-openbsd x86_64-unknown-freebsd
i686-unknown-uefi x86_64-unknown-haiku
i686-uwp-windows-gnu x86_64-unknown-hermit
i686-uwp-windows-msvc x86_64-unknown-hermit-kernel
i686-wrs-vxworks x86_64-unknown-illumos
mips-unknown-linux-gnu x86_64-unknown-l4re-uclibc
mips-unknown-linux-musl x86_64-unknown-linux-gnu
mips-unknown-linux-uclibc x86_64-unknown-linux-gnux32
mips64-unknown-linux-gnuabi64 x86_64-unknown-linux-musl
mips64-unknown-linux-muslabi64 x86_64-unknown-netbsd
mips64el-unknown-linux-gnuabi64 x86_64-unknown-openbsd
mips64el-unknown-linux-muslabi64 x86_64-unknown-redox
mipsel-unknown-linux-gnu x86_64-unknown-uefi
mipsel-unknown-linux-musl x86_64-uwp-windows-gnu
mipsel-unknown-linux-uclibc x86_64-uwp-windows-msvc
mipsisa32r6-unknown-linux-gnu x86_64-wrs-vxworks
次のコマンドを使うと、これらのターゲットのいずれか 1 つの仕様を表示できます:
$ rustc +nightly -Z unstable-options --print target-spec-json --target thumbv7m-none-eabi
{
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
],
"arch": "arm",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"emit-debug-gdb-scripts": false,
"env": "",
"executables": true,
"is-builtin": true,
"linker": "arm-none-eabi-gcc",
"linker-flavor": "gcc",
"llvm-target": "thumbv7m-none-eabi",
"max-atomic-width": 32,
"os": "none",
"panic-strategy": "abort",
"relocation-model": "static",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "32",
"vendor": ""
}
これらの組み込みターゲットのどれも自分のターゲットシステムに適していないようであれば、次のセクション で説明する JSON 形式の独自のターゲット仕様ファイルを作成して、カスタムターゲットを作る必要があります。
rust-std コンポーネント
一部の組み込みターゲットについては、Rust チームが rustup を通じて rust-std コンポーネントを配布しています。このコンポーネントは core や std のような事前コンパイル済みクレートの集合であり、クロスコンパイルに必要です。
次のコマンドを実行すると、rustup 経由で利用可能な rust-std コンポーネントを持つターゲットの一覧を確認できます:
``` console
$ rustup target list | column
aarch64-apple-ios mipsel-unknown-linux-musl
aarch64-fuchsia nvptx64-nvidia-cuda
aarch64-linux-android powerpc-unknown-linux-gnu
aarch64-pc-windows-msvc powerpc64-unknown-linux-gnu
aarch64-unknown-linux-gnu powerpc64le-unknown-linux-gnu
aarch64-unknown-linux-musl riscv32i-unknown-none-elf
aarch64-unknown-none riscv32imac-unknown-none-elf
aarch64-unknown-none-softfloat riscv32imc-unknown-none-elf
arm-linux-androideabi riscv64gc-unknown-linux-gnu
arm-unknown-linux-gnueabi riscv64gc-unknown-none-elf
arm-unknown-linux-gnueabihf riscv64imac-unknown-none-elf
arm-unknown-linux-musleabi s390x-unknown-linux-gnu
arm-unknown-linux-musleabihf sparc64-unknown-linux-gnu
armebv7r-none-eabi sparcv9-sun-solaris
armebv7r-none-eabihf thumbv6m-none-eabi
armv5te-unknown-linux-gnueabi thumbv7em-none-eabi
armv5te-unknown-linux-musleabi thumbv7em-none-eabihf
armv7-linux-androideabi thumbv7m-none-eabi
armv7-unknown-linux-gnueabi thumbv7neon-linux-androideabi
armv7-unknown-linux-gnueabihf thumbv7neon-unknown-linux-gnueabihf
armv7-unknown-linux-musleabi thumbv8m.base-none-eabi
armv7-unknown-linux-musleabihf thumbv8m.main-none-eabi
armv7a-none-eabi thumbv8m.main-none-eabihf
armv7r-none-eabi wasm32-unknown-emscripten
armv7r-none-eabihf wasm32-unknown-unknown
asmjs-unknown-emscripten wasm32-wasi
i586-pc-windows-msvc x86_64-apple-darwin
i586-unknown-linux-gnu x86_64-apple-ios
i586-unknown-linux-musl x86_64-fortanix-unknown-sgx
i686-linux-android x86_64-fuchsia
i686-pc-windows-gnu x86_64-linux-android
i686-pc-windows-msvc x86_64-pc-windows-gnu
i686-unknown-freebsd x86_64-pc-windows-msvc
i686-unknown-linux-gnu x86_64-rumprun-netbsd
i686-unknown-linux-musl x86_64-sun-solaris
mips-unknown-linux-gnu x86_64-unknown-cloudabi
mips-unknown-linux-musl x86_64-unknown-freebsd
mips64-unknown-linux-gnuabi64 x86_64-unknown-linux-gnu (default)
mips64-unknown-linux-muslabi64 x86_64-unknown-linux-gnux32
mips64el-unknown-linux-gnuabi64 x86_64-unknown-linux-musl
mips64el-unknown-linux-muslabi64 x86_64-unknown-netbsd
mipsel-unknown-linux-gnu x86_64-unknown-redox
ターゲット向けの rust-std コンポーネントがない場合、またはカスタムターゲットを使用している場合は、
標準ライブラリをビルドするために nightly ツールチェーンを使用する必要があります。カスタムターゲット向けのビルド
については次のページを参照してください。