Nguồn: blog.farre.se
Tóm tắt
Servo, browser engine viết bằng Rust được duy trì bởi Linux Foundation, sử dụng WebIDL (Web Interface Definition Language) để tự động sinh code binding giữa JavaScript và Rust. Quy trình code generation được thực hiện bởi một Python script, nhận đầu vào là các file .webidl và template, xuất ra Rust code. Vấn đề là script này không thể được cache bởi sccache hoặc bất kỳ build cache tool nào, khiến CI phải chạy lại từ đầu mỗi lần build.
Nguyên nhân gốc rễ được tìm ra: build script sử dụng directive rerun-if-changed = "." — một catch-all báo cho Cargo rằng bất kỳ file nào thay đổi cũng cần chạy lại script. Với directive này, Cargo không thể xác định được liệu output có còn hợp lệ hay không mà không chạy script, đồng nghĩa cache tool như sccache cũng không thể cache output.
Giải pháp là thay thế catch-all bằng cách khai báo tường minh tất cả input và output: enumerate từng file .webidl, template, config file, và file Rust được sinh ra, sau đó in các rerun-if-changed directive tương ứng ra stdout. Khi inputs không thay đổi, Cargo skip build script hoàn toàn; sccache cache được outputs.
Kết quả: CI build time giảm từ ~15 phút xuống ~10 phút — cắt giảm 33%. Bài học tổng quát: với Rust project có build script phức tạp, đầu tư khai báo rõ ràng inputs/outputs có thể mang lại cải thiện đáng kể mà không cần thay đổi logic build.