ป้ายกำกับ

รายงานปัญหา ดูแหล่งที่มา รุ่น 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

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

ชื่อแพ็กเกจต้องประกอบด้วยอักขระทั้งหมดจากชุดนั้น 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