ป้ายกำกับคือตัวระบุสำหรับเป้าหมาย ป้ายกำกับทั่วไปในรูปแบบ Canonical แบบเต็มจะมีลักษณะดังนี้
@@myrepo//my/app/main:app_binary
ส่วนแรกของป้ายกำกับคือชื่อที่เก็บ @@myrepo
ไวยากรณ์ @
แบบคู่บ่งบอกว่านี่คือชื่อที่เก็บCanonical ซึ่งไม่ซ้ำกันในพื้นที่ทำงาน ป้ายกำกับที่มีชื่อที่เก็บ Canonical จะระบุเป้าหมายอย่างชัดเจนไม่ว่าเป้าหมายนั้นจะปรากฏในบริบทใดก็ตาม
ชื่อที่เก็บ Canonical มักเป็นสตริง Arcane ที่มีลักษณะดังนี้ @@rules_java~7.1.0~toolchains~local_jdk
แต่สิ่งที่เห็นได้บ่อยที่สุดคือป้ายกำกับที่มีชื่อที่เก็บชัดเจน ซึ่งมีลักษณะดังนี้
@myrepo//my/app/main:app_binary
ความแตกต่างเพียงอย่างเดียวคือชื่อที่เก็บที่ขึ้นต้นด้วย @
หนึ่งตัวแทนที่จะเป็น 2 ตัว
โดยหมายถึงที่เก็บที่มีชื่อที่ชัดเจน 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
(แต่ละไดเรกทอรีนี้มีไฟล์ BUILD
ของตัวเอง) แพ็กเกจหลังจะมีไฟล์ชื่อ testdepot.zip
การอ้างอิงไฟล์นี้ภายใน //my/app:BUILD
มี 2 วิธี (แบบผิด 1 อย่าง 1 ข้อ)
ไม่ถูกต้อง — testdata
เป็นแพ็กเกจอื่น คุณจึงใช้เส้นทางแบบสัมพัทธ์ไม่ได้
testdata/testdepot.zip
ถูกต้อง — อ้างอิงถึง testdata
ที่มีเส้นทางแบบเต็ม
//my/app/testdata:testdepot.zip
ป้ายกำกับที่ขึ้นต้นด้วย @@//
จะอ้างอิงไปยังที่เก็บหลัก ซึ่งจะยังคงใช้งานได้จากที่เก็บภายนอก
ดังนั้น @@//a/b/c
จึงแตกต่างจาก //a/b/c
เมื่ออ้างอิงจากที่เก็บภายนอก
โดย URL แรกจะอ้างอิงกลับไปที่ที่เก็บหลัก ส่วนรายการหลังจะมองหา //a/b/c
ในที่เก็บภายนอกเอง
ซึ่งจะมีประโยชน์อย่างยิ่งเมื่อเขียนกฎในที่เก็บหลักที่อ้างถึงเป้าหมายในที่เก็บหลัก และจะใช้จากที่เก็บภายนอก
ดูข้อมูลเกี่ยวกับวิธีต่างๆ ในการอ้างอิงเป้าหมายได้ที่รูปแบบเป้าหมาย
ข้อกำหนดทางพจนานุกรมของป้ายกำกับ
ไวยากรณ์ป้ายกำกับไม่สนับสนุนการใช้อักขระเมตาซึ่งมีความหมายพิเศษต่อเชลล์ ซึ่งช่วยหลีกเลี่ยงปัญหาในการดึงข้อมูลโดยไม่ได้ตั้งใจและสร้างเครื่องมือและสคริปต์ที่จัดการกับป้ายกำกับ เช่น ภาษาการค้นหาบาเซล ได้ง่ายขึ้น
รายละเอียดที่ชัดเจนของชื่อเป้าหมายที่อนุญาตมีดังนี้
ชื่อเป้าหมาย — 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
กฎทุกข้อจะมีชุดแอตทริบิวต์ แอตทริบิวต์ที่เกี่ยวข้องกับกฎนั้นๆ รวมถึงความสำคัญและความหมายของแต่ละแอตทริบิวต์เป็นฟังก์ชันของกฎนั้นๆ โปรดดูรายการกฎและแอตทริบิวต์ที่เกี่ยวข้องในสร้างสารานุกรม แต่ละแอตทริบิวต์จะมีชื่อและประเภท ประเภททั่วไปบางส่วนที่แอตทริบิวต์อาจมี ได้แก่ จำนวนเต็ม ป้ายกำกับ รายการป้ายกำกับ สตริง รายการสตริง ป้ายกำกับเอาต์พุต รายการป้ายกำกับเอาต์พุต คุณไม่จำเป็นต้องระบุแอตทริบิวต์ทุกรายการในกฎทุกข้อ แอตทริบิวต์จึงเป็นเหมือนพจนานุกรมตั้งแต่คีย์ (ชื่อ) ไปจนถึงค่าที่พิมพ์หรือไม่ก็ได้
แอตทริบิวต์ srcs
ที่แสดงในกฎหลายข้อมีประเภทเป็น "list of labels" ซึ่งค่า หากมี จะเป็นรายการป้ายกำกับ แต่ละกฎจะเป็นชื่อของเป้าหมายที่เป็นอินพุตสำหรับกฎนี้
ในบางกรณี ชื่อประเภทกฎจะเป็นแบบอิสระและน่าสนใจกว่าคือชื่อของไฟล์ที่กฎสร้างขึ้น และเป็นความจริงเกี่ยวกับ Genrules ดูข้อมูลเพิ่มเติมได้ที่กฎทั่วไป: genRule
ในกรณีอื่นๆ ชื่อจะมีนัยสำคัญ เช่น สำหรับกฎ *_binary
และ *_test
เช่น ชื่อกฎจะเป็นตัวกำหนดชื่อของไฟล์ปฏิบัติการที่สร้างจากบิลด์
กราฟแบบวนซ้ำที่มีทิศทางตรงกับเป้าหมายนี้เรียกว่ากราฟเป้าหมายหรือกราฟการสร้างการอ้างอิง และเป็นโดเมนที่เครื่องมือ Query ของ Bazel ทำงาน
เป้าหมาย | สร้างไฟล์ |