Bazel สามารถสร้างและทดสอบโค้ดบนฮาร์ดแวร์ ระบบปฏิบัติการ และ การกำหนดค่าระบบ โดยใช้เครื่องมือสร้างเวอร์ชันต่างๆ มากมาย เช่น Linker และคอมไพเลอร์ เพื่อช่วยจัดการความซับซ้อนนี้ Bazel มีแนวคิด ข้อจำกัดและแพลตฟอร์ม ข้อจำกัดคือมิติข้อมูลที่บิลด์หรือ สภาพแวดล้อมการใช้งานจริงอาจแตกต่างกัน เช่น สถาปัตยกรรมของ CPU, การแสดงสถานะ หรือ ไม่มี GPU หรือเวอร์ชันของคอมไพเลอร์ที่ติดตั้งโดยระบบ แพลตฟอร์มคือ ที่ตั้งชื่อคอลเล็กชันของตัวเลือก สำหรับข้อจำกัดเหล่านี้ ซึ่งแสดงถึง ทรัพยากรที่ใช้ได้ในบางสภาพแวดล้อม
การสร้างโมเดลสภาพแวดล้อมในฐานะแพลตฟอร์มช่วยให้ Bazel เลือก เหมาะสม เครื่องมือเชน สำหรับการทำงานของบิลด์ คุณยังใช้แพลตฟอร์มร่วมกับ config_setting กฎในการเขียนแอตทริบิวต์ที่กำหนดค่าได้
Bazel เล็งเห็นบทบาท 3 บทบาทที่แพลตฟอร์มอาจนำเสนอ ดังนี้
- โฮสต์ - แพลตฟอร์มที่ Bazel ทำงานอยู่
- การดำเนินการ - แพลตฟอร์มที่เครื่องมือบิลด์ใช้การดำเนินการบิลด์เพื่อ สร้างผลลัพธ์ขั้นกลางและสุดท้าย
- เป้าหมาย - แพลตฟอร์มที่มีและเรียกใช้เอาต์พุตสุดท้าย
Bazel รองรับสถานการณ์บิลด์ต่อไปนี้เกี่ยวกับแพลตฟอร์ม
บิลด์แพลตฟอร์มเดียว (ค่าเริ่มต้น) - แพลตฟอร์มโฮสต์ การดำเนินการ และแพลตฟอร์มเป้าหมาย เช่นเดียวกัน ตัวอย่างเช่น การสร้างไฟล์ปฏิบัติการ Linux บน Ubuntu ที่ทำงานอยู่ CPU ของ Intel x64
บิลด์การคอมไพล์ข้าม - แพลตฟอร์มโฮสต์และการดำเนินการเหมือนกัน แต่ แพลตฟอร์มเป้าหมายแตกต่างกัน เช่น การสร้างแอป iOS ใน macOS ที่ทำงานบน MacBook Pro ได้
บิลด์หลายแพลตฟอร์ม - ทั้งแพลตฟอร์มโฮสต์ การดำเนินการ และแพลตฟอร์มเป้าหมาย แตกต่างกัน
การกำหนดข้อจำกัดและแพลตฟอร์ม
พื้นที่ของตัวเลือกที่เป็นไปได้สำหรับแพลตฟอร์มจะกำหนดโดยใช้
constraint_setting
และ
กฎ constraint_value
รายการภายใน BUILD
ไฟล์
constraint_setting
สร้างมิติข้อมูลใหม่ในขณะที่
constraint_value
สร้างค่าใหม่สำหรับมิติข้อมูลที่ระบุ พวกเขา
กำหนด enum และค่าที่เป็นไปได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น URL ต่อไปนี้
ตัวอย่างข้อมูลของไฟล์ BUILD
เพิ่มข้อจำกัดสำหรับเวอร์ชัน glibc ของระบบ
ด้วยค่าที่เป็นไปได้ 2 ค่า
constraint_setting(name = "glibc_version")
constraint_value(
name = "glibc_2_25",
constraint_setting = ":glibc_version",
)
constraint_value(
name = "glibc_2_26",
constraint_setting = ":glibc_version",
)
อาจมีการกำหนดข้อจำกัดและค่าสำหรับแพ็กเกจต่างๆ ใน Google Workspace ได้อย่างเต็มประสิทธิภาพ มีการอ้างอิงโดยป้ายกำกับและมองเห็นได้ตามปกติ หากการเปิดเผยอนุญาต คุณสามารถขยายการตั้งค่าข้อจำกัดที่มีอยู่ได้โดย กำหนดคุณค่าของคุณเอง
กฎ platform
เริ่มใช้แพลตฟอร์มใหม่
ค่าจำกัดบางตัวเลือก
ต่อไปนี้จะสร้างแพลตฟอร์มชื่อ linux_x86
และระบุว่า
ที่ใช้งานระบบปฏิบัติการ Linux ในสถาปัตยกรรม x86_64 ที่มี
glibc เวอร์ชัน 2.25 (ดูข้อมูลเพิ่มเติมด้านล่างเกี่ยวกับข้อจำกัดในตัวของ Bazel)
platform(
name = "linux_x86",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":glibc_2_25",
],
)
ข้อจำกัดและแพลตฟอร์มที่เป็นประโยชน์โดยทั่วไป
เพื่อให้ระบบนิเวศสอดคล้องกัน ทีม Bazel ได้ดูแลรักษาที่เก็บด้วย คำจำกัดความสำหรับสถาปัตยกรรมและการทำงานของ CPU ที่ได้รับความนิยมมากที่สุด ระบบต่างๆ ทั้งหมดนี้อยู่ใน https://github.com/bazelbuild/platforms.
Bazel จัดส่งพร้อมกับคำจำกัดความของแพลตฟอร์มพิเศษต่อไปนี้
@platforms//host
(ใช้นามแฝงเป็น @bazel_tools//tools:host_platform
) นี่คือ
ค่าแพลตฟอร์มโฮสต์ที่ตรวจหาโดยอัตโนมัติ -
แสดงแพลตฟอร์มที่ตรวจหาโดยอัตโนมัติสำหรับระบบที่ Bazel ทำงานอยู่
การระบุแพลตฟอร์มสำหรับบิลด์
คุณระบุแพลตฟอร์มโฮสต์และแพลตฟอร์มเป้าหมายสำหรับบิลด์ได้โดยใช้ข้อมูลต่อไปนี้ แฟล็กบรรทัดคำสั่ง:
--host_platform
- ค่าเริ่มต้นคือ@bazel_tools//tools:host_platform
- เป้าหมายนี้มีชื่อแทนเป็น
@platforms//host
ซึ่งได้รับการสนับสนุนโดยที่เก็บ กฎที่ตรวจหาระบบปฏิบัติการของโฮสต์และ CPU และเขียนเป้าหมายแพลตฟอร์ม - และยังมี
@platforms//host:constraints.bzl
ที่แสดง อาร์เรย์ชื่อHOST_CONSTRAINTS
ซึ่งใช้ใน BUILD อื่นๆ และ ไฟล์ Starlark
- เป้าหมายนี้มีชื่อแทนเป็น
--platforms
- ค่าเริ่มต้นของแพลตฟอร์มโฮสต์- หมายความว่าเมื่อไม่มีการตั้งค่าแฟล็กอื่นๆ
@platforms//host
เป็นแพลตฟอร์มเป้าหมาย - หากตั้งค่า
--host_platform
ไม่ใช่--platforms
ค่าของ--host_platform
เป็นทั้งโฮสต์และแพลตฟอร์มเป้าหมาย
- หมายความว่าเมื่อไม่มีการตั้งค่าแฟล็กอื่นๆ
การข้ามเป้าหมายที่ใช้ร่วมกันไม่ได้
เมื่อสร้างแพลตฟอร์มเป้าหมายที่เฉพาะเจาะจง ผู้ใช้มักต้องการข้าม
ที่จะไม่มีทางใช้งานได้บนแพลตฟอร์มนั้น เช่น อุปกรณ์ Windows
ไดรเวอร์มีแนวโน้มที่จะสร้างข้อผิดพลาดเกี่ยวกับคอมไพเลอร์จำนวนมากเมื่อสร้างบน
เครื่อง Linux ที่มี //...
ใช้เมนู
target_compatible_with
เพื่อบอก Bazel ว่าข้อจำกัดของแพลตฟอร์มเป้าหมายใดที่ทำให้โค้ดของคุณมี
การใช้แอตทริบิวต์นี้ที่ง่ายที่สุดจะจำกัดเป้าหมายไว้ที่แพลตฟอร์มเดียว
เป้าหมายจะไม่สร้างขึ้นสำหรับแพลตฟอร์มใดๆ ที่ไม่ตรงตาม
ข้อจำกัด ตัวอย่างต่อไปนี้จำกัด win_driver_lib.cc
ไว้ที่ 64 บิต
Windows
cc_library(
name = "win_driver_lib",
srcs = ["win_driver_lib.cc"],
target_compatible_with = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
],
)
:win_driver_lib
เข้ากันได้กับการสร้างด้วย Windows แบบ 64 บิตและเท่านั้น
ไม่สามารถใช้ร่วมกับระบบอื่นๆ ได้ ความไม่เข้ากันนี้เป็นแบบทรานซิทีฟ เป้าหมายทั้งหมด
ที่ขึ้นอยู่กับเป้าหมายที่ใช้ร่วมกันไม่ได้จะถูกนำมาพิจารณาด้วย
ใช้ร่วมกันไม่ได้
เมื่อใดที่เป้าหมายจะถูกข้าม
ระบบจะข้ามเป้าหมายเมื่อพิจารณาแล้วว่าใช้ร่วมกันไม่ได้และรวมอยู่ในเป้าหมาย สร้างเป็นส่วนหนึ่งของการขยายรูปแบบเป้าหมาย ตัวอย่างเช่น โฆษณา 2 รายการต่อไปนี้ การเรียกใช้จะข้ามเป้าหมายที่ใช้ร่วมกันไม่ได้ซึ่งพบในการขยายรูปแบบเป้าหมาย
$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all
การทดสอบที่เข้ากันไม่ได้ใน test_suite
มีดังนี้
ในทำนองเดียวกัน คุณสามารถข้ามหากระบุ test_suite
ในบรรทัดคำสั่งด้วย
--expand_test_suites
กล่าวคือ เป้าหมาย test_suite
ในบรรทัดคำสั่งจะทำงานเหมือน :all
และ
...
การใช้ --noexpand_test_suites
ป้องกันการขยายตัวและสาเหตุ
เป้าหมาย test_suite
รายการที่มีการทดสอบที่เข้ากันไม่ได้ จะเข้ากันไม่ได้ด้วย
การระบุเป้าหมายที่ใช้ร่วมกันไม่ได้ในบรรทัดคำสั่งอย่างชัดเจนจะส่งผลให้เกิด และบิลด์ที่ล้มเหลว
$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully
ระบบจะข้ามเป้าหมายที่อาจไม่เหมาะสมซึ่งเข้ากันไม่ได้หาก
--skip_incompatible_explicit_targets
เปิดใช้อยู่
ข้อจำกัดที่ชัดเจนมากกว่า
เพื่อความยืดหยุ่นที่มากขึ้นในการแสดงข้อจำกัด ให้ใช้
@platforms//:incompatible
constraint_value
ที่ไม่มีแพลตฟอร์มใดที่ทำงานได้จริง
ใช้ select()
ร่วมกับ
@platforms//:incompatible
เพื่อแสดงข้อจำกัดที่ซับซ้อนมากขึ้น สำหรับ
ตัวอย่างเช่น ใช้เพื่อติดตั้งใช้งานตรรกะ "หรือ" พื้นฐาน ข้อมูลต่อไปนี้จะทำเครื่องหมายไลบรารี
ทำงานร่วมกับ macOS และ Linux ได้ แต่ไม่สามารถใช้งานแพลตฟอร์มอื่นๆ ได้
cc_library(
name = "unixish_lib",
srcs = ["unixish_lib.cc"],
target_compatible_with = select({
"@platforms//os:osx": [],
"@platforms//os:linux": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
)
วิธีการข้างต้นสามารถตีความได้ดังนี้
- เมื่อกำหนดเป้าหมาย macOS เป้าหมายจะไม่มีข้อจำกัด
- เมื่อกำหนดเป้าหมาย Linux เป้าหมายไม่มีข้อจำกัด
- ไม่เช่นนั้น เป้าหมายจะมีข้อจํากัด
@platforms//:incompatible
เพราะ@platforms//:incompatible
ไม่ได้เป็นส่วนหนึ่งของแพลตฟอร์มใดๆ เป้าหมายคือ ถือว่าใช้ร่วมกันไม่ได้
ใช้เพื่อทำให้ข้อจำกัดอ่านง่ายขึ้น
ของ skylib
selects.with_or()
คุณสามารถแสดงความเข้ากันได้แบบผกผันด้วยวิธีที่คล้ายกัน ตัวอย่างต่อไปนี้ อธิบายไลบรารีที่ใช้ได้กับทุกอย่างยกเว้น ARM
cc_library(
name = "non_arm_lib",
srcs = ["non_arm_lib.cc"],
target_compatible_with = select({
"@platforms//cpu:arm": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
)
กำลังตรวจหาเป้าหมายที่ใช้ร่วมกันไม่ได้โดยใช้ bazel cquery
คุณสามารถใช้
IncompatiblePlatformProvider
ใน Starlark ของ bazel cquery
รูปแบบเพื่อแยกความแตกต่าง
เป้าหมายที่เข้ากันไม่ได้
จากเป้าหมายที่เข้ากันได้
สามารถใช้เพื่อกรองเป้าหมายที่ใช้ร่วมกันไม่ได้ออก ตัวอย่างด้านล่างจะ พิมพ์เฉพาะป้ายกำกับสำหรับเป้าหมายที่เข้ากันได้เท่านั้น เป้าหมายที่ใช้ร่วมกันไม่ได้คือ ไม่ได้พิมพ์
$ cat example.cquery
def format(target):
if "IncompatiblePlatformProvider" not in providers(target):
return target.label
return ""
$ bazel cquery //... --output=starlark --starlark:file=example.cquery
ปัญหาที่ทราบ
เป้าหมายที่ใช้ร่วมกันไม่ได้ ไม่สนใจการแสดงผล ข้อจำกัด