หน้านี้จะกล่าวถึงวิธีสร้างโปรแกรมด้วย Bazel, ไวยากรณ์คำสั่งบิลด์ และ ไวยากรณ์รูปแบบเป้าหมาย
คู่มือเริ่มใช้งานฉบับย่อ
หากต้องการเรียกใช้ Bazel ให้ไปที่ไดเรกทอรีพื้นที่ทำงานพื้นฐาน
หรือไดเรกทอรีย่อยใดก็ได้ แล้วพิมพ์ bazel
ดูสร้างหากต้องการสร้างพื้นที่ทำงานใหม่
bazel help
[Bazel release bazel version]
Usage: bazel command options ...
คำสั่งที่ใช้ได้
analyze-profile
: วิเคราะห์ข้อมูลโปรไฟล์การสร้างaquery
: เรียกใช้การค้นหาในกราฟการดำเนินการหลังการวิเคราะห์build
: สร้างเป้าหมายที่ระบุcanonicalize-flags
: กำหนดรูปแบบแฟล็ก Bazelclean
: นำไฟล์เอาต์พุตออกและหยุดเซิร์ฟเวอร์ (ไม่บังคับ)cquery
: เรียกใช้การค้นหากราฟการขึ้นต่อกันหลังการวิเคราะห์dump
: ทิ้งสถานะภายในของกระบวนการเซิร์ฟเวอร์ Bazelhelp
: พิมพ์ความช่วยเหลือสำหรับคำสั่งหรือดัชนีinfo
: แสดงข้อมูลรันไทม์เกี่ยวกับเซิร์ฟเวอร์ Bazelfetch
: ดึงข้อมูลการอ้างอิงภายนอกทั้งหมดของเป้าหมายmobile-install
: ติดตั้งแอปในอุปกรณ์เคลื่อนที่query
: เรียกใช้การค้นหากราฟทรัพยากร Dependencyrun
: เรียกใช้เป้าหมายที่ระบุshutdown
: หยุดเซิร์ฟเวอร์ Bazeltest
: สร้างและเรียกใช้เป้าหมายการทดสอบที่ระบุversion
: พิมพ์ข้อมูลเวอร์ชันสำหรับ Bazel
การขอความช่วยเหลือ
bazel help command
: ความช่วยเหลือและตัวเลือกในการพิมพ์สำหรับcommand
bazel help
startup_options
: ตัวเลือกสำหรับการโฮสต์ JVM ของ Bazelbazel help
target-syntax
: อธิบายไวยากรณ์สำหรับการระบุเป้าหมายbazel help info-keys
: แสดงรายการคีย์ที่ใช้โดยคำสั่ง info
bazel
มีฟังก์ชันมากมายที่เรียกว่าคำสั่ง โดยที่ใช้กันมากที่สุดคือ bazel build
และ bazel test
คุณเรียกดูข้อความความช่วยเหลือออนไลน์
ได้โดยใช้ bazel help
การสร้างเป้าหมายเดียว
คุณต้องมีพื้นที่ทำงานก่อนจึงจะเริ่มบิลด์ได้ พื้นที่ทำงานคือ โครงสร้างไดเรกทอรีที่มีไฟล์ต้นฉบับทั้งหมดที่จำเป็นต่อการสร้าง แอปพลิเคชัน Bazel ช่วยให้คุณทำการบิลด์จากวอลุ่มแบบอ่านอย่างเดียวได้
หากต้องการสร้างโปรแกรมด้วย Bazel ให้พิมพ์ bazel build
ตามด้วยเป้าหมายที่ต้องการสร้าง
bazel build //foo
หลังจากออกคำสั่งเพื่อสร้าง //foo
แล้ว คุณจะเห็นเอาต์พุตที่คล้ายกับเอาต์พุตนี้
INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
bazel-bin/foo/foo
INFO: Elapsed time: 9.905s, Critical Path: 3.25s
INFO: Build completed successfully, 6 total actions
ก่อนอื่น Bazel จะโหลดแพ็กเกจทั้งหมดในกราฟการขึ้นต่อกันของเป้าหมาย ซึ่งรวมถึงทรัพยากร Dependency ที่ประกาศไว้ ไฟล์ที่แสดงโดยตรงในไฟล์ BUILD
ของเป้าหมาย และทรัพยากร Dependency แบบทรานซิทีฟ ไฟล์ที่แสดงในไฟล์ BUILD
ของทรัพยากร Dependency ของเป้าหมาย
หลังจากระบุทรัพยากร Dependency ทั้งหมดแล้ว Bazel จะวิเคราะห์
ทรัพยากรเหล่านั้นเพื่อตรวจสอบความถูกต้องและสร้างการดำเนินการบิลด์ สุดท้าย Bazel จะเรียกใช้
คอมไพเลอร์และเครื่องมืออื่นๆ ของการสร้าง
ในระหว่างขั้นตอนการดำเนินการของบิลด์ Bazel จะพิมพ์ข้อความความคืบหน้า ข้อความความคืบหน้า ประกอบด้วยขั้นตอนการสร้างปัจจุบัน (เช่น คอมไพเลอร์หรือลิงเกอร์) เมื่อเริ่มต้น และจำนวนที่เสร็จสมบูรณ์จากจำนวนการดำเนินการสร้างทั้งหมด เมื่อการสร้างเริ่มต้นขึ้น จำนวนการดำเนินการทั้งหมดมักจะเพิ่มขึ้นเมื่อ Bazel ค้นพบกราฟการดำเนินการทั้งหมด แต่จำนวนจะคงที่ภายในไม่กี่วินาที
เมื่อสิ้นสุดการสร้าง Bazel จะพิมพ์เป้าหมายที่ขอ ไม่ว่าจะสร้างสำเร็จหรือไม่ก็ตาม และหากสร้างสำเร็จ ก็จะพิมพ์ตำแหน่งของไฟล์เอาต์พุต สคริปต์ที่เรียกใช้บิลด์จะแยกวิเคราะห์เอาต์พุตนี้ได้อย่างน่าเชื่อถือ ดูรายละเอียดเพิ่มเติมได้ที่
--show_result
หากคุณพิมพ์คำสั่งเดิมอีกครั้ง การสร้างจะเสร็จเร็วขึ้นมาก
bazel build //foo
INFO: Analyzed target //foo:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
bazel-bin/foo/foo
INFO: Elapsed time: 0.144s, Critical Path: 0.00s
INFO: Build completed successfully, 1 total action
นี่คือบิลด์เปล่า เนื่องจากไม่มีการเปลี่ยนแปลงใดๆ จึงไม่มีแพ็กเกจที่จะโหลดซ้ำ และไม่มีขั้นตอนการบิลด์ที่จะดำเนินการ หากมีการเปลี่ยนแปลงใน "foo" หรือ การอ้างอิงของ "foo" Bazel จะเรียกใช้การดำเนินการบิลด์บางอย่างอีกครั้ง หรือทำบิลด์ที่เพิ่มขึ้นให้เสร็จสมบูรณ์
สร้างเป้าหมายหลายรายการ
Bazel มีหลายวิธีในการระบุเป้าหมายที่จะสร้าง โดยรวมแล้ว
สิ่งเหล่านี้เรียกว่ารูปแบบเป้าหมาย ไวยากรณ์นี้ใช้ในคำสั่ง เช่น build
, test
หรือ query
ในขณะที่ป้ายกำกับใช้เพื่อระบุเป้าหมายแต่ละรายการ เช่น เพื่อประกาศการขึ้นต่อกันในไฟล์ BUILD
รูปแบบเป้าหมายของ Bazel จะระบุเป้าหมายหลายรายการ รูปแบบเป้าหมายเป็นการสรุปไวยากรณ์ป้ายกำกับสำหรับชุดเป้าหมายโดยใช้ไวลด์การ์ด ในกรณีที่ง่ายที่สุด ป้ายกำกับที่ถูกต้องจะถือเป็นรูปแบบเป้าหมายที่ถูกต้องด้วย ซึ่งจะระบุชุดเป้าหมายที่ตรงกัน 1 รายการ
รูปแบบเป้าหมายทั้งหมดที่ขึ้นต้นด้วย //
จะได้รับการแก้ไขโดยอิงตามเวิร์กสเปซปัจจุบัน
//foo/bar:wiz |
เพียงเป้าหมายเดียว //foo/bar:wiz |
//foo/bar |
เทียบเท่ากับ //foo/bar:bar |
//foo/bar:all |
เป้าหมายกฎทั้งหมดในแพ็กเกจ foo/bar |
//foo/... |
เป้าหมายกฎทั้งหมดในแพ็กเกจทั้งหมดภายใต้ไดเรกทอรี foo |
//foo/...:all |
เป้าหมายกฎทั้งหมดในแพ็กเกจทั้งหมดภายใต้ไดเรกทอรี foo |
//foo/...:* |
เป้าหมายทั้งหมด (กฎและไฟล์) ในแพ็กเกจทั้งหมดภายใต้ไดเรกทอรี foo |
//foo/...:all-targets |
เป้าหมายทั้งหมด (กฎและไฟล์) ในแพ็กเกจทั้งหมดภายใต้ไดเรกทอรี foo |
//... |
เป้าหมายกฎทั้งหมดในแพ็กเกจในที่เก็บข้อมูลหลัก ไม่รวมเป้าหมายจากที่เก็บภายนอก |
//:all |
เป้าหมายของกฎทั้งหมดในแพ็กเกจระดับบนสุด หากมีไฟล์ `BUILD` ที่ รูทของพื้นที่ทำงาน |
ระบบจะแก้ไขรูปแบบเป้าหมายที่ไม่ได้ขึ้นต้นด้วย //
โดยอิงตามไดเรกทอรีการทำงานปัจจุบัน ตัวอย่างเหล่านี้ถือว่าไดเรกทอรีการทำงานคือ foo
:foo |
เทียบเท่ากับ //foo:foo |
bar:wiz |
เทียบเท่ากับ //foo/bar:wiz |
bar/wiz |
เทียบเท่ากับ
|
bar:all |
เทียบเท่ากับ //foo/bar:all |
:all |
เทียบเท่ากับ //foo:all |
...:all |
เทียบเท่ากับ //foo/...:all |
... |
เทียบเท่ากับ //foo/...:all |
bar/...:all |
เทียบเท่ากับ //foo/bar/...:all |
โดยค่าเริ่มต้น ระบบจะติดตามลิงก์สัญลักษณ์ของไดเรกทอรีสำหรับรูปแบบเป้าหมายแบบเรียกซ้ำ ยกเว้นลิงก์ที่ชี้ไปยังไดเรกทอรีฐานเอาต์พุต เช่น ลิงก์สัญลักษณ์ที่สร้างขึ้นในไดเรกทอรีรูทของพื้นที่ทำงาน
นอกจากนี้ Bazel จะไม่ติดตามลิงก์สัญลักษณ์เมื่อประเมินรูปแบบเป้าหมายแบบเรียกซ้ำในไดเรกทอรีที่มีไฟล์ชื่อต่อไปนี้
DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN
foo/...
เป็นไวลด์การ์ดเหนือ packages ซึ่งระบุแพ็กเกจทั้งหมดแบบเรียกซ้ำ
ใต้ไดเรกทอรี foo
(สำหรับรูททั้งหมดของเส้นทางแพ็กเกจ) :all
คือ
อักขระไวด์การ์ดในเป้าหมาย ซึ่งจะจับคู่กฎทั้งหมดภายในแพ็กเกจ คุณอาจรวมทั้ง 2 อย่างเข้าด้วยกัน เช่น foo/...:all
และเมื่อใช้ไวลด์การ์ดทั้ง 2 แบบ คุณอาจย่อเป็น foo/...
ได้
นอกจากนี้ :*
(หรือ :all-targets
) ยังเป็นไวลด์การ์ดที่ตรงกับทุกเป้าหมาย
ในแพ็กเกจที่ตรงกัน รวมถึงไฟล์ที่ปกติแล้วไม่มีกฎใดสร้างขึ้น
เช่น ไฟล์ _deploy.jar
ที่เชื่อมโยงกับกฎ java_binary
ซึ่งหมายความว่า :*
แสดงถึงซูเปอร์เซ็ตของ :all
แม้ว่าไวยากรณ์นี้อาจทำให้สับสน แต่ก็อนุญาตให้ใช้ไวลด์การ์ด :all
ที่คุ้นเคยสำหรับการสร้างทั่วไป ซึ่งไม่ต้องการเป้าหมายการสร้าง เช่น _deploy.jar
นอกจากนี้ Bazel ยังอนุญาตให้ใช้เครื่องหมายทับแทนเครื่องหมายโคลอนที่ไวยากรณ์ของป้ายกำกับกำหนด ซึ่งมักจะสะดวกเมื่อใช้การขยายชื่อไฟล์ของ Bash
เช่น foo/bar/wiz
มีค่าเท่ากับ //foo/bar:wiz
(หากมีแพ็กเกจ foo/bar
) หรือเท่ากับ //foo:bar/wiz
(หากมีแพ็กเกจ foo
)
คำสั่ง Bazel หลายคำสั่งยอมรับรายการรูปแบบเป้าหมายเป็นอาร์กิวเมนต์ และคำสั่งทั้งหมดจะ
ใช้โอเปอเรเตอร์การปฏิเสธคำนำหน้า -
ใช้เพื่อลบชุดเป้าหมายออกจากชุดที่ระบุโดยอาร์กิวเมนต์ก่อนหน้าได้ โปรดทราบว่าการดำเนินการนี้หมายความว่า
ลำดับมีความสำคัญ ตัวอย่างเช่น
bazel build foo/... bar/...
หมายถึง "สร้างเป้าหมายทั้งหมดภายใต้ foo
และเป้าหมายทั้งหมดภายใต้ bar
" ในขณะที่
bazel build -- foo/... -foo/bar/...
หมายถึง "สร้างเป้าหมายทั้งหมดภายใต้ foo
ยกเว้นเป้าหมายที่อยู่ภายใต้ foo/bar
" (ต้องระบุอาร์กิวเมนต์ --
เพื่อป้องกันไม่ให้ระบบตีความอาร์กิวเมนต์ที่ตามมาซึ่งเริ่มต้นด้วย -
เป็นตัวเลือกเพิ่มเติม)
อย่างไรก็ตาม การลบเป้าหมายด้วยวิธีนี้จะไม่รับประกันว่าระบบจะไม่สร้างเป้าหมาย เนื่องจากเป้าหมายอาจเป็นทรัพยากร Dependency ของเป้าหมายที่ไม่ได้ลบ เช่น หากมีเป้าหมาย //foo:all-apis
ซึ่งขึ้นอยู่กับ //foo/bar:api
และเป้าหมายอื่นๆ ระบบจะสร้างเป้าหมายหลังเป็น
ส่วนหนึ่งของการสร้างเป้าหมายแรก
เป้าหมายที่มี tags = ["manual"]
จะไม่รวมอยู่ในรูปแบบเป้าหมายแบบไวลด์การ์ด
(...
, :*
, :all
ฯลฯ) เมื่อระบุในคำสั่ง เช่น
bazel build
และ bazel test
(แต่จะรวมอยู่ใน
รูปแบบเป้าหมายแบบไวลด์การ์ดเชิงลบ ซึ่งหมายความว่าจะมีการลบออก) คุณควร
ระบุเป้าหมายการทดสอบดังกล่าวด้วยรูปแบบเป้าหมายที่ชัดเจนในบรรทัดคำสั่ง หาก
ต้องการให้ Bazel สร้าง/ทดสอบเป้าหมายเหล่านั้น ในทางตรงกันข้าม bazel query
จะไม่ทำการกรองดังกล่าวโดยอัตโนมัติ (ซึ่งจะขัดต่อวัตถุประสงค์ของ bazel query
)
กำลังดึงข้อมูลทรัพยากร Dependency ภายนอก
โดยค่าเริ่มต้น Bazel จะดาวน์โหลดและ Symlink การอ้างอิงภายนอกในระหว่าง
การสร้าง อย่างไรก็ตาม คุณอาจไม่ต้องการให้เป็นเช่นนี้ ไม่ว่าจะเป็นเพราะคุณต้องการทราบ
เมื่อมีการเพิ่มการอ้างอิงภายนอกใหม่ หรือเพราะคุณต้องการ
"โหลดล่วงหน้า" การอ้างอิง (เช่น ก่อนขึ้นเครื่องบินที่คุณจะออฟไลน์) หากต้องการป้องกันไม่ให้มีการเพิ่มการอ้างอิงใหม่ระหว่างการสร้าง คุณสามารถระบุแฟล็ก --fetch=false
ได้ โปรดทราบว่าแฟล็กนี้ใช้ได้กับกฎของที่เก็บที่ไม่ได้ชี้ไปยังไดเรกทอรีในระบบไฟล์ในเครื่องเท่านั้น
การเปลี่ยนแปลง เช่น local_repository
,
new_local_repository
และกฎของที่เก็บ Android SDK และ NDK
จะมีผลเสมอไม่ว่าค่า --fetch
จะเป็นอะไรก็ตาม
หากคุณไม่อนุญาตให้ดึงข้อมูลในระหว่างการสร้างและ Bazel พบการอ้างอิงภายนอกใหม่ การสร้างจะล้มเหลว
คุณดึงข้อมูลการอ้างอิงด้วยตนเองได้โดยเรียกใช้ bazel fetch
หากคุณไม่อนุญาตการดึงข้อมูลระหว่างการสร้าง คุณจะต้องเรียกใช้ bazel fetch
- ก่อนที่จะสร้างเป็นครั้งแรก
- หลังจากเพิ่มการอ้างอิงภายนอกใหม่
เมื่อเรียกใช้แล้ว คุณไม่จำเป็นต้องเรียกใช้อีกจนกว่าไฟล์ MODULE.bazel จะมีการเปลี่ยนแปลง
fetch
รับรายการเป้าหมายเพื่อดึงข้อมูลการอ้างอิง ตัวอย่างเช่น คำสั่งนี้จะดึงข้อมูลการพึ่งพาที่จำเป็นต่อการสร้าง //foo:bar
และ //bar:baz
bazel fetch //foo:bar //bar:baz
หากต้องการดึงข้อมูลการอ้างอิงภายนอกทั้งหมดสำหรับพื้นที่ทำงาน ให้เรียกใช้คำสั่งต่อไปนี้
bazel fetch //...
หากใช้ Bazel 7 ขึ้นไปและเปิดใช้ Bzlmod คุณจะดึงข้อมูลการอ้างอิงภายนอกทั้งหมดได้โดยเรียกใช้
bazel fetch
คุณไม่จำเป็นต้องเรียกใช้ bazel fetch เลยหากมีเครื่องมือทั้งหมดที่ใช้ (ตั้งแต่ JAR ของไลบรารีไปจนถึง JDK เอง) อยู่ภายใต้รูทของพื้นที่ทำงาน
อย่างไรก็ตาม หากคุณใช้สิ่งอื่นนอกเหนือจากไดเรกทอรีพื้นที่ทำงาน Bazel
จะเรียกใช้ bazel fetch
โดยอัตโนมัติก่อนเรียกใช้
bazel build
แคชที่เก็บ
Bazel พยายามหลีกเลี่ยงการดึงข้อมูลไฟล์เดียวกันหลายครั้ง แม้ว่าจะต้องใช้ไฟล์เดียวกันในพื้นที่ทำงานที่แตกต่างกัน หรือหากคำจำกัดความของที่เก็บภายนอกมีการเปลี่ยนแปลง แต่ยังคงต้องดาวน์โหลดไฟล์เดียวกัน โดย Bazel จะแคชไฟล์ทั้งหมดที่ดาวน์โหลดในแคชที่เก็บ ซึ่งโดยค่าเริ่มต้น
จะอยู่ที่ ~/.cache/bazel/_bazel_$USER/cache/repos/v1/
โดยเปลี่ยนตำแหน่งได้โดยใช้ตัวเลือก --repository_cache
แคชจะแชร์ระหว่างพื้นที่ทำงานทั้งหมดและ Bazel เวอร์ชันที่ติดตั้ง
ระบบจะนำรายการจากแคชมาใช้ในกรณีที่
Bazel ทราบอย่างแน่นอนว่ามีสำเนาของไฟล์ที่ถูกต้อง นั่นคือ หาก
คำขอดาวน์โหลดมีผลรวม SHA256 ของไฟล์ที่ระบุ และมีไฟล์ที่มีแฮชดังกล่าว
อยู่ในแคช ดังนั้นการระบุแฮชสำหรับไฟล์ภายนอกแต่ละไฟล์จึง
ไม่เพียงแต่เป็นแนวคิดที่ดีในมุมมองด้านความปลอดภัย แต่ยังช่วยหลีกเลี่ยง
การดาวน์โหลดที่ไม่จำเป็นด้วย
เมื่อแคชทำงานแต่ละครั้ง ระบบจะอัปเดตเวลาแก้ไขของไฟล์ในแคช ด้วยวิธีนี้ คุณจะกำหนดการใช้งานไฟล์ล่าสุดในไดเรกทอรีแคชได้อย่างง่ายดาย เช่น เพื่อล้างแคชด้วยตนเอง ระบบจะไม่ล้างแคชโดยอัตโนมัติ เนื่องจากแคชอาจมีสำเนาของไฟล์ที่ไม่มี ให้ใช้งานในต้นทางอีกต่อไป
[เลิกใช้งานแล้ว] ไดเรกทอรีไฟล์การจัดจำหน่าย
เลิกใช้งานแล้ว: ขอแนะนำให้ใช้แคชของที่เก็บเพื่อสร้างแบบออฟไลน์
ไดเรกทอรีการจัดจำหน่ายเป็นอีกกลไกหนึ่งของ Bazel ที่ช่วยหลีกเลี่ยงการดาวน์โหลดที่ไม่จำเป็น Bazel จะค้นหาไดเรกทอรีการจัดจำหน่ายก่อนแคชที่เก็บ ความแตกต่างหลักคือไดเรกทอรีการเผยแพร่ต้องมีการเตรียมการด้วยตนเอง
การใช้ตัวเลือก
--distdir=/path/to-directory
จะช่วยให้คุณระบุไดเรกทอรีแบบอ่านอย่างเดียวเพิ่มเติมเพื่อค้นหาไฟล์
แทนการดึงข้อมูลได้ ระบบจะนำไฟล์จากไดเรกทอรีดังกล่าวมาใช้หากชื่อไฟล์
เท่ากับชื่อฐานของ URL และแฮชของไฟล์
เท่ากับแฮชที่ระบุไว้ในคำขอดาวน์โหลด ซึ่งจะใช้ได้ก็ต่อเมื่อมีการระบุแฮชของไฟล์ในการประกาศกฎของที่เก็บ
แม้ว่าการกำหนดเงื่อนไขในชื่อไฟล์จะไม่จำเป็นต่อความถูกต้อง แต่จะช่วยลดจำนวนไฟล์ที่อาจเป็นไฟล์ที่ถูกต้องให้เหลือเพียงไฟล์เดียวต่อไดเรกทอรีที่ระบุ ด้วยวิธีนี้ การระบุไดเรกทอรีไฟล์การจัดจำหน่ายจึงยังคงมีประสิทธิภาพ แม้ว่าจำนวนไฟล์ในไดเรกทอรีดังกล่าวจะเพิ่มขึ้นก็ตาม
การเรียกใช้ Bazel ในสภาพแวดล้อมที่แยกจากเครือข่ายภายนอก
Bazel จะดึงข้อมูลการอ้างอิงโดยนัยผ่านเครือข่ายขณะเรียกใช้เป็นครั้งแรกเพื่อรักษาขนาดไบนารีของ Bazel ให้มีขนาดเล็ก การขึ้นต่อกันโดยนัยเหล่านี้ มี Toolchain และกฎที่อาจไม่จำเป็นสำหรับทุกคน ตัวอย่างเช่น เครื่องมือ Android จะแยกออกและดึงข้อมูลเมื่อสร้างโปรเจ็กต์ Android เท่านั้น
อย่างไรก็ตาม การอ้างอิงโดยนัยเหล่านี้อาจทำให้เกิดปัญหาเมื่อเรียกใช้ Bazel ใน สภาพแวดล้อมที่แยกจากเครือข่ายภายนอก แม้ว่าคุณจะจัดเก็บการอ้างอิงภายนอกทั้งหมดไว้แล้วก็ตาม หากต้องการแก้ไขปัญหานี้ คุณสามารถเตรียมแคชที่เก็บ (ด้วย Bazel 7 ขึ้นไป) หรือไดเรกทอรีการจัดจำหน่าย (ด้วย Bazel ก่อนเวอร์ชัน 7) ที่มีทรัพยากร Dependency เหล่านี้ในเครื่องที่มีสิทธิ์เข้าถึงเครือข่าย จากนั้นโอนไปยังสภาพแวดล้อมที่แยกจากเครือข่ายอินเทอร์เน็ตด้วยวิธีแบบออฟไลน์
แคชที่เก็บ (ด้วย Bazel 7 ขึ้นไป)
หากต้องการเตรียมแคชของที่เก็บ ให้ใช้
--repository_cache
แฟล็ก คุณจะต้องดำเนินการนี้ 1 ครั้งสำหรับไบนารี Bazel เวอร์ชันใหม่ทุกเวอร์ชัน เนื่องจาก
การอ้างอิงโดยนัยอาจแตกต่างกันในแต่ละรุ่น
หากต้องการดึงข้อมูลการอ้างอิงเหล่านั้นนอกสภาพแวดล้อมที่แยกจากเครือข่ายภายนอก ให้สร้างพื้นที่ทำงานว่างก่อนโดยทำดังนี้
mkdir empty_workspace && cd empty_workspace
touch MODULE.bazel
หากต้องการดึงข้อมูลทรัพยากร Dependency ของ Bzlmod ในตัว ให้เรียกใช้คำสั่งต่อไปนี้
bazel fetch --repository_cache="path/to/repository/cache"
หากยังคงใช้ไฟล์ WORKSPACE เดิมอยู่ ให้เรียกข้อมูลทรัพยากร Dependency ของ WORKSPACE ที่มีอยู่แล้วโดยเรียกใช้
bazel sync --repository_cache="path/to/repository/cache"
สุดท้ายนี้ เมื่อใช้ Bazel ในสภาพแวดล้อมที่แยกจากเครือข่ายภายนอก ให้ส่งแฟล็ก --repository_cache
เดียวกัน คุณสามารถเพิ่มเป็น.bazelrc
รายการเพื่อความสะดวกได้โดยทำดังนี้
common --repository_cache="path/to/repository/cache"
นอกจากนี้ คุณอาจต้องโคลน BCR ในเครื่องและใช้แฟล็ก
--registry
เพื่อชี้สำเนาในเครื่องเพื่อป้องกันไม่ให้ Bazel เข้าถึง BCR ผ่านอินเทอร์เน็ต เพิ่มบรรทัดต่อไปนี้ใน .bazelrc
common --registry="path/to/local/bcr/registry"
ไดเรกทอรีการจัดจำหน่าย (ใช้ Bazel ก่อนเวอร์ชัน 7)
หากต้องการเตรียมไดเรกทอรีการจัดจำหน่าย ให้ใช้แฟล็ก
--distdir
คุณจะต้องดำเนินการนี้ 1 ครั้งสำหรับไบนารี Bazel เวอร์ชันใหม่ทุกเวอร์ชัน เนื่องจาก
การอ้างอิงโดยนัยอาจแตกต่างกันในแต่ละรุ่น
หากต้องการสร้างทรัพยากร Dependency เหล่านี้ภายนอกสภาพแวดล้อมที่แยกจากอินเทอร์เน็ต ให้ ตรวจสอบซอร์สทรีของ Bazel ในเวอร์ชันที่ถูกต้องก่อน
git clone https://github.com/bazelbuild/bazel "$BAZEL_DIR"
cd "$BAZEL_DIR"
git checkout "$BAZEL_VERSION"
จากนั้นสร้างไฟล์ tarball ที่มีทรัพยากร Dependency ของรันไทม์โดยนัยสำหรับ Bazel เวอร์ชันนั้น โดยเฉพาะ
bazel build @additional_distfiles//:archives.tar
ส่งออกไฟล์ tarball นี้ไปยังไดเรกทอรีที่คัดลอกไปยังสภาพแวดล้อมที่แยกจากเครือข่ายภายนอกได้ โปรดสังเกต--strip-components
เนื่องจาก --distdir
อาจ
ค่อนข้างละเอียดอ่อนกับระดับการซ้อนไดเรกทอรี
tar xvf bazel-bin/external/additional_distfiles/archives.tar \
-C "$NEW_DIRECTORY" --strip-components=3
สุดท้าย เมื่อใช้ Bazel ในสภาพแวดล้อมที่แยกจากอินเทอร์เน็ต ให้ส่งแฟล็ก --distdir
ที่ชี้ไปยังไดเรกทอรี คุณสามารถเพิ่มเป็น.bazelrc
รายการเพื่อความสะดวกได้โดยทำดังนี้
build --distdir=path/to/directory
การกำหนดค่าบิวด์และการคอมไพล์ข้าม
อินพุตทั้งหมดที่ระบุลักษณะการทำงานและผลลัพธ์ของการบิลด์ที่กำหนดสามารถแบ่งออกเป็น 2 หมวดหมู่ที่แตกต่างกันได้
ข้อมูลประเภทแรกคือข้อมูลโดยธรรมชาติ
ที่จัดเก็บไว้ในไฟล์ BUILD
ของโปรเจ็กต์ ได้แก่ กฎการสร้าง ค่าของแอตทริบิวต์ และชุดการอ้างอิงแบบทรานซิทีฟทั้งหมด
ข้อมูลประเภทที่ 2 คือข้อมูลภายนอกหรือข้อมูลสภาพแวดล้อม ซึ่งผู้ใช้หรือเครื่องมือบิลด์เป็นผู้จัดหาให้ ได้แก่ ตัวเลือกสถาปัตยกรรมเป้าหมาย ตัวเลือกการคอมไพล์และการลิงก์ และตัวเลือกการกำหนดค่า Toolchain อื่นๆ เราเรียกชุดข้อมูลด้านสิ่งแวดล้อมที่สมบูรณ์ว่าการกำหนดค่า
ในการสร้างแต่ละครั้ง อาจมีการกำหนดค่ามากกว่า 1 รายการ ลองพิจารณา
การคอมไพล์ข้าม ซึ่งคุณสร้าง//foo:bin
ไฟล์ที่เรียกใช้งานได้สำหรับสถาปัตยกรรม 64 บิต
แต่เวิร์กสเตชันเป็นเครื่อง 32 บิต เห็นได้ชัดว่าการสร้างจะต้อง//foo:bin
ใช้เครื่องมือที่สามารถสร้างไฟล์ที่เรียกใช้งานได้แบบ 64 บิต
แต่ระบบบิลด์จะต้องสร้างเครื่องมือต่างๆ ที่ใช้ในระหว่างการบิลด์ด้วย เช่น เครื่องมือที่สร้างจากแหล่งที่มา แล้วนำไปใช้ใน genrule เป็นต้น และเครื่องมือเหล่านี้จะต้องสร้างให้ทำงานบนเวิร์กสเตชันได้ ดังนั้น
เราจึงระบุการกำหนดค่าได้ 2 แบบ ได้แก่ การกำหนดค่า exec ซึ่งใช้
สำหรับการสร้างเครื่องมือที่ทำงานระหว่างการสร้าง และการกำหนดค่าเป้าหมาย
(หรือการกำหนดค่าคำขอ แต่เรามักจะพูดว่า "การกำหนดค่าเป้าหมาย" มากกว่าแม้ว่า
คำนั้นจะมีความหมายหลายอย่างอยู่แล้ว) ซึ่งใช้สำหรับการสร้าง
ไบนารีที่คุณขอในท้ายที่สุด
โดยปกติแล้วจะมีไลบรารีหลายรายการที่เป็นข้อกำหนดเบื้องต้นของทั้งเป้าหมายการสร้างที่ขอ (//foo:bin
) และเครื่องมือ exec อย่างน้อย 1 รายการ เช่น ไลบรารีพื้นฐานบางรายการ
ต้องสร้างไลบรารีดังกล่าว 2 ครั้ง ครั้งหนึ่งสำหรับการกำหนดค่า exec
และอีกครั้งสำหรับการกำหนดค่าเป้าหมาย Bazel จะดูแล
ให้มั่นใจว่าทั้ง 2 ตัวแปรได้รับการสร้างขึ้น และจะเก็บไฟล์ที่ได้
แยกกันเพื่อหลีกเลี่ยงการรบกวน โดยปกติแล้วเป้าหมายดังกล่าวจะสร้างพร้อมกันได้
เนื่องจากไม่ได้ขึ้นอยู่กับกัน หากคุณเห็นข้อความความคืบหน้า
ที่ระบุว่ามีการสร้างเป้าหมายหนึ่งๆ 2 ครั้ง แสดงว่า
สาเหตุอาจเป็นดังนี้
การกำหนดค่า Exec ได้รับมาจากการกำหนดค่าเป้าหมายดังนี้
- ใช้ Crosstool (
--crosstool_top
) เวอร์ชันเดียวกับที่ระบุในการกำหนดค่าคำขอ เว้นแต่จะระบุ--host_crosstool_top
- ใช้ค่า
--host_cpu
สำหรับ--cpu
(ค่าเริ่มต้น:k8
) - ใช้ค่าเดียวกันของตัวเลือกเหล่านี้ตามที่ระบุไว้ในการกำหนดค่าคำขอ:
--compiler
,--use_ijars
และหากใช้--host_crosstool_top
ระบบจะใช้ค่าของ--host_cpu
เพื่อค้นหาdefault_toolchain
ใน Crosstool (ไม่สนใจ--compiler
) สำหรับการกำหนดค่า exec - ใช้ค่าของ
--host_javabase
สำหรับ--javabase
- ใช้ค่าของ
--host_java_toolchain
สำหรับ--java_toolchain
- ใช้บิลด์ที่เพิ่มประสิทธิภาพสำหรับโค้ด C++ (
-c opt
) - ไม่สร้างข้อมูลการแก้ไขข้อบกพร่อง (
--copt=-g0
) - ลบข้อมูลการแก้ไขข้อบกพร่องออกจากไฟล์ที่เรียกใช้งานได้และไลบรารีที่ใช้ร่วมกัน
(
--strip=always
) - วางไฟล์ที่ได้มาทั้งหมดไว้ในตำแหน่งพิเศษที่แตกต่างจากตำแหน่งที่ใช้โดย การกำหนดค่าคำขอที่เป็นไปได้
- ระงับการประทับเวลาไบนารีด้วยข้อมูลการสร้าง (ดูตัวเลือก
--embed_*
) - ค่าอื่นๆ ทั้งหมดจะยังคงเป็นค่าเริ่มต้น
มีหลายเหตุผลที่ควรเลือกการกำหนดค่า exec ที่แตกต่างจากการกำหนดค่าคำขอ สิ่งที่สำคัญที่สุด
ประการแรก การใช้ไบนารีที่ได้รับการเพิ่มประสิทธิภาพและลบข้อมูลที่ไม่จำเป็นออกจะช่วยลดเวลาที่ใช้ในการลิงก์และเรียกใช้เครื่องมือ พื้นที่ดิสก์ที่เครื่องมือใช้ และเวลา I/O ของเครือข่ายในการบิลด์แบบกระจาย
ประการที่สอง การแยกการกำหนดค่า exec และการกำหนดค่าคำขอในการสร้างทั้งหมดจะช่วยให้คุณ หลีกเลี่ยงการสร้างใหม่ที่มีค่าใช้จ่ายสูงมากซึ่งอาจเกิดจากการเปลี่ยนแปลงเล็กน้อยในการกำหนดค่าคำขอ (เช่น การเปลี่ยนตัวเลือกของลิงเกอร์) ดังที่อธิบายไว้ ก่อนหน้านี้
การสร้างใหม่แบบเพิ่มทีละส่วนที่ถูกต้อง
เป้าหมายหลักอย่างหนึ่งของโปรเจ็กต์ Bazel คือการตรวจสอบว่าการสร้างใหม่แบบเพิ่มทีละรายการถูกต้อง เครื่องมือบิลด์ก่อนหน้า โดยเฉพาะเครื่องมือที่อิงตาม Make มีข้อสันนิษฐานที่ไม่สมเหตุสมผลหลายอย่างในการติดตั้งใช้งานบิลด์ที่เพิ่มขึ้น
ประการแรกคือการประทับเวลาของไฟล์จะเพิ่มขึ้นเรื่อยๆ แม้ว่านี่จะเป็นกรณีทั่วไป แต่ก็เป็นเรื่องง่ายมากที่จะละเมิดสมมติฐานนี้ การซิงค์ไฟล์กับเวอร์ชันก่อนหน้าจะทำให้เวลาแก้ไขของไฟล์นั้นลดลง ระบบที่ใช้ Make จะไม่สร้างใหม่
โดยทั่วไปแล้ว Make จะตรวจจับการเปลี่ยนแปลงในไฟล์ แต่จะไม่ตรวจจับการเปลี่ยนแปลง
ในคำสั่ง หากคุณเปลี่ยนตัวเลือกที่ส่งไปยังคอมไพเลอร์ในขั้นตอนการบิลด์ที่กำหนด Make จะไม่เรียกใช้คอมไพเลอร์อีกครั้ง และคุณจะต้องทิ้งเอาต์พุตที่ไม่ถูกต้องของการบิลด์ก่อนหน้าด้วยตนเองโดยใช้ make clean
นอกจากนี้ Make ยังไม่สามารถรับมือกับการสิ้นสุดที่ไม่สำเร็จของกระบวนการย่อยอย่างใดอย่างหนึ่งหลังจากที่กระบวนการย่อยนั้นเริ่มเขียนลงในไฟล์เอาต์พุตแล้ว แม้ว่าการเรียกใช้ Make ในปัจจุบันจะล้มเหลว แต่การเรียกใช้ Make ครั้งต่อๆ ไปจะถือว่าไฟล์เอาต์พุตที่ถูกตัดทอนนั้นถูกต้อง (เนื่องจากใหม่กว่าอินพุต) และจะไม่สร้างใหม่ ในทำนองเดียวกัน หากกระบวนการ Make ถูก หยุดทำงาน สถานการณ์ที่คล้ายกันอาจเกิดขึ้นได้
Bazel จะหลีกเลี่ยงการสมมติฐานเหล่านี้และอื่นๆ Bazel จะดูแลฐานข้อมูลของงานทั้งหมดที่ทำก่อนหน้านี้ และจะข้ามขั้นตอนการสร้างก็ต่อเมื่อพบว่าชุดไฟล์อินพุต (และการประทับเวลาของไฟล์) สำหรับขั้นตอนการสร้างนั้น รวมถึงคำสั่งคอมไพเลชันสำหรับขั้นตอนการสร้างนั้น ตรงกับรายการในฐานข้อมูลอย่างแน่นอน และชุดไฟล์เอาต์พุต (และการประทับเวลาของไฟล์) สำหรับรายการฐานข้อมูลตรงกับการประทับเวลาของไฟล์ในดิสก์อย่างแน่นอน การเปลี่ยนแปลงไฟล์อินพุตหรือไฟล์เอาต์พุต หรือการเปลี่ยนแปลงคำสั่งเอง จะทำให้ขั้นตอนการสร้างทำงานอีกครั้ง
ประโยชน์ที่ผู้ใช้จะได้รับจากการสร้างแบบเพิ่มทีละน้อยที่ถูกต้องคือ เสียเวลาน้อยลงเนื่องจาก
ความสับสน (นอกจากนี้ ยังใช้เวลารอนานน้อยลงในการสร้างใหม่เนื่องจากการใช้ make
clean
ไม่ว่าจะจำเป็นหรือไม่ก็ตาม)
สร้างความสม่ำเสมอและการเพิ่มขึ้นทีละน้อย
ในทางเทคนิค เราจะกำหนดสถานะของบิลด์เป็นสอดคล้องกันเมื่อมีไฟล์เอาต์พุตที่คาดไว้ทั้งหมด และเนื้อหาถูกต้องตามที่ระบุไว้ในขั้นตอนหรือกฎที่จำเป็นในการสร้างไฟล์ เมื่อคุณแก้ไขไฟล์ต้นฉบับ สถานะของ บิลด์จะถือว่าไม่สอดคล้องกัน และจะยังคงไม่สอดคล้องกันจนกว่าคุณจะเรียกใช้ เครื่องมือบิลด์อีกครั้งจนเสร็จสมบูรณ์ เราอธิบายสถานการณ์นี้ว่าไม่เสถียร ไม่สอดคล้องกันเนื่องจากเป็นเพียงชั่วคราว และความสอดคล้องจะกลับมา โดยการเรียกใช้เครื่องมือบิลด์
ความไม่สอดคล้องอีกประเภทหนึ่งที่ร้ายแรงคือความไม่สอดคล้องที่เสถียร หากบิลด์เข้าสู่สถานะที่ไม่สอดคล้องกันอย่างเสถียร การเรียกใช้เครื่องมือบิลด์ที่สำเร็จซ้ำๆ จะไม่คืนค่าความสอดคล้องกัน บิลด์จะ "ค้าง" และเอาต์พุตจะยังคงไม่ถูกต้อง สถานะที่ไม่สอดคล้องกันที่เสถียร
เป็นสาเหตุหลักที่ทำให้ผู้ใช้ Make (และเครื่องมือบิลด์อื่นๆ) พิมพ์ make clean
การพบว่าเครื่องมือบิลด์ล้มเหลวในลักษณะนี้ (และกู้คืนจากเครื่องมือ) อาจใช้เวลานานและน่าหงุดหงิดมาก
ในเชิงแนวคิด วิธีที่ง่ายที่สุดในการสร้างที่สอดคล้องกันคือการทิ้ง เอาต์พุตการสร้างทั้งหมดก่อนหน้าและเริ่มต้นใหม่ นั่นคือทำให้การสร้างทุกครั้งเป็นการสร้างที่สะอาด แน่นอนว่าวิธีนี้ใช้เวลานานเกินไปจนไม่สามารถนำไปใช้ได้จริง (ยกเว้นอาจจะเป็น สำหรับวิศวกรที่ดูแลการเผยแพร่) ดังนั้นเครื่องมือบิลด์จึงต้องสามารถ ทำการบิลด์แบบเพิ่มทีละรายการได้โดยไม่กระทบต่อความสอดคล้อง
การวิเคราะห์การขึ้นต่อกันแบบเพิ่มทีละรายการที่ถูกต้องเป็นเรื่องยาก และดังที่อธิบายไว้ข้างต้น เครื่องมือบิลด์อื่นๆ อีกมากมาย ทำงานได้ไม่ดีในการหลีกเลี่ยงสถานะที่ไม่สอดคล้องกันที่เสถียรระหว่าง การบิลด์แบบเพิ่มทีละรายการ ในทางตรงกันข้าม Bazel รับประกันว่าหลังจากเรียกใช้เครื่องมือบิลด์สำเร็จโดยที่คุณไม่ได้ทำการแก้ไขใดๆ บิลด์จะอยู่ในสถานะที่สอดคล้องกัน (หากคุณแก้ไขไฟล์ต้นฉบับระหว่างการบิลด์ Bazel จะไม่รับประกันความสอดคล้องของผลลัพธ์ของการบิลด์ปัจจุบัน แต่รับประกันได้ว่าผลลัพธ์ของบิลด์ถัดไปจะคืนค่าความสอดคล้อง)
เช่นเดียวกับการรับประกันทั้งหมด มีข้อความตัวเล็กๆ บางอย่างที่ควรทราบ นั่นคือมีวิธีที่ทราบกันดี ในการเข้าสู่สถานะที่ไม่สอดคล้องกันที่เสถียรด้วย Bazel เราไม่รับประกันว่าจะตรวจสอบปัญหาดังกล่าวที่เกิดจากการพยายามค้นหาข้อบกพร่องในการวิเคราะห์การขึ้นต่อกันแบบเพิ่มทีละรายการโดยเจตนา แต่จะตรวจสอบและพยายามอย่างเต็มที่เพื่อแก้ไขสถานะที่ไม่สอดคล้องกันที่เสถียรทั้งหมดซึ่งเกิดจากการใช้เครื่องมือบิลด์ตามปกติหรืออย่าง "สมเหตุสมผล"
หากตรวจพบสถานะที่ไม่สอดคล้องกันอย่างเสถียรใน Bazel โปรดรายงานข้อบกพร่อง
การดำเนินการในแซนด์บ็อกซ์
Bazel ใช้แซนด์บ็อกซ์เพื่อให้มั่นใจว่าการดำเนินการจะทำงานอย่างถูกต้องและ
เป็นไปตามข้อกำหนด Bazel จะเรียกใช้ spawn (พูดอย่างคร่าวๆ คือการดำเนินการ) ในแซนด์บ็อกซ์ที่มี
เฉพาะชุดไฟล์ขั้นต่ำที่เครื่องมือต้องใช้ในการทำงาน ปัจจุบัน
แซนด์บ็อกซ์ใช้งานได้ใน Linux 3.12 ขึ้นไปโดยเปิดใช้CONFIG_USER_NS
และใน macOS 10.11 ขึ้นไป
Bazel จะพิมพ์คำเตือนหากระบบไม่รองรับแซนด์บ็อกซ์เพื่อแจ้งให้คุณทราบว่าการบิลด์ไม่รับประกันว่าจะปิดสนิทและอาจส่งผลต่อระบบโฮสต์ในลักษณะที่ไม่รู้จัก หากต้องการปิดใช้คำเตือนนี้ ให้ส่งแฟล็ก
--ignore_unsupported_sandboxing
ไปยัง Bazel
ในบางแพลตฟอร์ม เช่น โหนดคลัสเตอร์ Google Kubernetes
Engine หรือ Debian
ระบบจะปิดใช้งานเนมสเปซของผู้ใช้โดยค่าเริ่มต้นเนื่องจากข้อกังวลด้านความปลอดภัย
โดยตรวจสอบได้จากไฟล์
/proc/sys/kernel/unprivileged_userns_clone
: หากมีอยู่และมีค่าเป็น 0
แสดงว่าเปิดใช้งานเนมสเปซของผู้ใช้ได้ด้วย
sudo sysctl kernel.unprivileged_userns_clone=1
ในบางกรณี แซนด์บ็อกซ์ของ Bazel จะดำเนินการตามกฎไม่สำเร็จเนื่องจากการตั้งค่าระบบ
โดยทั่วไปอาการคือการทำงานล้มเหลวซึ่งจะแสดงข้อความที่คล้ายกับ
namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory
ในกรณีนี้ ให้ลองปิดใช้งานแซนด์บ็อกซ์สำหรับ genrules ด้วย
--strategy=Genrule=standalone
และสำหรับกฎอื่นๆ ด้วย
--spawn_strategy=standalone
นอกจากนี้ โปรดรายงานข้อบกพร่องในเครื่องมือติดตามปัญหาของเราและระบุว่าคุณใช้ Linux รุ่นใด เพื่อให้เราตรวจสอบและแก้ไขในรุ่นต่อๆ ไปได้
ระยะต่างๆ ของบิลด์
ใน Bazel การบิลด์จะเกิดขึ้นใน 3 เฟสที่แตกต่างกัน ในฐานะผู้ใช้ การทำความเข้าใจความแตกต่างระหว่างเฟสเหล่านี้จะช่วยให้คุณทราบถึงตัวเลือกที่ควบคุมการบิลด์ (ดูด้านล่าง)
ระยะการโหลด
อย่างแรกคือการโหลด ซึ่งจะโหลด วิเคราะห์ ประเมิน และแคชไฟล์ BUILD ที่จำเป็นทั้งหมดสำหรับ เป้าหมายเริ่มต้น รวมถึงการปิดการขึ้นต่อกันแบบทรานซิทีฟ
สำหรับการบิลด์ครั้งแรกหลังจากเริ่มเซิร์ฟเวอร์ Bazel โดยปกติแล้วเฟสการโหลดจะใช้เวลาหลายวินาทีเนื่องจากมีการโหลดไฟล์ BUILD จำนวนมากจากระบบไฟล์ ในบิลด์ต่อๆ ไป โดยเฉพาะอย่างยิ่งหากไม่มีการเปลี่ยนแปลงไฟล์ BUILD การโหลดจะเกิดขึ้นอย่างรวดเร็ว
ข้อผิดพลาดที่รายงานในระหว่างขั้นตอนนี้ ได้แก่ ไม่พบแพ็กเกจ ไม่พบเป้าหมาย ข้อผิดพลาดทางคำศัพท์และไวยากรณ์ในไฟล์ BUILD และข้อผิดพลาดในการประเมิน
ระยะการวิเคราะห์
ระยะที่ 2 คือการวิเคราะห์ ซึ่งเกี่ยวข้องกับการวิเคราะห์เชิงความหมายและการตรวจสอบความถูกต้องของ กฎการสร้างแต่ละข้อ การสร้างกราฟการอ้างอิงการสร้าง และ การพิจารณาว่าต้องทำอะไรบ้างในแต่ละขั้นตอนของการสร้าง
เช่นเดียวกับการโหลด การวิเคราะห์จะใช้เวลาหลายวินาทีเมื่อคำนวณทั้งหมด อย่างไรก็ตาม Bazel จะแคชกราฟการขึ้นต่อกันจากการบิลด์หนึ่งไปยังการบิลด์ถัดไป และจะวิเคราะห์ซ้ำเฉพาะสิ่งที่ต้องทำเท่านั้น ซึ่งจะทำให้การบิลด์แบบเพิ่มทีละรายการรวดเร็วอย่างยิ่งในกรณีที่แพ็กเกจไม่เปลี่ยนแปลงตั้งแต่การบิลด์ครั้งก่อน
ข้อผิดพลาดที่รายงานในขั้นตอนนี้ ได้แก่ การอ้างอิงที่ไม่เหมาะสม อินพุตที่ไม่ถูกต้องสำหรับกฎ และข้อความแสดงข้อผิดพลาดทั้งหมดที่เฉพาะเจาะจงสำหรับกฎ
ระยะการโหลดและการวิเคราะห์จะรวดเร็วเนื่องจาก Bazel หลีกเลี่ยงการดำเนินการ I/O ของไฟล์ที่ไม่จำเป็นในขั้นตอนนี้ โดยจะอ่านเฉพาะไฟล์ BUILD เพื่อกำหนดงานที่จะต้องทำ ซึ่งเป็นไปตามการออกแบบ และทำให้ Bazel เป็นรากฐานที่ดีสำหรับเครื่องมือวิเคราะห์ เช่น คำสั่ง query ของ Bazel ซึ่งใช้ในระยะการโหลด
ระยะการดำเนินการ
เฟสที่ 3 ซึ่งเป็นเฟสสุดท้ายของการสร้างคือการดำเนินการ ระยะนี้จะช่วยให้มั่นใจว่าเอาต์พุตของแต่ละขั้นตอนในการสร้างสอดคล้องกับอินพุต โดยจะเรียกใช้เครื่องมือ การคอมไพล์/การลิงก์/ฯลฯ อีกครั้งตามที่จำเป็น ขั้นตอนนี้เป็นขั้นตอนที่บิลด์ใช้เวลาส่วนใหญ่ โดยอาจใช้เวลาตั้งแต่ไม่กี่วินาทีไปจนถึงมากกว่า 1 ชั่วโมงสำหรับบิลด์ขนาดใหญ่ ข้อผิดพลาดที่รายงานในระยะนี้ ได้แก่ ไม่มีไฟล์ต้นฉบับ ข้อผิดพลาดในเครื่องมือที่ดำเนินการโดยการดำเนินการบิลด์บางอย่าง หรือเครื่องมือสร้างชุดเอาต์พุตที่คาดไว้ไม่สำเร็จ