เป้าหมายทั้งหมดเป็นของแพ็กเกจเดียวเท่านั้น ชื่อของเป้าหมายเรียกว่า ป้ายกำกับ ป้ายกำกับแต่ละรายการจะระบุเป้าหมายที่ไม่ซ้ำกัน ป้ายกำกับทั่วไปในรูปแบบ Canonical มีลักษณะดังนี้
@myrepo//my/app/main:app_binary
ส่วนแรกของป้ายกำกับคือชื่อที่เก็บ @myrepo//
ในกรณีทั่วไปที่ป้ายกำกับอ้างอิงถึงที่เก็บเดียวกันกับที่ใช้ ตัวระบุที่เก็บอาจย่อเป็น //
ดังนั้น ภายใน @myrepo โดยปกติแล้วป้ายกำกับนี้จะเขียนเป็น
//my/app/main:app_binary
ส่วนที่ 2 ของป้ายกำกับคือชื่อแพ็กเกจที่ไม่สมบูรณ์ my/app/main ซึ่งเป็นเส้นทางไปยังแพ็กเกจที่สัมพันธ์กับรูทของที่เก็บ ชื่อที่เก็บและชื่อแพ็กเกจที่ไม่สมบูรณ์รวมกันเป็นชื่อแพ็กเกจที่สมบูรณ์ @myrepo//my/app/main เมื่อป้ายกำกับอ้างอิงถึงแพ็กเกจเดียวกันกับที่ใช้ ระบบอาจละเว้นชื่อแพ็กเกจ (และเครื่องหมายโคลอน) ได้ ดังนั้น ภายใน @myrepo//my/app/main ป้ายกำกับนี้อาจเขียนได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
app_binary
:app_binary
การละเว้นเครื่องหมายโคลอนสำหรับไฟล์แต่เก็บไว้สำหรับกฎเป็นเพียงเรื่องของธรรมเนียมปฏิบัติเท่านั้น ไม่ได้มีความสำคัญอย่างอื่น
ส่วนของป้ายกำกับหลังเครื่องหมายโคลอน app_binary คือชื่อเป้าหมายที่ไม่สมบูรณ์ เมื่อตรงกับคอมโพเนนต์สุดท้ายของเส้นทางแพ็กเกจ ระบบอาจละเว้นคอมโพเนนต์นั้นและเครื่องหมายโคลอนได้ ดังนั้น ป้ายกำกับ 2 รายการต่อไปนี้จึงมีความหมายเหมือนกัน
//my/app/lib
//my/app/lib:lib
ชื่อเป้าหมายไฟล์ในไดเรกทอรีย่อยของแพ็กเกจคือเส้นทางของไฟล์ที่สัมพันธ์กับรูทของแพ็กเกจ (ไดเรกทอรีที่มีไฟล์ BUILD) ดังนั้น ไฟล์นี้จึงอยู่ในไดเรกทอรีย่อย my/app/main/testdata ของที่เก็บ
//my/app/main:testdata/input.txt
สตริง เช่น //my/app และ @some_repo//my/app มี 2 ความหมายขึ้นอยู่กับ
บริบทที่ใช้ กล่าวคือ เมื่อ Bazel คาดหวังป้ายกำกับ สตริงเหล่านี้จะหมายถึง
//my/app:app และ @some_repo//my/app:app ตามลำดับ แต่เมื่อ Bazel คาดหวังแพ็กเกจ (เช่น ในข้อกำหนด package_group) สตริงเหล่านี้จะอ้างอิงถึงแพ็กเกจที่มีป้ายกำกับนั้น
ข้อผิดพลาดที่พบบ่อยในไฟล์ BUILD คือการใช้ //my/app เพื่ออ้างอิงถึงแพ็กเกจหรือเป้าหมาย ทั้งหมด ในแพ็กเกจ ซึ่งไม่ถูกต้อง โปรดทราบว่า มีความหมายเหมือนกับ //my/app:app ดังนั้นจึงตั้งชื่อเป้าหมาย app ในแพ็กเกจ my/app ของที่เก็บปัจจุบัน
อย่างไรก็ตาม เราขอแนะนำให้ใช้ //my/app เพื่ออ้างอิงถึงแพ็กเกจในการระบุ package_group หรือในไฟล์ .bzl เนื่องจากวิธีนี้จะสื่อสารอย่างชัดเจนว่าชื่อแพ็กเกจเป็นแบบสัมบูรณ์และอยู่ในไดเรกทอรีระดับบนสุดของพื้นที่ทำงาน
คุณใช้ป้ายกำกับแบบสัมพัทธ์เพื่ออ้างอิงถึงเป้าหมายในแพ็กเกจอื่นไม่ได้ ในกรณีนี้ คุณต้องระบุตัวระบุที่เก็บและชื่อแพ็กเกจเสมอ
ตัวอย่างเช่น หากต้นไม้แหล่งที่มามีทั้งแพ็กเกจ my/app และ
แพ็กเกจ my/app/testdata (ไดเรกทอรีทั้ง 2 รายการนี้มีไฟล์
BUILD ของตัวเอง) แพ็กเกจหลังจะมีไฟล์ชื่อ testdepot.zip ต่อไปนี้คือ 2 วิธี (วิธีหนึ่งผิด อีกวิธีหนึ่งถูก) ในการอ้างอิงถึงไฟล์นี้ภายใน //my/app:BUILD
ผิด — testdata เป็นแพ็กเกจอื่น ดังนั้นคุณจึงใช้เส้นทางแบบสัมพัทธ์ไม่ได้
testdata/testdepot.zip
ถูก — อ้างอิงถึง testdata ด้วยเส้นทางแบบเต็ม
//my/app/testdata:testdepot.zipป้ายกำกับที่ขึ้นต้นด้วย @// เป็นการอ้างอิงถึงที่เก็บหลัก ซึ่งจะยังคงใช้งานได้แม้จากที่เก็บภายนอก
ดังนั้น @//a/b/c จึงแตกต่างจาก
//a/b/c เมื่ออ้างอิงจากที่เก็บภายนอก
ป้ายกำกับแรกจะอ้างอิงกลับไปยังที่เก็บหลัก ส่วนป้ายกำกับหลังจะค้นหา //a/b/c ในที่เก็บภายนอกเอง
วิธีนี้มีประโยชน์อย่างยิ่งเมื่อเขียนกฎในที่เก็บหลักที่อ้างอิงถึงเป้าหมายในที่เก็บหลัก และจะใช้จากที่เก็บภายนอก
ดูข้อมูลเกี่ยวกับวิธีต่างๆ ที่คุณอ้างอิงถึงเป้าหมายได้ที่ รูปแบบเป้าหมาย
ข้อกำหนดทางไวยากรณ์ของป้ายกำกับ
ไวยากรณ์ของป้ายกำกับไม่แนะนำให้ใช้อักขระเมตาที่มีความหมายพิเศษสำหรับเชลล์ ซึ่งจะช่วยหลีกเลี่ยงปัญหาการใส่เครื่องหมายคำพูดโดยไม่ตั้งใจ และช่วยให้สร้างเครื่องมือและสคริปต์ที่จัดการป้ายกำกับได้ง่ายขึ้น เช่น ภาษาการค้นหาของ Bazel
รายละเอียดที่ชัดเจนเกี่ยวกับชื่อเป้าหมายที่อนุญาตมีดังนี้
ชื่อเป้าหมาย — package-name:target-name
target-name คือชื่อของเป้าหมายภายในแพ็กเกจ ชื่อของกฎคือค่าของแอตทริบิวต์ name ในการประกาศกฎในไฟล์ BUILD ส่วนชื่อของไฟล์คือชื่อเส้นทางที่สัมพันธ์กับไดเรกทอรีที่มีไฟล์ BUILD
ชื่อเป้าหมายต้องประกอบด้วยอักขระทั้งหมดจากชุด a–z,
A–Z, 0–9, และสัญลักษณ์เครื่องหมายวรรคตอน !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
ชื่อไฟล์ต้องเป็นชื่อเส้นทางแบบสัมพัทธ์ในรูปแบบปกติ ซึ่งหมายความว่าชื่อไฟล์ต้อง
ไม่ขึ้นต้นหรือลงท้ายด้วยเครื่องหมายทับ (เช่น ห้ามใช้ /foo และ foo/
และต้องไม่มีเครื่องหมายทับหลายรายการติดต่อกันเป็นตัวคั่นเส้นทาง
(เช่น foo//bar) ในทำนองเดียวกัน ระบบจะไม่อนุญาตการอ้างอิงระดับบน (..) และ
การอ้างอิงไดเรกทอรีปัจจุบัน (./)
ผิด — ห้ามใช้ `..` เพื่ออ้างอิงถึงไฟล์ในแพ็กเกจอื่น
ถูก — ใช้ `//package-name:filename`
แม้ว่าโดยทั่วไปจะใช้ / ในชื่อเป้าหมายไฟล์ แต่ให้หลีกเลี่ยงการใช้ / ในชื่อกฎ โดยเฉพาะอย่างยิ่งเมื่อใช้รูปแบบย่อของป้ายกำกับ ซึ่งอาจทำให้ผู้อ่านสับสนได้ ป้ายกำกับ //foo/bar/wiz เป็นรูปแบบย่อ
ของ //foo/bar/wiz:wiz เสมอ แม้ว่าจะไม่มีแพ็กเกจ foo/bar/wiz ก็ตาม และจะไม่ใช่ //foo:bar/wiz แม้ว่าเป้าหมายนั้นจะมีอยู่ก็ตาม
อย่างไรก็ตาม มีบางสถานการณ์ที่การใช้เครื่องหมายทับสะดวกหรือบางครั้งจำเป็นด้วยซ้ำ ตัวอย่างเช่น ชื่อของกฎบางข้อต้องตรงกับไฟล์แหล่งที่มาหลัก ซึ่งอาจอยู่ในไดเรกทอรีย่อยของแพ็กเกจ
ชื่อแพ็กเกจ — //package-name:target-name
ชื่อของแพ็กเกจคือชื่อของไดเรกทอรีที่มีไฟล์ BUILD ซึ่งสัมพันธ์กับไดเรกทอรีระดับบนสุดของที่เก็บที่มีแพ็กเกจนั้นอยู่
เช่น my/app
ชื่อแพ็กเกจต้องประกอบด้วยอักขระทั้งหมดจากชุด
A-Z, a–z, 0–9, '/', '-', '.', '@' และ '_' และต้องไม่
ขึ้นต้นด้วยเครื่องหมายทับ
สำหรับภาษาที่มีโครงสร้างไดเรกทอรีที่สำคัญต่อระบบโมดูล (เช่น Java) คุณควรเลือกชื่อไดเรกทอรีที่เป็นตัวระบุที่ถูกต้องในภาษาดังกล่าว
แม้ว่า Bazel จะรองรับเป้าหมายในแพ็กเกจรูทของเวิร์กสเปซ (เช่น //:foo) แต่ควรปล่อยให้แพ็กเกจนั้นว่างไว้เพื่อให้แพ็กเกจที่มีความหมายทั้งหมดมีชื่อที่สื่อความหมาย
ชื่อแพ็กเกจต้องไม่มีสตริงย่อย // และต้องไม่ลงท้ายด้วยเครื่องหมายทับ
กฎ
กฎจะระบุความสัมพันธ์ระหว่างอินพุตกับเอาต์พุต รวมถึงขั้นตอนในการสร้างเอาต์พุต กฎมีหลายประเภท (บางครั้งเรียกว่า คลาสกฎ) ซึ่งสร้างไฟล์ปฏิบัติการและไลบรารีที่คอมไพล์แล้ว ไฟล์ปฏิบัติการทดสอบ และเอาต์พุตอื่นๆ ที่รองรับตามที่อธิบายไว้ใน Build Encyclopedia
ไฟล์ BUILD จะประกาศ เป้าหมาย โดยการเรียกใช้ กฎ
ในตัวอย่างด้านล่าง เราจะเห็นการประกาศเป้าหมาย my_app โดยใช้กฎ cc_binary
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
การเรียกใช้กฎแต่ละรายการจะมีแอตทริบิวต์ name (ซึ่งต้องเป็น
ชื่อเป้าหมายที่ถูกต้อง) ที่ประกาศเป้าหมายภายในแพ็กเกจ
ของไฟล์ BUILD
กฎแต่ละข้อจะมีชุด แอตทริบิวต์ แอตทริบิวต์ที่ใช้ได้สำหรับ กฎที่กำหนด รวมถึงความสำคัญและความหมายของแอตทริบิวต์แต่ละรายการจะขึ้นอยู่กับ ชนิดของกฎ โปรดดูรายการกฎและแอตทริบิวต์ที่เกี่ยวข้องใน Build Encyclopedia แอตทริบิวต์แต่ละรายการจะมีชื่อและประเภท ประเภททั่วไปบางประเภทที่แอตทริบิวต์อาจมี ได้แก่ จำนวนเต็ม ป้ายกำกับ รายการป้ายกำกับ สตริง รายการสตริง ป้ายกำกับเอาต์พุต รายการป้ายกำกับเอาต์พุต คุณไม่จำเป็นต้องระบุแอตทริบิวต์ทั้งหมดในทุกกฎ ดังนั้น แอตทริบิวต์จึงสร้างพจนานุกรมจากคีย์ (ชื่อ) ไปยังค่าที่มีประเภทซึ่งไม่บังคับ
แอตทริบิวต์ srcs ที่มีอยู่ในกฎหลายข้อมีประเภทเป็น "รายการป้ายกำกับ" ค่าของแอตทริบิวต์นี้ (หากมี) คือรายการป้ายกำกับ ซึ่งแต่ละรายการเป็นชื่อของเป้าหมายที่เป็นอินพุตของกฎนี้
ในบางกรณี ชื่อประเภทกฎอาจค่อนข้างกำหนดขึ้นเอง และสิ่งที่น่าสนใจกว่าคือชื่อไฟล์ที่กฎสร้างขึ้น ซึ่งเป็นกรณีของ genrule ดูข้อมูลเพิ่มเติมได้ที่ กฎทั่วไป: genrule
ในกรณีอื่นๆ ชื่อมีความสำคัญ เช่น สำหรับกฎ *_binary และ *_test ชื่อกฎจะกำหนดชื่อของไฟล์ปฏิบัติการที่สร้างขึ้นโดยการบิลด์
กราฟแบบมีทิศทางและไม่มีวงจรนี้เหนือเป้าหมายเรียกว่า กราฟเป้าหมาย หรือ กราฟทรัพยากร Dependency ของการบิลด์ และเป็นโดเมนที่ เครื่องมือการค้นหาของ Bazel ทำงาน
| เป้าหมาย | ไฟล์ BUILD |