ป้ายกํากับคือตัวระบุเป้าหมาย ป้ายกํากับทั่วไปในรูปแบบแคโนนิกแบบเต็มมีลักษณะดังนี้
@@myrepo//my/app/main:app_binary
ส่วนแรกของป้ายกำกับคือชื่อที่เก็บ @@myrepo
รูปแบบ @
แบบคู่บ่งบอกว่านี่คือชื่อรีโป Canonical ซึ่งไม่ซ้ำกันภายใน Workspace ป้ายกำกับที่มีชื่อที่ถูกต้องตามหลักเกณฑ์ของที่เก็บข้อมูลจะระบุเป้าหมายอย่างชัดเจนไม่ว่าจะปรากฏในบริบทใดก็ตาม
บ่อยครั้งที่ชื่อที่ถูกต้องของรีโปจะเป็นสตริงที่อ่านไม่ออกซึ่งมีลักษณะดังนี้
@@rules_java++toolchains+local_jdk
สิ่งที่พบได้บ่อยกว่าคือป้ายกำกับที่มีชื่อที่ชัดเจนของรีโป ซึ่งมีลักษณะดังนี้
@myrepo//my/app/main:app_binary
ความแตกต่างเพียงอย่างเดียวคือชื่อรีโปจะมี @
อยู่หน้าชื่อ 1 ตัวแทนที่จะเป็น 2 ตัว
หมายถึงที่เก็บซึ่งมีชื่อที่ปรากฏว่า myrepo
ซึ่งอาจแตกต่างกันไปโดยขึ้นอยู่กับบริบทที่ป้ายกำกับนี้ปรากฏ
ในกรณีทั่วไปที่ป้ายกำกับอ้างอิงถึงที่เก็บเดียวกันกับที่ใช้ป้ายกำกับนั้น คุณอาจไม่ต้องใส่ส่วนชื่อที่เก็บ ดังนั้นภายใน @@myrepo
ป้ายกำกับแรกมักจะเขียนเป็น
//my/app/main:app_binary
ส่วนที่สองของป้ายกำกับคือชื่อแพ็กเกจแบบไม่ระบุข้อกำหนด 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 วิธี (1 วิธีไม่ถูกต้อง 1 วิธีถูกต้อง) ในการอ้างอิงไฟล์นี้ภายใน//my/app:BUILD
ไม่ถูกต้อง — testdata
เป็นแพ็กเกจอื่น คุณจึงใช้เส้นทางแบบสัมพัทธ์ไม่ได้
testdata/testdepot.zip
ถูกต้อง — อ้างอิง testdata
ด้วยเส้นทางแบบเต็ม
//my/app/testdata:testdepot.zip
ป้ายกำกับที่ขึ้นต้นด้วย @@//
เป็นการอ้างอิงถึงที่เก็บข้อมูลหลัก ซึ่งจะยังคงใช้งานได้แม้ว่าจะมาจากที่เก็บข้อมูลภายนอกก็ตาม
ดังนั้น @@//a/b/c
จึงแตกต่างจาก //a/b/c
เมื่ออ้างอิงจากที่เก็บข้อมูลภายนอก
รายการแรกจะอ้างอิงกลับไปยังที่เก็บข้อมูลหลัก ส่วนรายการที่ 2 จะค้นหา //a/b/c
ในที่เก็บข้อมูลภายนอก
ซึ่งมีความเกี่ยวข้องอย่างยิ่งเมื่อเขียนกฎในที่เก็บข้อมูลหลักซึ่งอ้างอิงเป้าหมายในที่เก็บข้อมูลหลัก และจะใช้จากที่เก็บข้อมูลภายนอก
ดูข้อมูลเกี่ยวกับวิธีต่างๆ ในการอ้างอิงเป้าหมายได้ที่รูปแบบเป้าหมาย
ข้อกำหนดเชิงคําของป้ายกำกับ
ไวยากรณ์ของป้ายกํากับไม่แนะนําให้ใช้อักขระเมตาที่มีความหมายพิเศษสําหรับเชลล์ วิธีนี้ช่วยหลีกเลี่ยงปัญหาการอ้างอิงโดยไม่ตั้งใจ และช่วยให้สร้างเครื่องมือและสคริปต์ที่จัดการกับป้ายกำกับได้ง่ายขึ้น เช่น Bazel Query Language
รายละเอียดที่แน่นอนของชื่อเป้าหมายที่อนุญาตมีดังนี้
ชื่อเป้าหมาย — 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
ในระดับเทคนิค Bazel จะบังคับใช้สิ่งต่อไปนี้
- อักขระที่อนุญาตในชื่อแพ็กเกจ ได้แก่ ตัวอักษรพิมพ์เล็ก
a
ถึงz
, ตัวอักษรพิมพ์ใหญ่A
ถึงZ
, ตัวเลข0
ถึง9
, อักขระ! \"#$%&'()*+,-.;<=>?@[]^_`{|}
(ใช่ มีอักขระเว้นวรรคอยู่ด้วย) และแน่นอน ทับ/
(เนื่องจากเป็นตัวคั่นไดเรกทอรี) - ชื่อแพ็กเกจต้องไม่ขึ้นต้นหรือลงท้ายด้วยเครื่องหมายทับ
/
- ชื่อแพ็กเกจต้องไม่มีสตริงย่อย
//
การดำเนินการนี้ไม่สมเหตุสมผล เส้นทางไดเรกทอรีที่เกี่ยวข้องควรเป็นอย่างไร - ชื่อแพ็กเกจต้องไม่มีสตริงย่อย
/./
หรือ/../
หรือ/.../
ฯลฯ การบังคับใช้นี้ทำเพื่อไม่ให้เกิดความสับสนเมื่อแปลระหว่างชื่อแพ็กเกจเชิงตรรกะกับชื่อไดเรกทอรีจริง โดยพิจารณาจากความหมายเชิงความหมายของอักขระจุดในสตริงเส้นทาง
ในแง่ปฏิบัติ
- สําหรับภาษาที่มีโครงสร้างไดเรกทอรีที่สําคัญต่อระบบโมดูล (เช่น Java) การเลือกชื่อไดเรกทอรีที่ถูกต้องในภาษานั้นๆ จึงเป็นเรื่องสําคัญ เช่น อย่าขึ้นต้นด้วยตัวเลขและหลีกเลี่ยงการใช้สัญลักษณ์พิเศษ โดยเฉพาะขีดล่างและขีดกลาง
- แม้ว่า Bazel จะรองรับเป้าหมายในแพ็กเกจรูทของเวิร์กスペース (เช่น
//:foo
) แต่คุณควรปล่อยแพ็กเกจนั้นว่างไว้เพื่อให้แพ็กเกจที่มีความหมายทั้งหมดมีชื่อที่สื่อความหมาย
กฎ
กฎจะระบุความสัมพันธ์ระหว่างอินพุตและเอาต์พุต รวมถึงขั้นตอนในการสร้างเอาต์พุต กฎอาจมีได้หลายประเภท (บางครั้งเรียกว่าคลาสกฎ) ซึ่งจะสร้างไฟล์ปฏิบัติการและไลบรารีที่คอมไพล์แล้ว ไฟล์ปฏิบัติการทดสอบ และเอาต์พุตอื่นๆ ที่รองรับตามที่อธิบายไว้ในสารานุกรมการสร้าง
ไฟล์ BUILD
จะประกาศเป้าหมายโดยการเรียกใช้กฎ
ในตัวอย่างด้านล่าง เราเห็นการประกาศเป้าหมาย my_app
ใช้กฎ cc_binary
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
การเรียกใช้กฎแต่ละรายการมีแอตทริบิวต์ name
(ต้องเป็นชื่อเป้าหมายที่ถูกต้อง) ซึ่งประกาศเป้าหมายภายในแพ็กเกจของไฟล์ BUILD
กฎทุกข้อมีชุดแอตทริบิวต์ แอตทริบิวต์ที่เกี่ยวข้องสำหรับกฎหนึ่งๆ ตลอดจนความสำคัญและความหมายของแอตทริบิวต์แต่ละรายการจะขึ้นอยู่กับประเภทของกฎ ดูรายการกฎและแอตทริบิวต์ที่เกี่ยวข้องได้ในสารานุกรม Build แอตทริบิวต์แต่ละรายการมีชื่อและประเภท แอตทริบิวต์อาจมีประเภททั่วไปบางประเภท เช่น จำนวนเต็ม ป้ายกำกับ รายการป้ายกำกับ สตริง รายการสตริง ป้ายกำกับเอาต์พุต รายการป้ายกำกับเอาต์พุต คุณไม่จำเป็นต้องระบุแอตทริบิวต์ทั้งหมดในกฎทุกข้อ แอตทริบิวต์จึงทำหน้าที่เป็นพจนานุกรมจากคีย์ (ชื่อ) ไปยังค่าที่มีการจัดประเภทซึ่งไม่บังคับ
แอตทริบิวต์ srcs
ที่มีอยู่ในกฎหลายข้อมีประเภทเป็น "รายการป้ายกำกับ" ค่าของแอตทริบิวต์นี้คือรายการป้ายกำกับ (หากมี) โดยแต่ละรายการจะเป็นชื่อของเป้าหมายที่เป็นอินพุตของกฎนี้
ในบางกรณี ชื่อของประเภทกฎอาจกำหนดขึ้นเอง และที่น่าสนใจกว่าคือชื่อของไฟล์ที่กฎสร้างขึ้น ซึ่งในกรณีนี้ก็คือ genrules ดูข้อมูลเพิ่มเติมได้ที่กฎทั่วไป: genrule
ในกรณีอื่นๆ ชื่อจะมีความหมาย เช่น สําหรับกฎ *_binary
และ *_test
ชื่อกฎจะเป็นตัวกําหนดชื่อไฟล์ปฏิบัติการที่บิลด์สร้างขึ้น
กราฟแบบมีทิศทางซึ่งไม่มีวงรอบนี้บนเป้าหมายเรียกว่ากราฟเป้าหมายหรือกราฟทรัพยากร Dependency ของการสร้าง และเป็นโดเมนที่เครื่องมือการค้นหา Bazel ทำงาน
เป้าหมาย | ไฟล์ BUILD |