Redesigning the Initial Bootstrap Sequence
Bài tóm tắt Rust (Rust Foundation) 2025 4. Điều chỉnh Độ khó: Khó
Rust · 2025 · 4. Điều chỉnh · Độ khó: Khó — bài gốc
Bối cảnh
- Bootstrap là dựng compiler mới bằng compiler cũ của chính nó, qua các stage: compiler stage N được dựng từ compiler stage N−1 và các artifact của stage đó. Stage 0 là compiler ban đầu, với hầu hết người đóng góp là bản beta tải về.
- Compiler (
rustc) và thư viện chuẩn (std) của Rust gắn chặt qua intrinsic và lang item: đổi một bên là phải đổi bên kia. Khác GCC hay Clang (dùng std dựng sẵn của hệ thống ở mọi stage), Rust dựng std từ mã nguồn trong cây. - Trình tự cũ: để dựng rustc stage 1 thì phải dựng std stage 0 từ mã nguồn trong cây bằng compiler beta (bật
cfg(bootstrap)); để dựng rustc stage 2 thì dựng std stage 1 từ cùng mã nguồn đó bằng compiler trong cây (tắtcfg(bootstrap)). Tức là std phải dựng được bằng hai phiên bản compiler, nên mọi thay đổi intrinsic hay lang item phải bọccfg(bootstrap), gây nhiều xáo trộn nhất là lúc ra bản mới. Theo Rust, lý do lựa chọn này chủ yếu là lịch sử (thời std đổi nhanh và compiler chưa dùng được crate từ crates.io), không còn ghi chép rõ.
Thay đổi chính
- Trình tự mới: tải về cả rustc beta lẫn std beta dựng sẵn làm stage 0; rustc stage 1 dựng bằng chúng; std stage 1 dựng từ mã nguồn trong cây bằng rustc stage 1. std chỉ còn phải dựng được bằng một compiler (compiler cùng stage).
- Lợi ích, theo Rust:
- Bỏ
cfg(bootstrap)cho intrinsic và lang item trong std. - Rebase không còn phải dựng lại tất cả: std giờ dựng sau compiler chứ không trước, nên các crate compiler và dependency không đổi được cache khi chuyển nhánh git; chỉ phải dựng lại hết khi bump bootstrap mỗi 6 tuần theo chu kỳ phát hành.
- Sửa std (ví dụ chỉ thêm doc comment) không còn kéo theo dựng lại compiler rồi dựng std lần nữa.
- Giống cách mọi chương trình Rust khác được dựng (compiler beta + std beta), hết cảnh stage 1 dựng từ rustc beta với std trong cây.
- Bỏ
- Đổi với người đóng góp: stage tối thiểu để check/build/test thư viện thành 1 (
--stage 0cho library thành no-op); profilelibrarybật mặc địnhdownload-rustc = "if-unchanged"để tải rustc dựng sẵn từ CI khi không đổi compiler.cfg(bootstrap)dời sang compiler nhưng hiếm, chỉ khi compiler muốn dùng tính năng thư viện unstable mới. - Người đóng gói bản phân phối không bị ảnh hưởng: vẫn dựng N+1 bằng N.
Vì sao
- Ràng buộc "dựng được bằng hai compiler" đặt lên phía hay thay đổi nhiều nhất (std phải theo mọi thay đổi intrinsic), trong khi compiler hiếm khi cần API thư viện mới; dời ràng buộc sang phía ít thay đổi thì giảm xáo trộn.
Bài học cho SWE
- Thứ tự dựng quyết định cái gì cache được: đặt phần hay đổi ở cuối chuỗi phụ thuộc để phần ổn định phía trước được dùng lại.
- Ràng buộc tương thích hai phiên bản nên đặt ở phía ít thay đổi; ghi lại lý do của ràng buộc, vì sau nhiều năm không ai còn nhớ.
- Tải artifact đã dựng sẵn khi phần đó không đổi (
download-rustc) là một dạng remote cache theo đơn vị lớn.
Liên quan
- CI và build ở quy mô lớn
- Cùng dự án: Rust 2020 · Rust 2026
- Cùng bài toán: Mercari 2026 · SoundCloud 2019
#Bootstrapping#rustc#stage 0#standard library#cfg(bootstrap)#intrinsics#lang items#beta toolchain#build cache#rebase#x.py
Được nhắc tới trong
Chủ đề (1)
Công ty (1)
Bài tóm tắt (1)