ป้ายกำกับ

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ป้ายกํากับคือตัวระบุเป้าหมาย ป้ายกำกับปกติในแบบฟอร์ม Canonical แบบเต็มจะมีลักษณะดังนี้

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

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

โดยปกติแล้วชื่อที่ถูกต้องของรีโปจะเป็นสตริงที่อ่านไม่ออกซึ่งมีลักษณะดังนี้ @@rules_java~7.1.0~toolchains~local_jdk สิ่งที่พบได้บ่อยกว่าคือป้ายกำกับที่มีชื่อที่ชัดเจนของรีโป ซึ่งมีลักษณะดังนี้

@myrepo//my/app/main:app_binary

ความแตกต่างเพียงอย่างเดียวคือชื่อรีโปจะมี @ อยู่หน้าชื่อ 1 ตัวแทนที่จะเป็น 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 ต่อไปนี้คือ 2 วิธี (1 วิธีไม่ถูกต้อง 1 วิธีถูกต้อง) ในการอ้างอิงไฟล์นี้ภายใน//my/app:BUILD

ไม่ถูกต้องtestdata เป็นแพ็กเกจอื่น คุณจึงใช้เส้นทางแบบสัมพัทธ์ไม่ได้

testdata/testdepot.zip

ถูกต้อง — อ้างอิง testdata ด้วยเส้นทางแบบเต็ม

//my/app/testdata:testdepot.zip

ป้ายกำกับที่ขึ้นต้นด้วย @@// เป็นการอ้างอิงถึงที่เก็บหลัก ซึ่งจะยังใช้งานได้แม้จากที่เก็บภายนอก ดังนั้น @@//a/b/c จึงแตกต่างจาก //a/b/c เมื่ออ้างอิงจากที่เก็บข้อมูลภายนอก เครื่องมือแรกอ้างอิงกลับไปยังที่เก็บหลัก ส่วนที่อยู่หลังจะมองหา //a/b/c ในที่เก็บภายนอก ซึ่งมีความเกี่ยวข้องอย่างยิ่งเมื่อเขียนกฎในที่เก็บข้อมูลหลักซึ่งอ้างอิงถึงเป้าหมายในที่เก็บข้อมูลหลัก และจะใช้จากที่เก็บข้อมูลภายนอก

ดูข้อมูลเกี่ยวกับวิธีต่างๆ ในการอ้างอิงเป้าหมายได้ที่รูปแบบเป้าหมาย

ข้อกำหนดเชิงศัพท์ของป้ายกำกับ

ไวยากรณ์ของป้ายกำกับไม่แนะนำให้ใช้อักขระเมตาที่มีความหมายพิเศษสำหรับเชลล์ วิธีนี้ช่วยหลีกเลี่ยงปัญหาการอ้างอิงโดยไม่ตั้งใจ และช่วยให้สร้างเครื่องมือและสคริปต์ที่จัดการกับป้ายกำกับได้ง่ายขึ้น เช่น Bazel Query Language

รายละเอียดที่แน่นอนของชื่อเป้าหมายที่อนุญาตมีดังนี้

ชื่อเป้าหมาย — 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

ชื่อแพ็กเกจต้องประกอบด้วยอักขระจากชุด A-Z, az, 09, '/', '-', '.', '@' และ '_' เท่านั้น และต้องไม่ขึ้นต้นด้วยเครื่องหมายทับ

สำหรับภาษาที่มีโครงสร้างไดเรกทอรีที่สำคัญต่อระบบโมดูล (เช่น 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 ชื่อกฎจะเป็นตัวกําหนดชื่อไฟล์ปฏิบัติการที่บิลด์สร้างขึ้น

กราฟแบบ Directed Acyclic Graph นี้เหนือเป้าหมายเรียกว่ากราฟเป้าหมายหรือกราฟทรัพยากร Dependency ของการสร้าง และเป็นโดเมนที่เครื่องมือการค้นหา Bazel ทำงาน

เป้าหมาย ไฟล์ BUILD