새 타깃 추가하기
다음은 새 타깃에 대한 지원을 추가하는 일련의 단계입니다. 도달할 수 있는 최종 상태와 그에 이르는 경로가 다양하므로, 모든 절이 원하는 목표와 관련이 있지는 않을 수 있습니다.
타깃 등급 정책의 관련 문서도 참고하십시오.
새 LLVM 지정하기
아주 새로운 타깃의 경우, 현재 Rust와 함께 배포되는 것과는 다른 LLVM 포크를 사용해야 할 수도 있습니다. 이 경우 src/llvm-project git 서브모듈로 이동하여(서브모듈이 갱신되도록 ./x check를 적어도 한 번 실행해야 할 수도 있습니다) 사용하는 포크에 맞는 커밋을 체크아웃한 다음, 그 새 서브모듈 참조를 메인 Rust 저장소에 커밋하십시오.
예시는 다음과 같습니다.
cd src/llvm-project
git remote add my-target-llvm some-llvm-repository
git checkout my-target-llvm/my-branch
cd ..
git add llvm-project
git commit -m 'Use my custom LLVM'
미리 빌드된 LLVM 사용하기
이미 빌드된 로컬 LLVM 체크아웃이 있다면, 중복 빌드를 피하기 위해 해당 빌드를 시스템 LLVM으로 취급하도록 Rust를 설정할 수 있습니다.
bootstrap.toml의 target 섹션을 사용하여 Rust가 미리 빌드된 버전의 LLVM을 사용하도록 지정할 수 있습니다.
[target.x86_64-unknown-linux-gnu]
llvm-config = "/path/to/llvm/llvm-7.0.1/bin/llvm-config"
시스템 LLVM을 사용하려는 경우, 이전에 다음과 같은 경로가 확인된 적이 있습니다. 다만 여러분의 시스템에서는 다를 수 있습니다.
/usr/bin/llvm-config-8/usr/lib/llvm-8/bin/llvm-config
코드 생성 테스트에 사용되는 LLVM FileCheck 도구가 설치되어 있어야 한다는 점에 유의하십시오. 이 도구는 보통 LLVM과 함께 빌드되지만, 직접 미리 설치한 LLVM을 사용하는 경우에는 FileCheck를 다른 방법으로 제공해야 합니다. Debian 기반 시스템에서는 llvm-N-tools 패키지를 설치할 수 있습니다(N은 LLVM 버전 번호이며, 예를 들면 llvm-8-tools입니다). 또는 bootstrap.toml의 llvm-filecheck 설정 항목으로 FileCheck의 경로를 지정하거나, bootstrap.toml의 rust.codegen-tests 항목으로 코드 생성 테스트를 비활성화할 수 있습니다.
타깃 명세 만들기
먼저 타깃 JSON 파일부터 시작해야 합니다. --print target-spec-json을 사용하면 기존 타깃의 명세를 볼 수 있습니다.
rustc -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json
해당 JSON을 파일로 저장하고 여러분의 타깃에 맞게 적절히 수정하십시오.
타깃 명세 추가하기
JSON 명세를 작성하고 어느 정도 성공적으로 컴파일할 수 있게 되면, 그 명세를 컴파일러 자체에 복사해 넣을 수 있습니다.
rustc_target::spec 모듈에 있는 supported_targets 매크로 내부의 큰 테이블에 한 줄을 추가해야 합니다. 그런 다음 target 함수를 담은, 새 타깃에 대응하는 파일을 추가합니다.
예시로 삼을 만한 기존 타깃을 찾아보십시오.
부트스트랩에서 이 타깃을 사용하려면 src/bootstrap/src/core/sanity.rs의 STAGE0_MISSING_TARGETS 목록에 타깃 트리플을 명시적으로 추가해야 합니다. 기본 부트스트랩 컴파일러(일반적으로 베타 컴파일러)가 방금 추가한 새 타깃을 인식하지 못하기 때문에 이 작업이 필요합니다. 따라서 이 타깃이 아직 stage0 컴파일러에서 지원되지 않는다는 것을 부트스트랩이 알 수 있도록 STAGE0_MISSING_TARGETS에 추가해야 합니다.
const STAGE0_MISSING_TARGETS: &[&str] = &[
+ "NEW_TARGET_TRIPLE"
];
크레이트 패치하기
컴파일러가 의존하는 libc나 cc 같은 크레이트를 변경해야 할 수도 있습니다. 그런 경우 Cargo의 [patch] 기능을 사용할 수 있습니다. 예를 들어 아직 릴리스되지 않은 버전의 libc를 사용하려면 최상위 Cargo.toml 파일에 다음과 같이 추가하면 됩니다.
diff --git a/Cargo.toml b/Cargo.toml
index 1e83f05e0ca..4d0172071c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -113,6 +113,8 @@ cargo-util = { path = "src/tools/cargo/crates/cargo-util" }
[patch.crates-io]
+libc = { git = "https://github.com/rust-lang/libc", rev = "0bf7ce340699dcbacabdf5f16a242d2219a49ee0" }
# 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' }
그런 다음 cargo update -p libc를 실행하여 lockfile을 갱신하십시오.
로컬 path 의존성으로 패치하면 해당 의존성에 대한 경고가 활성화된다는 점에 주의하십시오. 일부 의존성은 경고가 없는 상태가 아니므로, bootstrap.toml의 rust.deny-warnings 설정 때문에 빌드가 갑자기 실패하기 시작할 수 있습니다. 경고를 해결하려면 다음과 같이 할 수 있습니다.
- 의존성을 수정하여 경고를 제거합니다
- 또는 로컬 개발 목적이라면 bootstrap.toml에서
rust.deny-warnings = false를 설정하여 경고를 억제합니다.
크로스 컴파일
JSON과 코드에 타깃 명세를 마련했다면 rustc를 크로스 컴파일할 수 있습니다.
DESTDIR=/path/to/install/in \
./x install -i --stage 1 --host aarch64-apple-darwin.json --target aarch64-apple-darwin \
compiler/rustc library/std
대상 명세가 부트스트랩 컴파일러에 이미 있다면, 두 인자 모두에 JSON 파일 대신 해당 명세를 사용할 수 있습니다.
타깃을 tier 2(타깃)에서 tier 2(호스트)로 승격하기
tier 2 타깃에는 두 가지 수준이 있습니다.
- 크로스 컴파일만 되는 타깃(
rustup target add) - 네이티브 툴체인이 있는 타깃(
rustup toolchain install)
크로스 컴파일 타깃을 네이티브 타깃으로 승격한 예시는 #75914를 참고하십시오.