ป้ายกำกับ

รายงานปัญหา ดูแหล่งที่มา

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

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

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

ชื่อที่เก็บ Canonical มักเป็นสตริงที่มีลักษณะคล้ายกับ @@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 คือชื่อเป้าหมายที่ไม่เข้าเกณฑ์ หากค่าตรงกับคอมโพเนนต์สุดท้ายของเส้นทางแพ็กเกจ ระบบอาจละเว้นเครื่องหมายโคลอนและเครื่องหมายโคลอน ดังนั้น ป้ายกำกับทั้งสองนี้จะเทียบเท่ากัน

//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 วิธีในการอ้างอิงไฟล์นี้ภายใน //my/app:BUILD (หนึ่งผิด 1 ข้อ)

ไม่ถูกต้อง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

กฎทุกกฎจะมีชุด แอตทริบิวต์ แอตทริบิวต์ที่เกี่ยวข้องสำหรับกฎที่ระบุ ตลอดจนความสำคัญและความหมายของแต่ละแอตทริบิวต์เป็นฟังก์ชันของประเภทกฎ โปรดดูรายการกฎและแอตทริบิวต์ที่เกี่ยวข้องในสร้างสารานุกรม แต่ละแอตทริบิวต์จะมีชื่อและประเภท ประเภททั่วไปบางประเภทที่แอตทริบิวต์อาจมี ได้แก่ จำนวนเต็ม ป้ายกำกับ รายการป้ายกำกับ สตริง รายการสตริง ป้ายกำกับเอาต์พุต รายการป้ายกำกับเอาต์พุต คุณไม่จำเป็นต้องระบุแอตทริบิวต์บางรายการในทุกกฎ แอตทริบิวต์จึงเป็นเหมือนพจนานุกรม ตั้งแต่คีย์ (ชื่อ) ไปจนถึงค่าที่พิมพ์หรือไม่ก็ได้

แอตทริบิวต์ srcs ที่แสดงในกฎหลายข้อมีประเภท "list of label" และค่าของแอตทริบิวต์นั้นจะเป็นรายการป้ายกำกับ แต่ละค่าจะเป็นชื่อของเป้าหมายที่เป็นอินพุตสำหรับกฎนี้

ในบางกรณี ชื่อประเภทกฎอาจกำหนดชื่อได้ตามต้องการ และน่าสนใจกว่านั้นคือชื่อของไฟล์ที่กฎสร้างขึ้น ซึ่งก็เป็นจริงเกี่ยวกับกฎเกณฑ์ ดูข้อมูลเพิ่มเติมได้ที่กฎทั่วไป: genrule

ในกรณีอื่นๆ ชื่อจะมีนัยสำคัญ เช่น สำหรับกฎ *_binary และ *_test เช่น ชื่อกฎเป็นตัวกำหนดชื่อของไฟล์ปฏิบัติการที่บิลด์สร้างขึ้น

กราฟแบบวนซ้ำที่มีทิศทางของเป้าหมายนี้เรียกว่ากราฟเป้าหมายหรือกราฟการอ้างอิงของบิลด์ และเป็นโดเมนที่เครื่องมือ Query ของ Bazel ทำงาน

เป้าหมาย ไฟล์บิลด์