การย้ายข้อมูลไปยังแพลตฟอร์ม

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

Bazel มีการรองรับขั้นสูงสำหรับการสร้างโมเดลแพลตฟอร์มและเครื่องมือโซ่สำหรับสถาปัตยกรรมแบบหลายสถาปัตยกรรมและบิลด์ที่คอมไพล์แบบข้ามระบบ

หน้านี้สรุปสถานะของการสนับสนุนนี้

และดู:

สถานะ

C++

กฎ C++ จะใช้แพลตฟอร์มเพื่อเลือก Toolchain เมื่อตั้งค่า --incompatible_enable_cc_toolchain_resolution

ซึ่งหมายความว่าคุณจะกำหนดค่าโปรเจ็กต์ C++ ได้ด้วยสิ่งต่อไปนี้

bazel build //:my_cpp_project --platforms=//:myplatform

แทนที่จะเป็นแบบเดิม

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

การดำเนินการนี้จะเปิดใช้โดยค่าเริ่มต้นใน Bazel 7.0 (#7260)

หากต้องการทดสอบโปรเจ็กต์ C++ กับแพลตฟอร์ม โปรดดูการย้ายข้อมูลโปรเจ็กต์และการกำหนดค่าเครื่องมือเชน C++

Java

กฎ Java จะใช้แพลตฟอร์มเพื่อเลือก Toolchain

ซึ่งจะแทนที่แฟล็กเดิม --java_toolchain, --host_java_toolchain, --javabase และ --host_javabase

ดูรายละเอียดได้ที่ Java และ Bazel

Android

กฎ Android จะใช้แพลตฟอร์มเพื่อเลือก Toolchain เมื่อตั้งค่า --incompatible_enable_android_toolchain_resolution

ซึ่งหมายความว่าคุณจะกำหนดค่าโปรเจ็กต์ Android ได้ด้วยสิ่งต่อไปนี้

bazel build //:my_android_project --android_platforms=//:my_android_platform

แทน Flag เดิมอย่าง --android_crosstool_top, --android_cpu และ --fat_apk_cpu

การดำเนินการนี้จะเปิดใช้โดยค่าเริ่มต้นใน Bazel 7.0 (#16285)

หากต้องการทดสอบโปรเจ็กต์ Android กับแพลตฟอร์ม โปรดดูการย้ายข้อมูลโปรเจ็กต์

แอปเปิ้ล

กฎของ Apple ไม่รองรับแพลตฟอร์มและยังไม่ได้กำหนดเวลาสำหรับการสนับสนุน

คุณยังคงใช้ API ของแพลตฟอร์มกับบิลด์ของ Apple ได้ (เช่น เมื่อสร้างโดยใช้กฎของ Apple ร่วมกับ C++ ที่แท้จริง) ด้วยการแมปแพลตฟอร์ม

ภาษาอื่นๆ

หากคุณเป็นเจ้าของชุดกฎภาษา โปรดดูการย้ายข้อมูลชุดกฎสำหรับการเพิ่มการสนับสนุน

ที่มา

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

สิ่งนี้ได้รับแรงบันดาลใจมาจากการสังเกตที่ว่าผู้ดูแลภาษาทำสิ่งนี้เฉพาะกิจซึ่งเป็นวิธีที่เข้ากันไม่ได้อยู่แล้ว เช่น กฎ C++ ใช้ --cpu และ --crosstool_top เพื่อประกาศ CPU เป้าหมายและ Toolchain ทั้งสองวิธีในการสร้าง "แพลตฟอร์ม" อย่างถูกต้อง สิ่งนี้ทำให้เกิดงานสร้างที่ไม่ถูกต้องและแปลกประหลาด

Java, Android และภาษาอื่นๆ พัฒนาค่าสถานะของตัวเองเพื่อวัตถุประสงค์ที่คล้ายกัน โดยที่ไม่มีการดำเนินการใดๆ ระหว่างกัน ซึ่งทำให้การสร้างเกมข้ามภาษา เป็นเรื่องน่าสับสนและซับซ้อน

Bazel ออกแบบมาสำหรับโปรเจ็กต์ขนาดใหญ่ที่ใช้หลายภาษาและหลายแพลตฟอร์ม การดำเนินการนี้ต้องการการสนับสนุนที่มีหลักการมากกว่าเดิมสำหรับแนวคิดเหล่านี้ ซึ่งรวมถึง API มาตรฐานที่ชัดเจน

ความต้องการในการย้ายข้อมูล

การอัปเกรด API เป็น API ใหม่ต้องใช้ความพยายาม 2 ด้าน ได้แก่ การเผยแพร่ API และการอัปเกรดตรรกะของกฎเพื่อใช้งาน

รายการแรกเสร็จแล้ว แต่ครั้งที่ 2 ยังทำอยู่ ซึ่งประกอบด้วยการตรวจสอบว่ามีการกำหนดแพลตฟอร์มและ Toolchain เฉพาะภาษาแล้ว ตรรกะทางภาษาอ่าน Toolchain ผ่าน API ใหม่แทน Flag เก่า เช่น --crosstool_top และ config_setting เลือก API ใหม่แทน Flag เก่า

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

นี่จึงเป็นสาเหตุที่ต้องทำการย้ายข้อมูลอย่างต่อเนื่อง

เป้าหมาย

การย้ายข้อมูลนี้จะเสร็จสมบูรณ์เมื่อโปรเจ็กต์ทั้งหมดสร้างด้วยฟอร์ม:

bazel build //:myproject --platforms=//:myplatform

ซึ่งหมายความว่า

  1. กฎของโปรเจ็กต์เลือกเครื่องมือเชนที่ถูกต้องสำหรับ //:myplatform
  2. ทรัพยากร Dependency ของโปรเจ็กต์เลือก Toolchain ที่เหมาะสมสำหรับ //:myplatform
  3. //:myplatform การอ้างอิง การประกาศทั่วไป ของ CPU, OS และพร็อพเพอร์ตี้ทั่วไปอื่นๆ ที่ไม่ขึ้นอยู่กับภาษา
  4. select() ที่เกี่ยวข้องทั้งหมดตรงกับ //:myplatform อย่างถูกต้อง
  5. //:myplatform ได้รับการกำหนดไว้ในตำแหน่งที่ชัดเจนและเข้าถึงได้ง่าย เช่น ในที่เก็บของโปรเจ็กต์หากแพลตฟอร์มนั้นเป็นของโปรเจ็กต์ของคุณโดยเฉพาะ หรือสถานที่ทั่วไปที่โปรเจ็กต์ที่ใช้งานอยู่ทั้งหมดจะเห็น

เราจะเลิกใช้งานและนําแฟล็กเดิม เช่น --cpu, --crosstool_top และ --fat_apk_cpu ออกทันทีที่ดำเนินการได้อย่างปลอดภัย

ท้ายที่สุดแล้ว การกำหนดค่าสถาปัตยกรรมจึงเป็นวิธีเดียว

กำลังย้ายข้อมูลโปรเจ็กต์

หากคุณสร้างโดยใช้ภาษาที่รองรับแพลตฟอร์ม บิลด์ของคุณควรใช้งานร่วมกับคำขอต่างๆ ได้อยู่แล้ว เช่น

bazel build //:myproject --platforms=//:myplatform

ดูรายละเอียดอย่างละเอียดได้ที่สถานะและเอกสารประกอบของภาษา

หากภาษาใดต้องมี Flag เพื่อเปิดใช้การรองรับแพลตฟอร์ม คุณจะต้องตั้งค่า Flag นั้นด้วย ดูรายละเอียดได้ที่สถานะ

คุณต้องตรวจสอบรายการต่อไปนี้เพื่อให้โปรเจ็กต์สร้าง

  1. ต้องมี //:myplatform อยู่ โดยทั่วไปแล้ว เจ้าของโปรเจ็กต์มีหน้าที่กำหนดแพลตฟอร์ม เนื่องจากโปรเจ็กต์ที่ต่างกันจะกำหนดเป้าหมายเครื่องที่ต่างกัน โปรดดูแพลตฟอร์มเริ่มต้น

  2. ต้องมี Toolchain ที่ต้องการใช้ หากใช้ Stock Toolchain เจ้าของภาษาควรระบุวิธีการลงทะเบียนด้วย หากเขียน Toolchain ที่กำหนดเองของคุณเอง คุณต้องregisterเชนเหล่านั้นใน WORKSPACE หรือกับ --extra_toolchains

  3. select() และการเปลี่ยนการกำหนดค่าต้องได้รับการแก้ไขอย่างถูกต้อง โปรดดูselect() และการเปลี่ยน

  4. หากเวอร์ชันของคุณผสมภาษาที่รองรับและไม่รองรับแพลตฟอร์ม คุณอาจต้องแมปแพลตฟอร์มเพื่อช่วยให้ภาษาเดิมทำงานร่วมกับ API ใหม่ได้ ดูรายละเอียดได้ที่การแมปแพลตฟอร์ม

หากยังพบปัญหาอยู่ โปรดติดต่อเพื่อขอความช่วยเหลือ

แพลตฟอร์มเริ่มต้น

เจ้าของโปรเจ็กต์ควรกำหนดแพลตฟอร์มที่ชัดเจนเพื่ออธิบายสถาปัตยกรรมที่ต้องการสร้าง ซึ่งจะทริกเกอร์ด้วย --platforms

หากไม่ได้ตั้งค่า --platforms ไว้ Bazel จะมีค่าเริ่มต้นเป็น platform ที่แสดงถึงเครื่องสร้างภายใน สิ่งนี้จะสร้างขึ้นโดยอัตโนมัติที่ @local_config_platform//:host ดังนั้นจึงไม่จำเป็นต้องระบุให้ชัดเจน โดยจะแมป OS ในเครื่องและ CPU กับ constraint_value ที่ประกาศใน @platforms

select()

โปรเจ็กต์จะ select() ได้ใน constraint_value เป้าหมาย แต่จะดำเนินการในแพลตฟอร์มไม่ได้ เราตั้งใจให้ select() รองรับเครื่องที่หลากหลายมากที่สุด ไลบรารีที่มีแหล่งที่มาที่เจาะจง ARM ควรรองรับเครื่องที่ทำงานด้วยระบบ ARM ทั้งหมด เว้นแต่จะมีเหตุผลให้เจาะจงมากขึ้น

หากต้องการเลือก constraint_value อย่างน้อย 1 รายการ ให้ใช้

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

ซึ่งเทียบเท่ากับการเลือกบน --cpu ตามปกติ:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

ดูรายละเอียดเพิ่มเติมได้ที่นี่

select ใน --cpu, --crosstool_top ฯลฯ ไม่เข้าใจ --platforms เมื่อย้ายข้อมูลโปรเจ็กต์ไปยังแพลตฟอร์ม คุณต้องแปลงโปรเจ็กต์เป็น constraint_values หรือใช้การแมปแพลตฟอร์มเพื่อรองรับทั้ง 2 สไตล์ระหว่างการย้ายข้อมูล

ทรานซิชัน

การเปลี่ยนแบบ Starlark เปลี่ยน การทำเครื่องหมายส่วนต่างๆ ของกราฟบิลด์ หากโปรเจ็กต์ใช้การเปลี่ยนที่ตั้งค่า --cpu, --crossstool_top หรือแฟล็กเดิมอื่นๆ กฎที่อ่านว่า --platforms จะไม่เห็นการเปลี่ยนแปลงเหล่านี้

เมื่อย้ายข้อมูลโปรเจ็กต์ไปยังแพลตฟอร์ม คุณต้องแปลงการเปลี่ยนแปลง เช่น return { "//command_line_option:cpu": "arm" } เป็น return { "//command_line_option:platforms": "//:my_arm_platform" } หรือใช้การแมปแพลตฟอร์มเพื่อรองรับทั้ง 2 สไตล์ระหว่างการย้ายข้อมูล

กำลังย้ายข้อมูลชุดกฎ

หากคุณเป็นเจ้าของชุดกฎและต้องการรองรับแพลตฟอร์ม คุณต้องทำดังนี้

  1. มีการแปลง Toolchain ของกฎด้วย Toolchain API โปรดดู toolchain API (ctx.toolchains)

  2. ไม่บังคับ: กำหนดแฟล็ก --incompatible_enable_platforms_for_my_language เพื่อให้ตรรกะของกฎสลับกันแก้ไข Toolchain ผ่าน API ใหม่หรือแฟล็กเก่า เช่น --crosstool_top ระหว่างการทดสอบการย้ายข้อมูล

  3. กำหนดพร็อพเพอร์ตี้ที่เกี่ยวข้องซึ่งเป็นส่วนประกอบของแพลตฟอร์ม ดูพร็อพเพอร์ตี้แพลตฟอร์มทั่วไป

  4. กำหนด Toolchain มาตรฐานและทำให้ผู้ใช้เข้าถึงได้ผ่านวิธีการลงทะเบียนของกฎ (รายละเอียด)

  5. ตรวจสอบว่าแพลตฟอร์มรองรับ select() และการเปลี่ยนการกำหนดค่า นี่เป็นความท้าทายที่ยิ่งใหญ่ที่สุด ซึ่งมีความท้าทายอย่างยิ่งสำหรับโปรเจ็กต์หลายภาษา (ซึ่งอาจล้มเหลวหากทุกภาษาอ่าน--platformsไม่ได้)

หากต้องการใช้กฎที่ไม่รองรับแพลตฟอร์มต่างๆ ผสมกัน คุณอาจต้องการแมปแพลตฟอร์มเพื่อเชื่อมช่องว่าง

พร็อพเพอร์ตี้ของแพลตฟอร์มทั่วไป

คุณควรประกาศพร็อพเพอร์ตี้แพลตฟอร์มข้ามภาษาทั่วไป เช่น OS และ CPU ใน @platforms ซึ่งจะช่วยส่งเสริมการแชร์ การกำหนดมาตรฐาน และความเข้ากันได้ข้ามภาษา

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

หากกฎใช้ระบบปฏิบัติการหรือ CPU ตามวัตถุประสงค์ที่กำหนดเอง ควรประกาศเหล่านี้ในที่เก็บของกฎเทียบกับ @platforms

การแมปแพลตฟอร์ม

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

การแมปแพลตฟอร์มคือการแมป platform() กับชุด Flag เดิมที่สอดคล้องกันหรือแบบย้อนกลับ เช่น

platforms:
  # Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
  //platforms:ios
    --cpu=ios_x86_64
    --apple_platform_type=ios

flags:
  # Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --cpu=ios_x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin_x86_64
  --apple_platform_type=macos
    //platforms:macos

Bazel ใช้วิธีนี้เพื่อรับประกันการตั้งค่าทั้งหมดทั้งตามแพลตฟอร์มและแบบเดิมจะมีผลอย่างสอดคล้องกันตลอดบิลด์ รวมถึงการเปลี่ยน

โดยค่าเริ่มต้น Bazel จะอ่านการแมปจากไฟล์ platform_mappings ในรูทพื้นที่ทำงานของคุณ คุณยังตั้งค่า --platform_mappings=//:my_custom_mapping ได้ด้วย

โปรดดูรายละเอียดในการออกแบบการแมปแพลตฟอร์ม

การตรวจสอบ API

platform คือคอลเล็กชันของ constraint_value เป้าหมาย ได้แก่

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value คือพร็อพเพอร์ตี้เครื่อง ค่าต่างๆ ที่เป็น "ชนิด" เดียวกันจะจัดกลุ่มภายใต้ constraint_setting ทั่วไปดังนี้

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchain คือกฎของ Starlark แอตทริบิวต์ของแอตทริบิวต์ประกาศเครื่องมือของภาษา (เช่น compiler = "//mytoolchain:custom_gcc") ผู้ให้บริการจะส่งข้อมูลนี้ไปยังกฎที่จำเป็นต้องสร้างด้วยเครื่องมือเหล่านี้

Toolchains ประกาศ constraint_value ของเครื่องที่ กำหนดเป้าหมาย (target_compatible_with = ["@platforms//os:linux"]) และเครื่องที่เครื่องมือของตน ทำงานบนได้ (exec_compatible_with = ["@platforms//os:mac"])

เมื่อสร้าง $ bazel build //:myproject --platforms=//:myplatform Bazel จะเลือก Toolchain ที่เรียกใช้บนเครื่องบิลด์โดยอัตโนมัติและสร้างไบนารีสำหรับ //:myplatform ได้ วิธีนี้เรียกว่าความละเอียดของ Toolchain

ชุด Toolchain ที่พร้อมใช้งานสามารถลงทะเบียนใน WORKSPACE ด้วย register_toolchains หรือในบรรทัดคำสั่งกับ --extra_toolchains ได้

ดูข้อมูลเพิ่มเติมที่นี่

คำถาม

หากต้องการการสนับสนุนทั่วไปและมีคำถามเกี่ยวกับไทม์ไลน์การย้ายข้อมูล โปรดติดต่อbazel-discuss หรือเจ้าของกฎที่เหมาะสม

หากต้องการพูดคุยเกี่ยวกับการออกแบบและพัฒนา API ของแพลตฟอร์ม/เครื่องมือเชน โปรดติดต่อ bazel-dev

ดูเพิ่มเติม