แพลตฟอร์ม

รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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"],
    }),
)

วิธีการข้างต้นสามารถตีความได้ดังนี้

  1. เมื่อกำหนดเป้าหมาย macOS เป้าหมายจะไม่มีข้อจำกัด
  2. เมื่อกำหนดเป้าหมาย Linux เป้าหมายไม่มีข้อจำกัด
  3. ไม่เช่นนั้น เป้าหมายจะมีข้อจํากัด @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

ปัญหาที่ทราบ

เป้าหมายที่ใช้ร่วมกันไม่ได้ ไม่สนใจการแสดงผล ข้อจำกัด