หน้านี้จะถือว่าคุณคุ้นเคยกับ Bazel และให้คำแนะนำและเคล็ดลับในการจัดโครงสร้างโปรเจ็กต์เพื่อใช้ประโยชน์จากฟีเจอร์ของ Bazel อย่างเต็มที่
เป้าหมายโดยรวมมีดังนี้
- ใช้ทรัพยากร Dependency แบบละเอียดเพื่ออนุญาตการทำงานแบบขนานและการเพิ่มขึ้น
- เก็บทรัพยากร Dependency ไว้ในแคปซูลอย่างดี
- ทำให้โค้ดมีโครงสร้างที่ดีและทดสอบได้
- สร้างการกำหนดค่าบิลด์ที่เข้าใจและดูแลรักษาง่าย
คำแนะนำเหล่านี้ไม่ใช่ข้อกำหนด เนื่องจากมีเพียงไม่กี่โปรเจ็กต์ที่จะปฏิบัติตามคำแนะนำทั้งหมดได้ ดังที่หน้าคู่มือสำหรับ lint ระบุไว้ว่า "เราจะมอบรางวัลพิเศษให้กับบุคคลแรกที่สร้างโปรแกรมจริงที่ไม่มีข้อผิดพลาดเมื่อตรวจสอบอย่างเข้มงวด" อย่างไรก็ตาม การรวมหลักการเหล่านี้ไว้ให้มากที่สุดเท่าที่จะเป็นไปได้จะช่วยให้โปรเจ็กต์อ่านง่ายขึ้น มีข้อผิดพลาดน้อยลง และสร้างได้เร็วขึ้น
หน้านี้ใช้ระดับข้อกำหนดที่อธิบายไว้ใน RFC นี้
การเรียกใช้บิลด์และการทดสอบ
โปรเจ็กต์ควรเรียกใช้ bazel build //... และ bazel test //... ใน Branch ที่เสถียรได้สำเร็จเสมอ เป้าหมายที่จำเป็นแต่ไม่ได้สร้างขึ้นในบางสถานการณ์ (เช่น ต้องใช้แฟล็กบิลด์ที่เฉพาะเจาะจง ไม่ได้สร้างขึ้นในแพลตฟอร์มหนึ่งๆ ต้องมีข้อตกลงสิทธิ์การใช้งาน) ควรมีการติดแท็กให้เฉพาะเจาะจงมากที่สุด (เช่น "requires-osx") การติดแท็กนี้ช่วยให้กรองเป้าหมายได้ในระดับที่ละเอียดกว่าแท็ก "manual" และช่วยให้ผู้ที่ตรวจสอบไฟล์ BUILD เข้าใจข้อจำกัดของเป้าหมาย
ทรัพยากร Dependency ของบุคคลที่สาม
คุณประกาศทรัพยากร Dependency ของบุคคลที่สามได้ดังนี้
- ประกาศเป็นที่เก็บระยะไกลในไฟล์
MODULE.bazel - หรือวางไว้ในไดเรกทอรีที่ชื่อ
third_party/ในไดเรกทอรีพื้นที่ทำงาน
การใช้ไบนารี
ควรสร้างทุกอย่างจากแหล่งที่มาทุกครั้งที่เป็นไปได้ โดยทั่วไปหมายความว่าแทนที่จะใช้ไลบรารี some-library.so คุณจะสร้างไฟล์ BUILD และสร้าง some-library.so จากแหล่งที่มา แล้วใช้เป้าหมายนั้น
การสร้างจากแหล่งที่มาเสมอจะช่วยให้มั่นใจได้ว่าบิลด์ไม่ได้ใช้ไลบรารีที่สร้างขึ้นด้วยแฟล็กที่ไม่เข้ากันหรือสถาปัตยกรรมที่แตกต่างกัน นอกจากนี้ยังมีฟีเจอร์บางอย่าง เช่น ความครอบคลุม การวิเคราะห์แบบคงที่ หรือการวิเคราะห์แบบไดนามิกที่ทำงานกับแหล่งที่มาเท่านั้น
การกำหนดเวอร์ชัน
ควรสร้างโค้ดทั้งหมดจาก Head ทุกครั้งที่เป็นไปได้ เมื่อต้องใช้เวอร์ชัน ให้หลีกเลี่ยงการใส่เวอร์ชันในชื่อเป้าหมาย (เช่น //guava ไม่ใช่ //guava-20.0) การตั้งชื่อแบบนี้จะช่วยให้อัปเดตไลบรารีได้ง่ายขึ้น (ต้องอัปเดตเป้าหมายเดียวเท่านั้น) นอกจากนี้ยังมีความยืดหยุ่นมากขึ้นในการจัดการปัญหาทรัพยากร Dependency แบบ Diamond หากไลบรารีหนึ่งใช้ guava-19.0 และอีกไลบรารีใช้ guava-20.0 คุณอาจได้ไลบรารีที่พยายามใช้ 2 เวอร์ชันที่แตกต่างกัน
หากคุณสร้างนามแฝงที่ทำให้เข้าใจผิดเพื่อชี้เป้าหมายทั้ง 2 ไปยังไลบรารี guava เดียว ไฟล์ BUILD ก็จะทำให้เข้าใจผิด
การใช้ไฟล์ .bazelrc
สำหรับตัวเลือกที่เฉพาะเจาะจงของโปรเจ็กต์ ให้ใช้ไฟล์การกำหนดค่าของคุณ
workspace/.bazelrc (ดูรูปแบบ bazelrc)
หากต้องการรองรับตัวเลือกต่อผู้ใช้สำหรับโปรเจ็กต์ที่ไม่ ต้องการเช็กอินในการควบคุมแหล่งที่มา ให้ใส่บรรทัด
try-import %workspace%/user.bazelrc
(หรือชื่อไฟล์อื่นๆ) ใน workspace/.bazelrc
และเพิ่ม user.bazelrc ลงใน .gitignore
แพ็กเกจ
ทุกไดเรกทอรีที่มีไฟล์ที่สร้างได้ควรเป็นแพ็กเกจ หากไฟล์ BUILD
อ้างอิงไฟล์ในไดเรกทอรีย่อย (เช่น srcs = ["a/b/C.java"]) แสดงว่าควรเพิ่มไฟล์ BUILD ลงในไดเรกทอรีย่อยนั้น ยิ่งโครงสร้างนี้มีอยู่นานเท่าใด ก็ยิ่งมีแนวโน้มที่จะสร้างทรัพยากร Dependency แบบวงกลมโดยไม่ได้ตั้งใจ ขอบเขตของเป้าหมายจะขยายออกไป และจะต้องอัปเดตทรัพยากร Dependency แบบย้อนกลับจำนวนมากขึ้น