ป้ายกำกับ

ป้ายกำกับ คือตัวระบุเป้าหมาย ป้ายกำกับทั่วไปในรูปแบบ Canonical ที่สมบูรณ์จะมีลักษณะดังนี้

@@myrepo//my/app/main:app_binary

ส่วนแรกของป้ายกำกับคือชื่อที่เก็บ @@myrepo ไวยากรณ์ @ คู่หมายความว่านี่คือชื่อที่เก็บ Canonical ซึ่งไม่ซ้ำกันภายใน พื้นที่ทำงาน ป้ายกำกับที่มีชื่อที่เก็บ Canonical จะระบุเป้าหมายได้อย่างชัดเจนไม่ว่าป้ายกำกับจะปรากฏในบริบทใดก็ตาม

โดยส่วนใหญ่แล้วชื่อที่เก็บ Canonical จะเป็นสตริงที่เข้าใจยากซึ่งมีลักษณะดังนี้ @@rules_java++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 (ไดเรกทอรีทั้ง 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

ชื่อเป้าหมายต้องประกอบด้วยอักขระทั้งหมดจากชุด az, AZ, 09, และสัญลักษณ์เครื่องหมายวรรคตอน !%-@^_"#$&'()*-+,;<=>?[]{|}~/.

ชื่อไฟล์ต้องเป็นชื่อเส้นทางแบบสัมพัทธ์ในรูปแบบปกติ ซึ่งหมายความว่าชื่อไฟล์ต้อง ไม่ขึ้นต้นหรือลงท้ายด้วยเครื่องหมายทับ (เช่น /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 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