ฟังก์ชัน

เนื้อหา

package

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

ฟังก์ชันนี้ประกาศข้อมูลเมตาที่มีผลกับทุกกฎในแพ็กเกจ โดยใช้ได้ไม่เกิน 1 ครั้งภายในแพ็กเกจ (ไฟล์ BUILD)

หากต้องการใช้ฟังก์ชันที่ประกาศข้อมูลเมตาที่มีผลกับทุกกฎใน ที่เก็บทั้งหมด ให้ใช้ฟังก์ชัน repo() ใน REPO.bazel ไฟล์ ที่รูทของที่เก็บ ฟังก์ชัน repo() จะใช้อาร์กิวเมนต์เดียวกันกับ package() ทุกประการ

ควรเรียกใช้ฟังก์ชัน package() ทันทีหลังจากคำสั่ง load() ทั้งหมดที่ด้านบนของไฟล์ ก่อนกฎใดๆ

อาร์กิวเมนต์

แอตทริบิวต์ คำอธิบาย
default_applicable_licenses

อีเมลแทนสำหรับ default_package_metadata

default_visibility

รายการป้ายกำกับ ค่าเริ่มต้นคือ []

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

ดูข้อมูลโดยละเอียดเกี่ยวกับไวยากรณ์ของแอตทริบิวต์นี้ได้ใน เอกสารประกอบของ visibility ระดับการเข้าถึงเริ่มต้นของแพ็กเกจจะไม่มีผลกับ exports_files ซึ่งเป็นสาธารณะโดยค่าเริ่มต้น

default_deprecation

สตริง ค่าเริ่มต้นคือ ""

ตั้งค่าข้อความ deprecation เริ่มต้นสำหรับกฎทั้งหมดในแพ็กเกจนี้

default_package_metadata

รายการป้ายกำกับ ค่าเริ่มต้นคือ []

ตั้งค่ารายการเป้าหมายข้อมูลเมตาเริ่มต้นที่มีผลกับเป้าหมายอื่นๆ ทั้งหมดในแพ็กเกจ โดยปกติแล้วเป้าหมายเหล่านี้จะเกี่ยวข้องกับแพ็กเกจ OSS และการประกาศใบอนุญาต ดูตัวอย่างได้ที่ rules_license

default_testonly

บูลีน ค่าเริ่มต้นคือ False ยกเว้นที่ระบุไว้

ตั้งค่าพร็อพเพอร์ตี้ testonly เริ่มต้นสำหรับกฎทั้งหมดในแพ็กเกจนี้

ในแพ็กเกจภายใต้ javatests ค่าเริ่มต้นคือ True

features

รายการสตริง ค่าเริ่มต้นคือ []

ตั้งค่าแฟล็กต่างๆ ที่ส่งผลต่อความหมายของไฟล์ BUILD นี้

ฟีเจอร์นี้ส่วนใหญ่ใช้โดยผู้ที่ทำงานในระบบบิลด์เพื่อ ติดแท็กแพ็กเกจที่ต้องมีการจัดการพิเศษบางอย่าง อย่าใช้ฟีเจอร์นี้ เว้นแต่จะได้รับคำขออย่างชัดเจนจากผู้ที่ทำงานในระบบบิลด์

ตัวอย่าง

การประกาศด้านล่างประกาศว่ากฎในแพ็กเกจนี้จะมองเห็นได้เฉพาะสมาชิกของกลุ่มแพ็กเกจ //foo:target การประกาศระดับการเข้าถึงแต่ละรายการในกฎ (หากมี) จะลบล้างข้อกำหนดนี้
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

ฟังก์ชันนี้กำหนดชุด แพ็กเกจ และเชื่อมโยงป้ายกำกับกับชุดแพ็กเกจ โดยสามารถอ้างอิงป้ายกำกับในแอตทริบิวต์ visibility

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

ระบบจะพิจารณาว่าแพ็กเกจหนึ่งๆ อยู่ในกลุ่มหากแพ็กเกจนั้นตรงกับแอตทริบิวต์ packages หรืออยู่ในกลุ่มแพ็กเกจอื่นๆ ที่ระบุไว้ในแอตทริบิวต์ includes

กลุ่มแพ็กเกจเป็นเป้าหมายทางเทคนิค แต่ไม่ได้สร้างขึ้นโดยกฎและไม่มีการปกป้องระดับการเข้าถึง

อาร์กิวเมนต์

แอตทริบิวต์ คำอธิบาย
name

ชื่อ ต้องระบุ

ชื่อที่ไม่ซ้ำกันสำหรับเป้าหมายนี้

packages

รายการสตริง ค่าเริ่มต้นคือ []

รายการข้อกำหนดแพ็กเกจจำนวน 0 รายการขึ้นไป

สตริงข้อกำหนดแพ็กเกจแต่ละรายการอาจมีรูปแบบใดรูปแบบหนึ่งต่อไปนี้

  1. ชื่อเต็มของแพ็กเกจโดยไม่มีที่เก็บ ซึ่งเริ่มต้นด้วยเครื่องหมายทับ 2 ครั้ง เช่น //foo/bar จะระบุแพ็กเกจ ที่มีชื่อดังกล่าวและอยู่ในที่เก็บเดียวกับกลุ่มแพ็กเกจ
  2. เหมือนกับด้านบน แต่มี /... ต่อท้าย เช่น //foo/... จะระบุชุด //foo และแพ็กเกจย่อยทั้งหมด //... จะระบุแพ็กเกจทั้งหมดในที่เก็บปัจจุบัน
  3. สตริง public หรือ private ซึ่ง จะระบุทุกแพ็กเกจหรือไม่มีแพ็กเกจตามลำดับ (รูปแบบนี้ต้องตั้งค่าแฟล็ก --incompatible_package_group_has_public_syntax )

นอกจากนี้ ข้อกำหนดแพ็กเกจ 2 ประเภทแรกยังอาจมี คำนำหน้าเป็น - เพื่อระบุว่าข้อกำหนดนั้นเป็นข้อกำหนดที่ถูกปฏิเสธ

กลุ่มแพ็กเกจจะมีแพ็กเกจใดก็ตามที่ตรงกับข้อกำหนดเชิงบวกอย่างน้อย 1 ข้อและไม่ตรงกับข้อกำหนดเชิงลบใดๆ เช่น ค่า [//foo/..., -//foo/tests/...] จะรวมแพ็กเกจย่อยทั้งหมดของ //foo ที่ไม่ใช่แพ็กเกจย่อยของ //foo/tests (//foo จะรวมอยู่ด้วย แต่ //foo/tests จะไม่รวม)

นอกเหนือจากระดับการเข้าถึงแบบสาธารณะแล้ว ยังไม่มีวิธีระบุแพ็กเกจภายนอกที่เก็บปัจจุบันโดยตรง

หากไม่มีแอตทริบิวต์นี้ การตั้งค่าแอตทริบิวต์นี้จะเป็นเหมือนกับการตั้งค่าเป็นรายการว่าง ซึ่งเหมือนกับการตั้งค่าเป็นรายการที่มีเฉพาะ private

หมายเหตุ: ก่อน Bazel 6.0 ข้อกำหนด //... มีลักษณะการทำงานแบบเดิมที่เหมือนกับ public ลักษณะการทำงานนี้ได้รับการแก้ไขเมื่อ --incompatible_fix_package_group_reporoot_syntax เปิดใช้งาน ซึ่งเป็นค่าเริ่มต้นหลังจาก Bazel 6.0

หมายเหตุ: ก่อน Bazel 6.0 เมื่อมีการเรียงอันดับแอตทริบิวต์นี้เป็นส่วนหนึ่งของ bazel query --output=proto (หรือ --output=xml) ระบบจะละเว้นเครื่องหมายทับนำหน้า เช่น //pkg/foo/... จะแสดงผลเป็น \"pkg/foo/...\" ลักษณะการทำงานนี้ได้รับการแก้ไขเมื่อ --incompatible_package_group_includes_double_slash เปิดใช้ ซึ่งเป็นค่าเริ่มต้นหลังจาก Bazel 6.0

includes

รายการป้ายกำกับ ค่าเริ่มต้นคือ []

กลุ่มแพ็กเกจอื่นๆ ที่รวมอยู่ในกลุ่มนี้

ป้ายกำกับในแอตทริบิวต์นี้ต้องอ้างอิงถึงกลุ่มแพ็กเกจอื่นๆ ระบบจะถือว่าแพ็กเกจในกลุ่มแพ็กเกจที่อ้างอิงเป็นส่วนหนึ่งของกลุ่มแพ็กเกจนี้ ซึ่งเป็นแบบถ่ายทอด หากกลุ่มแพ็กเกจ a รวมกลุ่มแพ็กเกจ b และ b รวมกลุ่มแพ็กเกจ c แพ็กเกจทุกแพ็กเกจใน c จะเป็นสมาชิกของ a ด้วย

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

ตัวอย่าง

การประกาศ package_group ต่อไปนี้จะระบุกลุ่มแพ็กเกจที่ชื่อ "tropical" ซึ่งมีผลไม้เขตร้อน

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

การประกาศต่อไปนี้จะระบุกลุ่มแพ็กเกจของแอปพลิเคชันสมมติ

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files() จะระบุรายการไฟล์ที่เป็นของ แพ็กเกจนี้ซึ่งส่งออกไปยังแพ็กเกจอื่นๆ

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

ในฐานะที่เป็นพฤติกรรมเดิม ระบบจะส่งออกไฟล์ที่ระบุเป็นอินพุตของกฎด้วยระดับการเข้าถึงเริ่มต้น จนกว่าจะเปลี่ยนแฟล็ก --incompatible_no_implicit_file_export อย่างไรก็ตาม คุณไม่ควรพึ่งพาลักษณะการทำงานนี้และควรย้ายข้อมูลออกจากลักษณะการทำงานนี้อย่างจริงจัง

อาร์กิวเมนต์

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

ตัวอย่าง

ตัวอย่างต่อไปนี้จะส่งออก golden.txt ซึ่งเป็นไฟล์ข้อความจากแพ็กเกจ test_data เพื่อให้แพ็กเกจอื่นๆ ใช้ไฟล์นี้ได้ เช่น ในแอตทริบิวต์ data ของการทดสอบ

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob เป็นฟังก์ชันตัวช่วยที่ค้นหาไฟล์ทั้งหมดที่ตรงกับรูปแบบเส้นทางบางอย่าง และแสดงผลรายการเส้นทางใหม่ที่เปลี่ยนแปลงได้และจัดเรียงแล้ว Glob จะค้นหาเฉพาะไฟล์ในแพ็กเกจของตัวเอง และค้นหาเฉพาะไฟล์แหล่งที่มา (ไม่ใช่ไฟล์ที่สร้างขึ้นหรือเป้าหมายอื่นๆ)

ระบบจะรวมป้ายกำกับของไฟล์แหล่งที่มาไว้ในผลลัพธ์หากเส้นทางที่สัมพันธ์กับแพ็กเกจของไฟล์ตรงกับรูปแบบ include ใดรูปแบบหนึ่งและไม่ตรงกับรูปแบบ exclude ใดๆ

รายการ include และ exclude มีรูปแบบเส้นทางที่สัมพันธ์กับแพ็กเกจปัจจุบัน ทุกรูปแบบอาจประกอบด้วยกลุ่มเส้นทางอย่างน้อย 1 กลุ่ม กลุ่มเหล่านี้คั่นด้วย / ตามปกติของเส้นทาง Unix ระบบจะจับคู่กลุ่มในรูปแบบกับกลุ่มของเส้นทาง กลุ่มอาจมีไวลด์การ์ด * ซึ่งจะจับคู่กับ สตริงย่อยใดก็ได้ในกลุ่มเส้นทาง (แม้แต่สตริงย่อยว่าง) ยกเว้น ตัวคั่นไดเรกทอรี / คุณใช้ไวลด์การ์ดนี้ได้หลายครั้งภายในกลุ่มเส้นทางเดียว นอกจากนี้ ไวลด์การ์ด ** ยังจับคู่กับกลุ่มเส้นทางที่สมบูรณ์จำนวน 0 กลุ่มขึ้นไปได้ แต่ต้องประกาศเป็นกลุ่มเส้นทางแบบสแตนด์อโลน

ตัวอย่าง:
  • foo/bar.txt จะตรงกับไฟล์ foo/bar.txt ในแพ็กเกจนี้อย่างแน่นอน (ยกเว้นในกรณีที่ foo/ เป็นแพ็กเกจย่อย)
  • foo/*.txt จะตรงกับทุกไฟล์ในไดเรกทอรี foo/ หากไฟล์ลงท้ายด้วย .txt (ยกเว้นในกรณีที่ foo/ เป็น แพ็กเกจย่อย)
  • foo/a*.htm* จะตรงกับทุกไฟล์ในไดเรกทอรี foo/ ที่ขึ้นต้นด้วย a ตามด้วยสตริงใดก็ได้ (อาจ เป็นสตริงว่าง) จากนั้นตามด้วย .htm และลงท้ายด้วยสตริงใดก็ได้ (ยกเว้นในกรณีที่ foo/ เป็นแพ็กเกจย่อย) เช่น foo/axx.htm และ foo/a.html หรือ foo/axxx.html
  • foo/* จะตรงกับทุกไฟล์ในไดเรกทอรี foo/ (ยกเว้นในกรณีที่ foo/ เป็นแพ็กเกจย่อย) แต่จะไม่ตรงกับไดเรกทอรี foo เอง แม้ว่าจะตั้งค่า exclude_directories เป็น 0 ก็ตาม
  • foo/** จะตรงกับทุกไฟล์ในทุกไดเรกทอรีย่อยที่ไม่ใช่แพ็กเกจย่อย ภายใต้ไดเรกทอรีย่อยระดับแรกของแพ็กเกจ foo/ หาก exclude_directories ตั้งค่าเป็น 0 foo ไดเรกทอรีเองก็จะตรงกับรูปแบบด้วย ในกรณีนี้ ระบบจะถือว่า ** เป็น กลุ่มเส้นทาง 0 กลุ่ม
  • **/a.txt จะตรงกับไฟล์ a.txt ในไดเรกทอรีของแพ็กเกจนี้ รวมถึงไดเรกทอรีย่อยที่ไม่ใช่แพ็กเกจย่อย
  • **/bar/**/*.txt จะตรงกับทุกไฟล์ .txt ในทุกไดเรกทอรีย่อยที่ไม่ใช่แพ็กเกจย่อยของแพ็กเกจนี้ หากมีไดเรกทอรีอย่างน้อย 1 ไดเรกทอรีในเส้นทางที่ได้ชื่อว่า bar เช่น xxx/bar/yyy/zzz/a.txt หรือ bar/a.txt (โปรดทราบว่า ** ยังตรงกับกลุ่ม 0 กลุ่ม) หรือ bar/zzz/a.txt
  • ** จะตรงกับทุกไฟล์ในทุกไดเรกทอรีย่อยที่ไม่ใช่แพ็กเกจย่อยของแพ็กเกจนี้
  • foo**/a.txt เป็นรูปแบบที่ไม่ถูกต้อง เนื่องจาก ** ต้อง เป็นกลุ่มแบบสแตนด์อโลน
  • foo/ เป็นรูปแบบที่ไม่ถูกต้อง เนื่องจากกลุ่มที่ 2 ที่กำหนด หลัง / เป็นสตริงว่าง

หากเปิดใช้อาร์กิวเมนต์ exclude_directories (ตั้งค่าเป็น 1) ระบบจะละเว้นไฟล์ประเภทไดเรกทอรีจากผลลัพธ์ (ค่าเริ่มต้นคือ 1)

หากตั้งค่าอาร์กิวเมนต์ allow_empty เป็น False ฟังก์ชัน glob จะแสดงข้อผิดพลาดหากผลลัพธ์เป็นรายการว่าง

ข้อจำกัดและคำเตือนที่สำคัญมีดังนี้

  1. เนื่องจาก glob() ทำงานระหว่างการประเมินไฟล์ BUILD glob() จึงจับคู่เฉพาะไฟล์ในโครงสร้างแหล่งที่มาเท่านั้น ไม่ใช่ไฟล์ที่สร้างขึ้น หากคุณกำลังสร้างเป้าหมายที่ต้องใช้ทั้ง ไฟล์แหล่งที่มาและไฟล์ที่สร้างขึ้น คุณต้องต่อท้ายรายการไฟล์ที่สร้างขึ้นอย่างชัดเจนกับ ไฟล์กับ glob ดู ตัวอย่าง ด้านล่างที่มี :mylib และ :gen_java_srcs

  2. หากกฎมีชื่อเดียวกับไฟล์แหล่งที่มาที่ตรงกัน กฎจะ "ซ่อน" ไฟล์

    โปรดทราบว่า glob() จะแสดงผลรายการเส้นทาง ดังนั้นการใช้ glob() ในแอตทริบิวต์ของกฎอื่นๆ (เช่น srcs = glob(["*.cc"])) จะมีผลเหมือนกับการแสดงรายการเส้นทางที่ตรงกันอย่างชัดเจน เช่น หาก glob() แสดงผล ["Foo.java", "bar/Baz.java"] แต่ในแพ็กเกจมีกฎที่ชื่อว่า "Foo.java" ด้วย (ซึ่งทำได้ แม้ว่า Bazel จะแสดงคำเตือน) ผู้ใช้ glob() จะใช้กฎ "Foo.java" (เอาต์พุตของกฎ) แทนไฟล์ "Foo.java" ดูรายละเอียดเพิ่มเติมได้ที่ GitHub ปัญหา #10395

  3. Globs อาจตรงกับไฟล์ในไดเรกทอรีย่อย และชื่อไดเรกทอรีย่อย อาจเป็นไวลด์การ์ด อย่างไรก็ตาม...
  4. ป้ายกำกับจะข้ามขอบเขตแพ็กเกจไม่ได้ และ glob จะไม่ตรงกับไฟล์ในแพ็กเกจย่อย

    เช่น นิพจน์ glob **/*.cc ในแพ็กเกจ x จะไม่รวม x/y/z.cc หาก x/y มีอยู่เป็นแพ็กเกจ (ไม่ว่าจะเป็น x/y/BUILD, หรือที่อื่นในเส้นทางแพ็กเกจ) ซึ่ง หมายความว่าผลลัพธ์ของนิพจน์ glob จะขึ้นอยู่กับการ มีอยู่ของไฟล์ BUILD โดยนิพจน์ glob เดียวกันจะ รวม x/y/z.cc หากไม่มีแพ็กเกจที่ชื่อว่า x/y หรือมีการทำเครื่องหมายว่าถูกลบโดยใช้ --deleted_packages แฟล็ก

  5. ข้อจำกัดข้างต้นมีผลกับนิพจน์ glob ทั้งหมด ไม่ว่านิพจน์นั้นจะใช้ไวลด์การ์ดใดก็ตาม
  6. ไวลด์การ์ด ** และ * จะจับคู่ไฟล์ที่ซ่อนอยู่ซึ่งมีชื่อไฟล์ขึ้นต้นด้วย . ได้อย่างสมบูรณ์ หากต้องการจับคู่ไฟล์ที่ซ่อนอยู่ กับรูปแบบผสม รูปแบบของคุณต้องขึ้นต้นด้วย . เช่น * และ .*.txt จะจับคู่กับ .foo.txt แต่ *.txt จะไม่จับคู่ ระบบจะจับคู่ไดเรกทอรีที่ซ่อนอยู่ด้วยวิธีเดียวกัน ไดเรกทอรีที่ซ่อนอยู่ อาจมีไฟล์ที่ไม่จำเป็นต้องใช้เป็นอินพุต และอาจเพิ่มจำนวน ไฟล์ที่ globbed โดยไม่จำเป็นและการใช้หน่วยความจำ หากต้องการยกเว้น ไดเรกทอรีที่ซ่อนอยู่ ให้เพิ่มไดเรกทอรีเหล่านั้นลงในอาร์กิวเมนต์รายการ "exclude"
  7. ไวลด์การ์ด "**" มีกรณีพิเศษ 1 กรณีคือ รูปแบบ "**" จะไม่ตรงกับเส้นทางไดเรกทอรีของแพ็กเกจ กล่าวคือ glob(["**"], exclude_directories = False) จะตรงกับไฟล์ และไดเรกทอรีทั้งหมดแบบถ่ายทอดภายใต้ไดเรกทอรีของแพ็กเกจปัจจุบันอย่างเคร่งครัด (แต่จะไม่เข้าไปในไดเรกทอรีของแพ็กเกจย่อย โปรดดู หมายเหตุเกี่ยวกับเรื่องนี้ก่อนหน้านี้)

โดยทั่วไป คุณควรระบุส่วนขยายที่เหมาะสม (เช่น *.html) แทนการใช้ '*' เปล่าๆ สำหรับรูปแบบ glob ชื่อที่ชัดเจนมากขึ้นจะอธิบายตัวเองและช่วยให้มั่นใจได้ว่าคุณจะไม่จับคู่ไฟล์สำรองหรือไฟล์บันทึกอัตโนมัติของ emacs/vi/... โดยไม่ได้ตั้งใจ

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

ตัวอย่าง Glob

สร้างไลบรารี Java ที่สร้างจากไฟล์ Java ทั้งหมดในไดเรกทอรีนี้ และไฟล์ทั้งหมดที่สร้างขึ้นโดยกฎ :gen_java_srcs

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

รวมไฟล์ txt ทั้งหมดในไดเรกทอรี testdata ยกเว้น experimental.txt โปรดทราบว่าระบบจะไม่รวมไฟล์ในไดเรกทอรีย่อยของ testdata หากต้องการรวมไฟล์เหล่านั้น ให้ใช้ glob แบบเรียกซ้ำ (**)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

ตัวอย่าง Glob แบบเรียกซ้ำ

ทำให้การทดสอบขึ้นอยู่กับไฟล์ txt ทั้งหมดในไดเรกทอรี testdata และไดเรกทอรีย่อยใดๆ ของไดเรกทอรีนั้น (และไดเรกทอรีย่อยของไดเรกทอรีย่อย และอื่นๆ) ระบบจะละเว้นไดเรกทอรีย่อยที่มีไฟล์ BUILD (ดูข้อจำกัด และคำเตือนด้านบน)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

สร้างไลบรารีที่สร้างจากไฟล์ Java ทั้งหมดในไดเรกทอรีนี้และไดเรกทอรีย่อยทั้งหมด ยกเว้นไดเรกทอรีที่มีเส้นทางรวมถึงไดเรกทอรีที่ชื่อว่า testing ควรหลีกเลี่ยงรูปแบบนี้หากเป็นไปได้ เนื่องจากอาจลดการเพิ่มขึ้นของบิลด์และทำให้เวลาบิลด์เพิ่มขึ้น

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

ตัวอย่าง Glob ที่ขยาย

สร้าง genrule แต่ละรายการสำหรับ *_test.cc ในไดเรกทอรีปัจจุบันที่นับจำนวนบรรทัดในไฟล์

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

หากไฟล์ BUILD ด้านบนอยู่ในแพ็กเกจ //foo และแพ็กเกจมีไฟล์ที่ตรงกัน 3 ไฟล์ ได้แก่ a_test.cc, b_test.cc และ c_test.cc การเรียกใช้ bazel query '//foo:all' จะแสดงรายการกฎทั้งหมดที่สร้างขึ้น

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

เลือก

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() เป็นฟังก์ชันตัวช่วยที่ทำให้แอตทริบิวต์กฎ กำหนดค่าได้. โดยสามารถแทนที่ด้านขวาของการกำหนดแอตทริบิวต์ เกือบ ทั้งหมดเพื่อให้ค่าขึ้นอยู่กับแฟล็ก Bazel ในบรรทัดคำสั่ง คุณสามารถใช้ฟังก์ชันนี้ได้ เช่น เพื่อกำหนดการอ้างอิงที่เฉพาะเจาะจงแพลตฟอร์ม หรือเพื่อ ฝังทรัพยากรต่างๆ ขึ้นอยู่กับว่ากฎนั้นสร้างขึ้นในโหมด "นักพัฒนาซอฟต์แวร์" หรือโหมด "รุ่นที่เผยแพร่"

การใช้งานพื้นฐานมีดังนี้

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

ซึ่งจะทำให้แอตทริบิวต์ srcs ของ sh_binary กำหนดค่าได้โดยการแทนที่การกำหนดรายการป้ายกำกับ ปกติด้วยการเรียก select ที่แมป เงื่อนไขการกำหนดค่ากับค่าที่ตรงกัน แต่ละเงื่อนไขเป็นการอ้างอิงป้ายกำกับไปยัง config_setting หรือ constraint_value ซึ่งจะ "ตรงกัน" หากการกำหนดค่าของเป้าหมายตรงกับชุดค่าที่คาดไว้ จากนั้นค่าของ mytarget#srcs จะกลายเป็นรายการป้ายกำกับที่ตรงกับการเรียกใช้ปัจจุบัน

หมายเหตุ

  • ระบบจะเลือกเงื่อนไข 1 ข้อในการเรียกใช้แต่ละครั้ง
  • หากมีหลายเงื่อนไขที่ตรงกันและเงื่อนไขหนึ่งเป็นเงื่อนไขเฉพาะของเงื่อนไขอื่นๆ เงื่อนไขเฉพาะจะมีลำดับความสำคัญสูงกว่า เงื่อนไข B ถือเป็นเงื่อนไขเฉพาะของเงื่อนไข A หาก B มีแฟล็กและค่าข้อจำกัดทั้งหมดเหมือนกับ A รวมถึงแฟล็กหรือค่าข้อจำกัดเพิ่มเติม ซึ่งหมายความว่าการแก้ปัญหาเงื่อนไขเฉพาะไม่ได้ออกแบบมาเพื่อสร้างลำดับตามที่แสดงในตัวอย่างที่ 2 ด้านล่าง
  • หากมีหลายเงื่อนไขที่ตรงกันและเงื่อนไขหนึ่งไม่ใช่เงื่อนไขเฉพาะของเงื่อนไขอื่นๆ ทั้งหมด Bazel จะแสดงข้อผิดพลาด เว้นแต่เงื่อนไขทั้งหมดจะแสดงผลค่าเดียวกัน
  • ระบบจะถือว่าป้ายกำกับเทียมพิเศษ //conditions:default ตรงกันหากไม่มีเงื่อนไขอื่นตรงกัน หากละเว้นเงื่อนไขนี้ กฎอื่นต้องตรงกันเพื่อหลีกเลี่ยงข้อผิดพลาด
  • select สามารถฝัง ภายใน การกำหนดแอตทริบิวต์ที่ใหญ่ขึ้นได้ ดังนั้น srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) และ srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) จึงเป็นนิพจน์ที่ถูกต้อง
  • select ทำงานร่วมกับแอตทริบิวต์ส่วนใหญ่ แต่ไม่ใช่ทั้งหมด แอตทริบิวต์ที่ไม่เข้ากัน จะมีการทำเครื่องหมายเป็น nonconfigurable ในเอกสารประกอบ

    subpackages

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() เป็นฟังก์ชันตัวช่วยที่คล้ายกับ glob() ซึ่งแสดงรายการแพ็กเกจย่อยแทนไฟล์และไดเรกทอรี ฟังก์ชันนี้ใช้รูปแบบเส้นทางเดียวกันกับ glob() และสามารถจับคู่แพ็กเกจย่อยใดก็ได้ที่เป็น ลูกหลานโดยตรงของไฟล์ BUILD ที่กำลังโหลด ดูคำอธิบายโดยละเอียดและตัวอย่างรูปแบบ include และ exclude ได้ที่ glob

    รายการแพ็กเกจย่อยที่แสดงผลจะอยู่ในลำดับการจัดเรียงแล้วและมี เส้นทางที่สัมพันธ์กับแพ็กเกจที่กำลังโหลดซึ่งตรงกับรูปแบบที่ระบุใน include และไม่ตรงกับรูปแบบใน exclude

    ตัวอย่าง

    ตัวอย่างต่อไปนี้จะแสดงรายการแพ็กเกจย่อยโดยตรงทั้งหมดสำหรับแพ็กเกจ foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    

    โดยทั่วไป เราขอแนะนำให้ผู้ใช้ใช้โมดูล 'subpackages' ของ skylib แทนการเรียกใช้ฟังก์ชันนี้โดยตรง