หน้านี้จะพูดถึงวิธีสร้างโปรแกรมด้วย Bazel, ไวยากรณ์คำสั่ง และไวยากรณ์รูปแบบเป้าหมาย
คู่มือเริ่มใช้งานฉบับย่อ
หากต้องการเรียกใช้ Bazel ให้ไปที่ไดเรกทอรีพื้นที่ทำงานพื้นฐานหรือไดเรกทอรีย่อยใดๆ ของไดเรกทอรีแล้วพิมพ์ bazel
ดูสร้างหากจำเป็นต้องสร้างพื้นที่ทำงานใหม่
bazel help
[Bazel release bazel version]
Usage: bazel command options ...
คำสั่งที่ใช้ได้
analyze-profile
: วิเคราะห์ข้อมูลโปรไฟล์การสร้างaquery
: เรียกใช้การค้นหาในกราฟการดำเนินการหลังการวิเคราะห์build
: สร้างเป้าหมายที่ระบุcanonicalize-flags
: กำหนดค่าแฟล็ก Bazel ให้เป็นค่ามาตรฐานclean
: นำไฟล์เอาต์พุตออกและหยุดเซิร์ฟเวอร์ (ไม่บังคับ)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
การสร้างเป้าหมาย 1 รายการ
คุณต้องมีเวิร์กスペースก่อนจึงจะเริ่มสร้างได้ พื้นที่ทํางานคือลําดับชั้นไดเรกทอรีที่มีไฟล์ต้นทางทั้งหมดที่จําเป็นสําหรับการสร้างแอปพลิเคชัน 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
นี่เป็นบิลด์ Null เนื่องจากไม่มีการเปลี่ยนแปลงใดๆ จึงไม่มีแพ็กเกจที่จะโหลดซ้ำและไม่มีขั้นตอนการสร้างที่จะดำเนินการ หากมีการเปลี่ยนแปลงใน "foo" หรือข้อกําหนดของ "foo" Bazel จะดําเนินการบางอย่างในบิลด์อีกครั้ง หรือทําบิลด์แบบเพิ่มให้เสร็จสมบูรณ์
การสร้างเป้าหมายหลายรายการ
Bazel มีวิธีระบุเป้าหมายที่จะสร้างได้หลายวิธี รายการเหล่านี้เรียกรวมกันว่ารูปแบบเป้าหมาย ไวยากรณ์นี้ใช้ในคําสั่ง เช่น build
, test
หรือ query
ส่วนป้ายกำกับจะใช้เพื่อระบุเป้าหมายแต่ละรายการ เช่น สำหรับการประกาศการพึ่งพาในไฟล์ BUILD
รูปแบบเป้าหมายของ Bazel จะระบุเป้าหมายหลายรายการ รูปแบบเป้าหมายเป็นไวยากรณ์ทั่วไปของป้ายกำกับสำหรับชุดเป้าหมายโดยใช้ไวลด์การ์ด ในกรณีที่ง่ายที่สุด ป้ายกำกับที่ถูกต้องจะเป็นรูปแบบเป้าหมายที่ถูกต้องด้วย ซึ่งจะระบุชุดเป้าหมายเพียงชุดเดียว
รูปแบบเป้าหมายทั้งหมดที่ขึ้นต้นด้วย //
จะได้รับการแก้ไขโดยสัมพันธ์กับเวิร์กสเปซปัจจุบัน
//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/...
คือไวลด์การ์ดที่อยู่เหนือแพ็กเกจ ซึ่งบ่งบอกว่าแพ็กเกจทั้งหมดอยู่ภายใต้ไดเรกทอรี foo
(สำหรับรูททั้งหมดของเส้นทางแพ็กเกจ) :all
เป็นไวลด์การ์ดสำหรับ targets ซึ่งจะจับคู่กฎทั้งหมดภายในแพ็กเกจ ทั้ง 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
" (ต้องใช้อาร์กิวเมนต์ --
เพื่อป้องกันไม่ให้ระบบตีความอาร์กิวเมนต์ต่อๆ ไปซึ่งขึ้นต้นด้วย -
เป็นตัวเลือกเพิ่มเติม)
อย่างไรก็ตาม โปรดทราบว่าการลบเป้าหมายด้วยวิธีนี้ไม่ได้รับประกันว่าระบบจะไม่สร้างเป้าหมายดังกล่าว เนื่องจากเป้าหมายเหล่านั้นอาจเป็นทรัพยากรของเป้าหมายที่ไม่ได้ถูกลบ ตัวอย่างเช่น หากมีเป้าหมาย //foo:all-apis
ที่ขึ้นอยู่กับ //foo/bar:api
รายการอื่นๆ ระบบจะสร้าง //foo/bar:api
เป็นส่วนหนึ่งของการสร้าง //foo:all-apis
เป้าหมายที่มี tags = ["manual"]
จะไม่รวมอยู่ในรูปแบบเป้าหมายไวลด์การ์ด (...
, :*
, :all
ฯลฯ) เมื่อระบุไว้ในคําสั่ง เช่น bazel build
และ bazel test
(แต่จะรวมอยู่ในรูปแบบเป้าหมายไวลด์การ์ดเชิงลบ ซึ่งก็คือจะมีการลบออก) คุณควรระบุเป้าหมายการทดสอบดังกล่าวด้วยรูปแบบเป้าหมายที่ชัดเจนในบรรทัดคำสั่งหากต้องการให้ Bazel บิลด์/ทดสอบ ในทางตรงกันข้าม bazel query
จะไม่กรองข้อมูลดังกล่าวโดยอัตโนมัติ (เพราะจะขัดต่อวัตถุประสงค์ของ bazel query
)
การดึงข้อมูลทรัพยากร Dependency ภายนอก
โดยค่าเริ่มต้น Bazel จะดาวน์โหลดและสร้างลิงก์สัญลักษณ์สำหรับทรัพยากร Dependency ภายนอกระหว่างการสร้าง อย่างไรก็ตาม การดำเนินการนี้อาจไม่เหมาะสมเนื่องจากคุณต้องการทราบเมื่อมีการเพิ่มการพึ่งพาภายนอกใหม่ หรือคุณต้องการ "เตรียมความพร้อมล่วงหน้า" ให้กับการพึ่งพา (เช่น ก่อนเที่ยวบินที่คุณจะต้องออฟไลน์) หากต้องการป้องกันไม่ให้เพิ่มการพึ่งพาใหม่ระหว่างการสร้าง คุณสามารถระบุ Flag --fetch=false
โปรดทราบว่า Flag นี้มีผลกับกฎของที่เก็บซึ่งไม่ได้ชี้ไปยังไดเรกทอรีในระบบไฟล์ในเครื่องเท่านั้น เช่น การเปลี่ยนแปลงกฎ local_repository
, new_local_repository
และ Android SDK และกฎที่เก็บ NDK จะมีผลเสมอโดยไม่คำนึงถึงค่า --fetch
หากคุณไม่อนุญาตให้ดึงข้อมูลระหว่างการบิลด์และ Bazel พบข้อกําหนดภายนอกใหม่ การบิลด์จะดำเนินการไม่สำเร็จ
คุณสามารถดึงข้อมูล Dependency ด้วยตนเองได้โดยเรียกใช้ bazel fetch
หากไม่อนุญาตให้ดึงข้อมูลระหว่างการสร้าง คุณจะต้องเรียกใช้ bazel fetch
ดังนี้
- ก่อนสร้างครั้งแรก
- หลังจากเพิ่มทรัพยากรภายนอกใหม่
เมื่อเรียกใช้แล้ว คุณไม่ควรเรียกใช้อีกครั้งจนกว่าไฟล์ MODULE.bazel จะเปลี่ยนแปลง
fetch
ใช้รายการเป้าหมายเพื่อดึงข้อมูลการพึ่งพา ตัวอย่างเช่น คำสั่งนี้จะดึงข้อมูล Dependency ที่จําเป็นสําหรับการสร้าง //foo:bar
และ //bar:baz
bazel fetch //foo:bar //bar:baz
หากต้องการดึงข้อมูล Dependency ภายนอกทั้งหมดสําหรับพื้นที่ทํางาน ให้เรียกใช้คำสั่งต่อไปนี้
bazel fetch //...
ใน Bazel 7 ขึ้นไป หากเปิดใช้ Bzlmod ไว้ คุณจะดึงข้อมูลข้อกำหนดภายนอกทั้งหมดได้โดยเรียกใช้
bazel fetch
คุณไม่จำเป็นต้องเรียกใช้การดึงข้อมูลแบบ Bazel เลยหากมีเครื่องมือทั้งหมดที่ใช้อยู่ (ตั้งแต่ JD ไลบรารีไปจนถึง 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 และนอกจากนี้ แฮชของไฟล์ก็เท่ากับแฮชที่ระบุในคําขอดาวน์โหลด ซึ่งจะใช้ได้หากมีการระบุแฮชของไฟล์ในการประกาศกฎที่เก็บเท่านั้น
แม้ว่าเงื่อนไขในชื่อไฟล์จะไม่จำเป็นต่อความถูกต้อง แต่เงื่อนไขดังกล่าวจะลดจำนวนไฟล์ที่เป็นไปได้ให้เหลือเพียง 1 ไฟล์ต่อไดเรกทอรีที่ระบุ วิธีนี้ช่วยให้การระบุไดเรกทอรีไฟล์สำหรับเผยแพร่ยังคงมีประสิทธิภาพแม้ว่าจำนวนไฟล์ในไดเรกทอรีดังกล่าวจะเพิ่มขึ้นมากก็ตาม
เรียกใช้ Bazel ในสภาพแวดล้อมที่มีการแยกเครือข่าย
ระบบจะดึงข้อมูล Dependency ที่ไม่ชัดแจ้งของ Bazel ผ่านเครือข่ายขณะที่ใช้งานเป็นครั้งแรกเพื่อให้ไฟล์ไบนารีของ Bazel มีขนาดเล็ก ไลบรารีและเครื่องมือโดยนัยเหล่านี้มีเครื่องมือและกฎที่ผู้ใช้บางรายอาจไม่จำเป็น เช่น เครื่องมือ Android จะเลิกรวมกลุ่มและดึงข้อมูลเมื่อสร้างโปรเจ็กต์ Android เท่านั้น
อย่างไรก็ตาม ทรัพยากร Dependency โดยนัยเหล่านี้อาจทำให้เกิดปัญหาเมื่อเรียกใช้ Bazel ในสภาพแวดล้อมที่มีการเชื่อมต่อ แม้ว่าคุณจะเป็นผู้ให้บริการการขึ้นต่อกันภายนอกทั้งหมดก็ตาม วิธีแก้ปัญหานี้คือ คุณอาจเตรียมแคชที่เก็บ (โดยใช้ Bazel 7 ขึ้นไป) หรือไดเรกทอรีการเผยแพร่ (โดยใช้ Bazel เวอร์ชันก่อน 7) ที่มีข้อมูลที่ต้องพึ่งพาเหล่านี้ในเครื่องที่มีสิทธิ์เข้าถึงเครือข่าย จากนั้นโอนไปยังสภาพแวดล้อมที่มีการแยกเครือข่ายโดยใช้วิธีการแบบออฟไลน์
แคชที่เก็บ (ใช้กับ Bazel 7 ขึ้นไป)
หากต้องการเตรียมแคชที่เก็บ ให้ใช้ Flag --repository_cache
คุณจะต้องทําเช่นนี้ 1 ครั้งสําหรับไบนารี Bazel เวอร์ชันใหม่ทุกเวอร์ชัน เนื่องจากความเกี่ยวข้องโดยนัยอาจแตกต่างกันไปในแต่ละรุ่น
หากต้องการดึงข้อมูลทรัพยากร Dependency เหล่านั้นนอกสภาพแวดล้อม Airgapp ของคุณ ก่อนอื่นให้สร้างพื้นที่ทำงานว่าง
mkdir empty_workspace && cd empty_workspace
touch MODULE.bazel
หากต้องการดึงข้อมูล Dependency ของ Bzlmod ในตัว ให้เรียกใช้
bazel fetch --repository_cache="path/to/repository/cache"
หากคุณยังคงใช้ไฟล์ WORKSPACE แบบเดิม ให้เรียกใช้
bazel sync --repository_cache="path/to/repository/cache"
สุดท้าย เมื่อใช้ Bazel ในสภาพแวดล้อมที่มีการป้องกันทางอากาศ ให้ส่ง Flag --repository_cache
เดียวกัน คุณสามารถเพิ่มเป็น.bazelrc
รายการได้เพื่อความสะดวก
common --repository_cache="path/to/repository/cache"
นอกจากนี้ คุณอาจต้องโคลน BCR ในเครื่องและใช้ Flag --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 นี้ไปยังไดเรกทอรีที่คัดลอกไปยังสภาพแวดล้อมที่ปลอดภัยได้ โปรดสังเกต Flag --strip-components
เนื่องจาก --distdir
อาจทำงานได้ไม่ดีนักกับระดับการซ้อนไดเรกทอรี
tar xvf bazel-bin/external/additional_distfiles/archives.tar \
-C "$NEW_DIRECTORY" --strip-components=3
สุดท้าย เมื่อใช้ Bazel ในสภาพแวดล้อมที่มีการป้องกันอากาศ ให้ส่ง Flag --distdir
ที่ชี้ไปยังไดเรกทอรี คุณสามารถเพิ่มเป็น.bazelrc
รายการได้เพื่อความสะดวก
build --distdir=path/to/directory
การกำหนดค่าบิลด์และการคอมไพล์ข้าม
อินพุตทั้งหมดที่ระบุลักษณะการทำงานและผลลัพธ์ของบิลด์หนึ่งๆ สามารถแบ่งออกเป็น 2 หมวดหมู่ที่แตกต่างกัน ประเภทแรกคือข้อมูลภายในที่เก็บไว้ในไฟล์ BUILD
ของโปรเจ็กต์ ซึ่งได้แก่ กฎการสร้าง ค่าของแอตทริบิวต์ และชุดของข้อกำหนดที่เกี่ยวข้องทั้งหมด
ประเภทที่ 2 คือข้อมูลภายนอกหรือข้อมูลสภาพแวดล้อมที่ผู้ใช้หรือเครื่องมือสร้างระบุ ได้แก่ ตัวเลือกสถาปัตยกรรมเป้าหมาย ตัวเลือกการคอมไพล์และการลิงก์ และตัวเลือกการกำหนดค่าเครื่องมืออื่นๆ ส่วนเราจะเรียกชุดข้อมูลด้านสิ่งแวดล้อมทั้งหมดว่าการกำหนดค่า
อาจมีการกำหนดค่ามากกว่า 1 รายการในบิลด์หนึ่งๆ ลองใช้เครื่องมือคอมไพล์แบบครอสคอมไพล์เพื่อสร้างไฟล์ปฏิบัติการ //foo:bin
สำหรับสถาปัตยกรรมแบบ 64 บิต แต่เวิร์กสเตชันของคุณเป็นเครื่องแบบ 32 บิต เห็นได้ชัดว่าบิลด์จะต้องสร้าง //foo:bin
โดยใช้เครื่องมือเชนที่สามารถสร้างไฟล์ปฏิบัติการ 64 บิตได้ แต่ระบบบิลด์จะต้องสร้างเครื่องมือต่างๆ ที่ใช้ในระหว่างบิลด์ด้วย เช่น เครื่องมือที่สร้างขึ้นจากแหล่งที่มา แล้วนำมาใช้ในภายหลัง เช่น Genrule ซึ่งจะต้องสร้างขึ้นมาเพื่อให้ทำงานบนเวิร์กสเตชันของคุณได้ ดังนั้น เราจึงระบุการกําหนดค่าได้ 2 รายการ ได้แก่ การกําหนดค่า exec ซึ่งใช้สําหรับการสร้างเครื่องมือที่ทํางานระหว่างการบิลด์ และการกําหนดค่าเป้าหมาย (หรือการกําหนดค่าคําขอ แต่เราใช้คำว่า "การกําหนดค่าเป้าหมาย" บ่อยกว่า แม้ว่าคําดังกล่าวจะมีความหมายหลายอย่างอยู่แล้ว) ซึ่งใช้สําหรับการสร้างไบนารีที่คุณขอในท้ายที่สุด
โดยทั่วไปแล้ว จะมีไลบรารีหลายรายการที่เป็นข้อกําหนดเบื้องต้นของทั้งเป้าหมายการสร้างที่ขอ (//foo:bin
) และเครื่องมือ exec อย่างน้อย 1 รายการ เช่น ไลบรารีพื้นฐานบางรายการ ไลบรารีดังกล่าวต้องสร้างขึ้น 2 ครั้ง โดย 1 ครั้งสําหรับการกําหนดค่า exec และ 1 ครั้งสําหรับการกําหนดค่าเป้าหมาย Bazel ดูแลให้มีการสร้างตัวแปรทั้งสองแบบและแยกไฟล์ที่ดึงมาไว้แยกกันเพื่อหลีกเลี่ยงการรบกวน โดยทั่วไปเป้าหมายดังกล่าวจะสามารถสร้างพร้อมกัน เนื่องจากเป้าหมายทั้งสองจะแยกจากกัน หากคุณเห็นข้อความความคืบหน้าที่ระบุว่ามีการสร้างเป้าหมายที่กำหนด 2 ครั้ง นั่นก็น่าจะเป็นคำอธิบาย
การกำหนดค่า exec มาจากการกำหนดค่าเป้าหมาย ดังนี้
- ใช้ Crosstool (
--crosstool_top
) เวอร์ชันเดียวกับที่ระบุในการกําหนดค่าคําขอ เว้นแต่จะมีการระบุ--host_crosstool_top
- ใช้ค่า
--host_cpu
สำหรับ--cpu
(ค่าเริ่มต้น:k8
) - ใช้ค่าของตัวเลือกเหล่านี้ให้เหมือนกับที่ระบุในการกำหนดค่าคำขอ:
--compiler
,--use_ijars
และหากใช้--host_crosstool_top
ระบบจะใช้ค่าของ--host_cpu
เพื่อค้นหาdefault_toolchain
ใน Crosstool (ไม่สนใจ--compiler
) สำหรับการกำหนดค่าการดำเนินการ - ใช้ค่าของ
--host_javabase
สําหรับ--javabase
- ใช้ค่า
--host_java_toolchain
สําหรับ--java_toolchain
- ใช้บิลด์ที่เพิ่มประสิทธิภาพสำหรับโค้ด C++ (
-c opt
) - ไม่สร้างข้อมูลการแก้ไขข้อบกพร่อง (
--copt=-g0
) - นำข้อมูลการแก้ไขข้อบกพร่องออกจากไฟล์ปฏิบัติการและไลบรารีที่ใช้ร่วมกัน (
--strip=always
) - วางไฟล์ที่ดึงข้อมูลทั้งหมดไว้ในตำแหน่งพิเศษ ซึ่งแตกต่างจากตำแหน่งที่ใช้โดยการกำหนดค่าคำขอที่เป็นไปได้
- ระงับการประทับเวลาของไบนารีด้วยข้อมูลบิลด์ (ดูตัวเลือก
--embed_*
) - ค่าอื่นๆ ทั้งหมดจะยังคงเป็นค่าเริ่มต้น
มีเหตุผลหลายประการที่อาจทำให้คุณเลือกการกําหนดค่า exec ที่แตกต่างจากการกําหนดค่าคําขอ สิ่งสำคัญที่สุด
ประการแรก การใช้ไบนารีที่ผ่านการลบข้อมูลและเพิ่มประสิทธิภาพแล้วจะช่วยประหยัดเวลาในการลิงก์และเรียกใช้เครื่องมือ พื้นที่ดิสก์ที่เครื่องมือใช้ และเวลา I/O ของเครือข่ายในบิลด์แบบกระจาย
ประการที่ 2 การแยกการกำหนดค่าการดำเนินการและคำขอในบิลด์ทั้งหมดช่วยหลีกเลี่ยงการสร้างใหม่ที่มีราคาแพงมาก ซึ่งอาจเกิดจากการเปลี่ยนแปลงการกำหนดค่าคำขอเล็กๆ น้อยๆ (เช่น การเปลี่ยนตัวเลือก Linker ก็สามารถทำได้) ดังที่ได้อธิบายก่อนหน้านี้
แก้ไขการสร้างใหม่ที่เพิ่มขึ้นเรื่อยๆ
เป้าหมายหลักอย่างหนึ่งของโปรเจ็กต์ Bazel คือการสร้างการปรับปรุงส่วนเพิ่มที่ถูกต้อง เครื่องมือสร้างก่อนหน้านี้ โดยเฉพาะเครื่องมือที่สร้างจาก Make มีการสมมติฐานที่ไม่ถูกต้องหลายประการในการใช้งานการสร้างแบบเพิ่ม
ประการแรก การประทับเวลาของไฟล์จะเพิ่มขึ้นเรื่อยๆ แม้ว่านี่จะเป็นกรณีทั่วไป แต่การซิงค์กับไฟล์เวอร์ชันก่อนหน้าจะทำให้เวลาการแก้ไขไฟล์ลดลง ระบบที่ใช้ Make จะไม่สร้างใหม่
กล่าวโดยทั่วไปคือ แม้เครื่องมือจะตรวจจับการเปลี่ยนแปลงไฟล์ แต่เครื่องมือจะไม่ตรวจหาการเปลี่ยนแปลงของคำสั่ง หากคุณแก้ไขตัวเลือกที่ส่งไปยังคอมไพเลอร์ในขั้นตอนการสร้างหนึ่งๆ Make จะไม่เรียกใช้คอมไพเลอร์อีกครั้ง และคุณจะต้องทิ้งเอาต์พุตที่ไม่ถูกต้องของบิลด์ก่อนหน้าด้วยตนเองโดยใช้ make clean
นอกจากนี้ Make ยังไม่เสถียรเมื่อการสิ้นสุดกระบวนการย่อยไม่สำเร็จหลังจากที่กระบวนการย่อยนั้นเริ่มเขียนลงในไฟล์เอาต์พุตแล้ว แม้ว่าการดำเนินการ Make ปัจจุบันจะล้มเหลว แต่การเรียกใช้ Make ในครั้งต่อๆ ไปจะสันนิษฐานว่าไฟล์เอาต์พุตที่ถูกตัดนั้นถูกต้อง (เนื่องจากเป็นไฟล์ที่ใหม่กว่าอินพุต) และจะไม่สร้างขึ้นใหม่ ในทํานองเดียวกัน หากกระบวนการสร้างถูกยกเลิก สถานการณ์ที่คล้ายกันก็อาจเกิดขึ้นได้
Bazel หลีกเลี่ยงสมมติฐานเหล่านี้และอื่นๆ Bazel จะดูแลฐานข้อมูลของงานทั้งหมดที่ทำก่อนหน้านี้ และจะข้ามขั้นตอนการสร้างเฉพาะในกรณีที่พบว่าชุดไฟล์อินพุต (และการประทับเวลา) ของขั้นตอนการสร้างนั้น และคำสั่งคอมไพล์สำหรับขั้นตอนการสร้างนั้นตรงกับรายการในฐานข้อมูลทุกประการ และชุดไฟล์เอาต์พุต (และการประทับเวลา) ของรายการฐานข้อมูลตรงกับการประทับเวลาของไฟล์ในดิสก์ทุกประการ การเปลี่ยนแปลงไฟล์อินพุตหรือไฟล์เอาต์พุต หรือการเปลี่ยนแปลงคำสั่งเองจะทำให้ระบบเรียกใช้ขั้นตอนการสร้างอีกครั้ง
ประโยชน์ที่ผู้ใช้จะได้รับจากบิลด์ที่เพิ่มขึ้นอย่างถูกต้องคือประหยัดเวลาอันเนื่องมาจากการเกิดความสับสน (นอกจากนี้ คุณยังรอเวลาสร้างใหม่ได้น้อยลงเนื่องจากการใช้ make
clean
ไม่ว่าจะจำเป็นหรือป้องกันไว้ก่อนก็ตาม)
สร้างความสอดคล้องและบิลด์ที่เพิ่มขึ้น
อย่างเป็นทางการ เราจะกำหนดสถานะของบิลด์เป็นสอดคล้องกันเมื่อมีไฟล์เอาต์พุตที่คาดไว้ทั้งหมด และเนื้อหาในไฟล์มีความถูกต้อง ตามที่ระบุไว้ในขั้นตอนหรือกฎที่จำเป็นในการสร้างไฟล์ดังกล่าว เมื่อคุณแก้ไขไฟล์ต้นฉบับ ระบบจะถือว่าสถานะการสร้างไม่สอดคล้องกัน และยังคงไม่สอดคล้องกันจนกว่าคุณจะเรียกใช้เครื่องมือสร้างให้เสร็จสมบูรณ์ในครั้งถัดไป เราอธิบายสถานการณ์นี้ว่าความไม่สอดคล้องที่ไม่เสถียร เนื่องจากเป็นสถานการณ์ที่เกิดขึ้นชั่วคราวเท่านั้น และระบบจะคืนค่าความสอดคล้องโดยการดำเนินการกับเครื่องมือสร้าง
ความไม่สอดคล้องอีกประเภทหนึ่งที่เป็นอันตรายคือความไม่สอดคล้องแบบคงที่ หากบิวด์อยู่ในสถานะไม่สอดคล้องกันซึ่งเสถียรแล้ว การเรียกใช้เครื่องมือสร้างที่สำเร็จซ้ำๆ จะไม่คืนค่าความสอดคล้องกัน เนื่องจากบิวด์ "ค้าง" และเอาต์พุตยังคงไม่ถูกต้อง สถานะที่คงที่แต่ไม่สอดคล้องกันคือสาเหตุหลักที่ทำให้ผู้ใช้ Make (และเครื่องมือสร้างอื่นๆ) พิมพ์ make clean
การพบว่าเครื่องมือสร้างทำงานไม่สำเร็จในลักษณะนี้ (และกู้คืนจากปัญหา) อาจใช้เวลานานและน่าหงุดหงิดมาก
โดยหลักการแล้ว วิธีที่ง่ายที่สุดในการทำให้บิลด์มีความสอดคล้องกันคือการใช้เอาต์พุตของบิลด์ก่อนหน้าทั้งหมดทิ้งแล้วเริ่มใหม่อีกครั้ง: ทำให้ทุกบิลด์เป็นบิลด์ที่สะอาด เห็นได้ชัดว่าวิธีการนี้ใช้เวลานานเกินไปที่จะปฏิบัติได้จริง (ยกเว้นสำหรับวิศวกรที่เปิดตัว) และด้วยเหตุนี้ จึงจะมีประโยชน์ เครื่องมือสร้างเวอร์ชันต้องสามารถทำบิลด์เพิ่มเติมได้โดยไม่ส่งผลกระทบต่อความสอดคล้องกัน
การวิเคราะห์การพึ่งพาแบบเพิ่มที่ถูกต้องนั้นทำได้ยาก และเครื่องมือสร้างอื่นๆ จำนวนมากทำงานได้ไม่ดีนักในการหลีกเลี่ยงสถานะที่เสถียรแต่ไม่สอดคล้องกันในระหว่างการสร้างแบบเพิ่ม ในทางตรงกันข้าม Bazel ให้การรับประกันดังต่อไปนี้ หลังจากเรียกใช้เครื่องมือสร้างสำเร็จโดยที่คุณไม่ได้ทำการแก้ไขใดๆ การสร้างจะอยู่ในสถานะที่สอดคล้องกัน (หากคุณแก้ไขไฟล์ต้นฉบับระหว่างการบิลด์ Bazel จะไม่รับประกันความสอดคล้องของผลลัพธ์ของบิลด์ปัจจุบัน แต่รับประกันว่าผลลัพธ์ของบิลด์ถัดไปจะคืนค่าความสอดคล้อง)
เช่นเดียวกับการรับประกันทั้งหมด ก็มีรายละเอียดปลีกย่อยอยู่บ้าง ซึ่งเราทราบมาว่ามีวิธีบางอย่างที่ทำให้เกิดสถานะไม่สอดคล้องกันซึ่งเสถียรกับ Bazel เราไม่รับประกันว่าจะตรวจสอบปัญหาดังกล่าวที่เกิดจากความพยายามอย่างตั้งใจเพื่อค้นหาข้อบกพร่องในการวิเคราะห์ทรัพยากร Dependency ที่เพิ่มขึ้น แต่จะตรวจสอบและพยายามอย่างเต็มที่เพื่อแก้ไขสถานะที่ไม่สอดคล้องกันทั้งหมดซึ่งเกิดจากการใช้เครื่องมือสร้างตามปกติหรือ "สมเหตุสมผล"
หากตรวจพบสถานะที่ไม่สอดคล้องกันซึ่งเสถียรกับ Bazel โปรดรายงานข้อบกพร่อง
การดำเนินการที่แซนด์บ็อกซ์
Bazel ใช้แซนด์บ็อกซ์เพื่อรับประกันว่าการดำเนินการจะทำงานอย่างถูกต้องและปลอดภัย Bazel จะเรียกใช้การสร้าง (พูดง่ายๆ คือการดำเนินการ) ในแซนด์บ็อกซ์ที่มีเฉพาะชุดไฟล์ขั้นต่ำที่เครื่องมือต้องใช้ในการทำงาน ปัจจุบัน Sandboxing ใช้งานได้ใน Linux 3.12 ขึ้นไปที่เปิดใช้ตัวเลือก CONFIG_USER_NS
และใน macOS 10.11 ขึ้นไป
Bazel จะพิมพ์คำเตือนหากระบบของคุณไม่รองรับแซนด์บ็อกซ์เพื่อแจ้งให้คุณทราบว่าไม่มีการรับประกันว่าบิลด์จะปิดผนึกและอาจส่งผลต่อระบบโฮสต์ในลักษณะที่ไม่รู้จัก หากต้องการปิดใช้คำเตือนนี้ ให้ส่ง Flag --ignore_unsupported_sandboxing
ไปยัง Bazel
ในบางแพลตฟอร์ม เช่น โหนดคลัสเตอร์ Google Kubernetes Engine หรือ Debian เนมสเปซของผู้ใช้จะถูกปิดใช้งานโดยค่าเริ่มต้นเนื่องจากข้อกังวลด้านความปลอดภัย ตรวจสอบได้โดยดูที่ไฟล์ /proc/sys/kernel/unprivileged_userns_clone
: หากมีไฟล์ดังกล่าวและมี 0 อยู่ แสดงว่าเปิดใช้งานเนมสเปซของผู้ใช้ได้ด้วย sudo sysctl kernel.unprivileged_userns_clone=1
ในบางกรณี Sandbox ของ Bazel ไม่สามารถเรียกใช้กฎได้เนื่องจากการตั้งค่าระบบ โดยทั่วไป อาการคือความล้มเหลวที่แสดงข้อความคล้ายกับ
namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory
ในกรณีนี้ ให้ลองปิดใช้งานแซนด์บ็อกซ์สำหรับ genrules ที่มี --strategy=Genrule=standalone
และสำหรับกฎอื่นๆ ที่มี --spawn_strategy=standalone
นอกจากนี้ โปรดรายงานข้อบกพร่องในเครื่องมือติดตามปัญหา และระบุว่าคุณใช้ Linux Distribution ใดอยู่เพื่อให้เราตรวจสอบและแก้ไขข้อบกพร่องในรุ่นต่อๆ ไปได้
ระยะต่างๆ ของการสร้าง
ใน Bazel บิลด์จะเกิดขึ้นโดยแบ่งเป็น 3 ระยะ ในฐานะผู้ใช้ การทำความเข้าใจความแตกต่างระหว่างทั้งสองจะให้ข้อมูลเชิงลึกเกี่ยวกับตัวเลือกที่ควบคุมบิลด์ (ดูด้านล่าง)
ระยะการโหลด
ขั้นตอนแรกคือการโหลด ซึ่งจะโหลด แยกวิเคราะห์ ประเมิน และแคชไฟล์ BUILD ที่จำเป็นทั้งหมดสำหรับเป้าหมายเริ่มต้นและชุดค่าผสมแบบทรานซิทีฟของข้อกำหนด
สำหรับบิลด์แรกหลังจากเริ่มเซิร์ฟเวอร์ Bazel ระยะการโหลดมักจะใช้เวลาหลายวินาทีเนื่องจากมีการโหลดไฟล์ BUILD จำนวนมากจากระบบไฟล์ ในบิลด์ต่อๆ ไป การโหลดจะทํางานอย่างรวดเร็วมาก โดยเฉพาะในกรณีที่ไม่มีการเปลี่ยนแปลงไฟล์ BUILD
ข้อผิดพลาดที่รายงานในระยะนี้ ได้แก่ ไม่พบแพ็กเกจ ไม่พบเป้าหมาย ข้อผิดพลาดด้านคําศัพท์และไวยากรณ์ในไฟล์ BUILD และข้อผิดพลาดในการประเมิน
ระยะการวิเคราะห์
ระยะที่ 2 คือการวิเคราะห์ ซึ่งเกี่ยวข้องกับการวิเคราะห์เชิงความหมายและการตรวจสอบกฎการสร้างแต่ละข้อ การสร้างกราฟความเกี่ยวข้องของบิลด์ และการกำหนดสิ่งที่ต้องทําในแต่ละขั้นตอนของการสร้าง
เช่นเดียวกับการโหลด การวิเคราะห์ก็ใช้เวลาหลายวินาทีเมื่อคํานวณทั้งหมด อย่างไรก็ตาม Bazel จะแคชกราฟความเกี่ยวข้องจากบิลด์หนึ่งไปยังอีกบิลด์หนึ่ง และวิเคราะห์ซ้ำเฉพาะสิ่งที่จำเป็นต้องวิเคราะห์เท่านั้น ซึ่งจะทำให้บิลด์แบบเพิ่มข้อมูลทำได้รวดเร็วมากในกรณีที่แพ็กเกจไม่มีการเปลี่ยนแปลงนับตั้งแต่บิลด์ก่อนหน้า
ข้อผิดพลาดที่รายงานในขั้นตอนนี้ ได้แก่ ทรัพยากร Dependency ที่ไม่เหมาะสม ข้อมูลเข้ากฎที่ไม่ถูกต้อง และข้อความแสดงข้อผิดพลาดเฉพาะกฎทั้งหมด
ระยะการโหลดและการวิเคราะห์จะรวดเร็วเนื่องจาก Bazel หลีกเลี่ยง I/O ของไฟล์ที่ไม่จำเป็นในระยะนี้ โดยจะอ่านเฉพาะไฟล์ BUILD เพื่อกำหนดงานที่จะทำ การดำเนินการนี้เป็นไปตามการออกแบบและทำให้ Bazel เป็นรากฐานที่ดีสำหรับเครื่องมือวิเคราะห์ เช่น คำสั่ง query ของ Bazel ซึ่งติดตั้งใช้งานในเฟสการโหลด
ระยะการดําเนินการ
ระยะที่ 3 และเป็นระยะสุดท้ายของการสร้างคือการดำเนินการ ระยะนี้ช่วยให้มั่นใจว่าเอาต์พุตของแต่ละขั้นตอนในบิลด์จะสอดคล้องกับอินพุต โดยระบบจะเรียกใช้เครื่องมือคอมไพล์/ลิงก์/อื่นๆ อีกครั้งตามความจำเป็น ขั้นตอนนี้เป็นขั้นตอนที่ใช้เวลาส่วนใหญ่ในการสร้าง ซึ่งอาจใช้เวลาตั้งแต่ 2-3 วินาทีไปจนถึงกว่า 1 ชั่วโมงสำหรับบิลด์ขนาดใหญ่ ข้อผิดพลาดที่รายงานในระยะนี้ ได้แก่ ไฟล์ต้นฉบับหายไป ข้อผิดพลาดในเครื่องมือที่ดำเนินการโดยการดำเนินการบิลด์บางอย่าง หรือการที่เครื่องมือสร้างชุดเอาต์พุตที่คาดไว้ไม่สำเร็จ