Bazel มีการรองรับที่ซับซ้อนสำหรับการจำลองแพลตฟอร์มและชุดเครื่องมือสำหรับบิลด์หลายสถาปัตยกรรมและบิลด์ที่คอมไพล์ข้าม
หน้านี้จะสรุปสถานะการสนับสนุนนี้
และดู:
สถานะ
C++
กฎ C++ ใช้แพลตฟอร์มเพื่อเลือกชุดเครื่องมือเมื่อตั้งค่า --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
ซึ่งจะใช้แทน Flag เดิมอย่าง --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
กฎของ Apple ไม่รองรับแพลตฟอร์มและยังไม่มีกำหนดเวลาให้การสนับสนุน
คุณยังคงใช้ API ของแพลตฟอร์มกับบิลด์ของ Apple ได้ (เช่น เมื่อสร้างโดยใช้กฎของ Apple ร่วมกับ C++ ที่แท้จริง) ด้วยการแมปแพลตฟอร์ม
ภาษาอื่นๆ
หากคุณเป็นเจ้าของชุดกฎภาษา โปรดดูการย้ายข้อมูลชุดกฎเพื่อเพิ่มการสนับสนุน
ข้อมูลเบื้องต้น
มีการนำแพลตฟอร์มและเครื่องมือเชนมาใช้เพื่อกำหนดมาตรฐานวิธีที่โปรเจ็กต์ซอฟต์แวร์จะกำหนดเป้าหมายสถาปัตยกรรมที่ต่างกันและการคอมไพล์แบบข้ามแพลตฟอร์ม
แนวคิดนี้ได้รับแรงบันดาลใจจากการสังเกตว่าผู้ดูแลภาษาทําเช่นนี้อยู่แล้วในลักษณะที่ไม่สอดคล้องกัน เช่น กฎ C++ ใช้ --cpu
และ
--crosstool_top
เพื่อประกาศ CPU และเครื่องมือทางเทคนิคเป้าหมาย ตัวอย่างทั้ง 2 รายการนี้ไม่ได้จําลอง "แพลตฟอร์ม" อย่างถูกต้อง ซึ่งทำให้ได้บิลด์ที่ไม่ถูกต้องและดูไม่เหมาะสม
Java, Android และภาษาอื่นๆ ได้พัฒนาแฟล็กของตนเองเพื่อวัตถุประสงค์ที่คล้ายกัน ซึ่งไม่มีแฟล็กใดที่ทำงานร่วมกันได้ ซึ่งทำให้การสร้างหลายภาษามีความสับสนและซับซ้อน
Bazel ออกแบบมาสำหรับโปรเจ็กต์ขนาดใหญ่ที่ใช้หลายภาษาและหลายแพลตฟอร์ม ด้วยเหตุนี้ เราจึงต้องการการสนับสนุนแนวคิดเหล่านี้อย่างมีหลักการมากขึ้น รวมถึง API มาตรฐานที่ชัดเจน
ความจำเป็นในการย้ายข้อมูล
การอัปเกรดเป็น API ใหม่ต้องใช้ความพยายาม 2 อย่าง ได้แก่ การเผยแพร่ API และการอัปเกรดตรรกะกฎเพื่อใช้งาน
รายการแรกเสร็จแล้ว แต่รายการที่ 2 ยังอยู่ระหว่างดำเนินการ ซึ่งประกอบด้วยการตรวจสอบว่าได้กำหนดแพลตฟอร์มและเครื่องมือทางภาษาเฉพาะภาษาแล้ว ตรรกะภาษาจะอ่านเครื่องมือทางภาษาผ่าน API ใหม่แทน Flag เดิม เช่น --crosstool_top
และconfig_setting
จะเลือกใน API ใหม่แทน Flag เดิม
งานนี้ตรงไปตรงมาแต่ต้องใช้ความพยายามที่แตกต่างกันสำหรับแต่ละภาษา รวมถึงคำเตือนที่ยุติธรรมสำหรับเจ้าของโปรเจ็กต์เพื่อทดสอบกับการเปลี่ยนแปลงที่กําลังจะเกิดขึ้น
นี่จึงเป็นสาเหตุที่ต้องทำการย้ายข้อมูลอย่างต่อเนื่อง
เป้าหมาย
การย้ายข้อมูลนี้จะเสร็จสมบูรณ์เมื่อโปรเจ็กต์ทั้งหมดสร้างด้วยฟอร์ม:
bazel build //:myproject --platforms=//:myplatform
ซึ่งหมายความว่า
- กฎของโปรเจ็กต์จะเลือกเครื่องมือทางเทคนิคที่เหมาะสมสําหรับ
//:myplatform
- ไลบรารีของโปรเจ็กต์จะเลือกเครื่องมือทางเทคนิคที่เหมาะสมสําหรับ
//:myplatform
//:myplatform
อ้างอิงการประกาศทั่วไปของCPU
,OS
และพร็อพเพอร์ตี้ทั่วไปอื่นๆ ที่ไม่ขึ้นอยู่กับภาษาselect()
ที่เกี่ยวข้องทั้งหมดจับคู่กับ//:myplatform
อย่างถูกต้อง//:myplatform
ได้รับการกําหนดในที่ที่เข้าถึงได้ชัดเจน เช่น ในรีโปของโปรเจ็กต์หากแพลตฟอร์มนั้นใช้เฉพาะกับโปรเจ็กต์ของคุณ หรือที่ที่โปรเจ็กต์ที่บริโภคทั้งหมดสามารถค้นหาได้
เราจะเลิกใช้งานและนําแฟล็กเก่าๆ เช่น --cpu
, --crosstool_top
และ --fat_apk_cpu
ออกทันทีที่ดำเนินการได้อย่างปลอดภัย
ท้ายที่สุดแล้ว การดำเนินการนี้จะกลายเป็นวิธีเดียวในการกำหนดค่าสถาปัตยกรรม
กำลังย้ายข้อมูลโปรเจ็กต์
หากคุณสร้างด้วยภาษาที่รองรับแพลตฟอร์ม บิลด์ของคุณควรทํางานกับการเรียกใช้ เช่น
bazel build //:myproject --platforms=//:myplatform
ดูรายละเอียดอย่างละเอียดได้ที่สถานะและเอกสารประกอบของภาษา
หากภาษาใดต้องใช้ Flag เพื่อเปิดใช้การรองรับแพลตฟอร์ม คุณจะต้องตั้งค่า Flag นั้นด้วย ดูรายละเอียดได้ที่สถานะ
คุณต้องตรวจสอบรายการต่อไปนี้เพื่อให้โปรเจ็กต์สร้าง
//:myplatform
ต้องมีอยู่ โดยทั่วไปแล้ว เจ้าของโปรเจ็กต์มีหน้าที่รับผิดชอบในการกําหนดแพลตฟอร์ม เนื่องจากโปรเจ็กต์ต่างๆ จะกําหนดเป้าหมายไปยังเครื่องที่แตกต่างกัน โปรดดูแพลตฟอร์มเริ่มต้นเครื่องมือทางเทคนิคที่คุณต้องการใช้ต้องมีอยู่ หากใช้เครื่องมือทางภาษาที่มีอยู่ เจ้าของภาษาควรระบุวิธีการลงทะเบียนเครื่องมือเหล่านั้น หากเขียนเครื่องมือทางเทคนิคที่กําหนดเอง คุณจะต้องregisterเครื่องมือเหล่านั้นในไฟล์
MODULE.bazel
หรือกับ--extra_toolchains
select()
และการเปลี่ยนการกำหนดค่าต้องได้รับการแก้ไขอย่างถูกต้อง ดูselect() และ Transitionsหากบิลด์ของคุณผสมภาษาที่รองรับและไม่รองรับแพลตฟอร์ม คุณอาจต้องใช้การแมปแพลตฟอร์มเพื่อช่วยให้ภาษาเดิมทำงานร่วมกับ API ใหม่ได้ ดูรายละเอียดได้ที่การแมปแพลตฟอร์ม
หากยังพบปัญหาอยู่ โปรดติดต่อขอรับการสนับสนุน
แพลตฟอร์มเริ่มต้น
เจ้าของโปรเจ็กต์ควรกำหนดแพลตฟอร์มอย่างชัดเจนเพื่ออธิบายสถาปัตยกรรมที่ต้องการสร้าง จากนั้นระบบจะทริกเกอร์เหตุการณ์เหล่านี้ด้วย --platforms
เมื่อไม่ได้ตั้งค่า --platforms
ค่าเริ่มต้นของ Bazel จะเป็น platform
ที่แสดงถึงเครื่องสำหรับสร้างในเครื่อง ระบบจะสร้างค่านี้โดยอัตโนมัติที่ @platforms//host
(ใช้แทนที่ด้วย @bazel_tools//tools:host_platform
) คุณจึงไม่ต้องกําหนดค่านี้อย่างชัดเจน โดยจะแมป 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
หรือ Flag เดิมอื่นๆ กฎที่อ่าน --platforms
จะไม่แสดงการเปลี่ยนแปลงเหล่านี้
เมื่อย้ายข้อมูลโปรเจ็กต์ไปยังแพลตฟอร์ม คุณต้องแปลงการเปลี่ยนแปลง เช่น return { "//command_line_option:cpu": "arm" }
เป็น return {
"//command_line_option:platforms": "//:my_arm_platform" }
หรือใช้การแมปแพลตฟอร์มเพื่อรองรับทั้ง 2 รูปแบบในระหว่างการย้ายข้อมูล
การย้ายข้อมูลชุดกฎ
หากคุณเป็นเจ้าของชุดกฎและต้องการสนับสนุนแพลตฟอร์ม คุณต้องดำเนินการดังนี้
มีการแปลง Toolchain ของกฎด้วย Toolchain API ดูToolchain API (
ctx.toolchains
)ไม่บังคับ: กําหนด Flag
--incompatible_enable_platforms_for_my_language
เพื่อให้ตรรกะกฎแก้ไข Toolchain ผ่าน API ใหม่หรือ Flag เก่าสลับกัน เช่น--crosstool_top
ในระหว่างการทดสอบการย้ายข้อมูลกําหนดพร็อพเพอร์ตี้ที่เกี่ยวข้องซึ่งประกอบกันเป็นคอมโพเนนต์ของแพลตฟอร์ม ดูพร็อพเพอร์ตี้แพลตฟอร์มทั่วไป
กำหนดเครื่องมือมาตรฐานและทำให้ผู้ใช้เข้าถึงเครื่องมือเหล่านั้นได้ผ่านวิธีการลงทะเบียนของกฎ (รายละเอียด)
ตรวจสอบว่าแพลตฟอร์มรองรับ
select()
และการเปลี่ยนการกำหนดค่า นี่เป็นปัญหาที่ใหญ่ที่สุด ซึ่งมีความท้าทายอย่างยิ่งสำหรับโปรเจ็กต์หลายภาษา (ซึ่งอาจล้มเหลวหากทุกภาษาอ่าน--platforms
ไม่ได้)
หากต้องการใช้กฎที่ไม่รองรับแพลตฟอร์มต่างๆ ร่วมกัน คุณอาจต้องการแมปแพลตฟอร์มเพื่อเชื่อมช่องว่าง
พร็อพเพอร์ตี้ของแพลตฟอร์มทั่วไป
คุณควรประกาศพร็อพเพอร์ตี้แพลตฟอร์มทั่วไปที่ข้ามภาษา เช่น OS
และ CPU
ใน @platforms
ซึ่งจะช่วยส่งเสริมให้เกิดการแชร์ มาตรฐาน และการรองรับหลายภาษา
คุณควรประกาศพร็อพเพอร์ตี้ที่ไม่ซ้ำกันสำหรับกฎของคุณในที่เก็บของกฎ วิธีนี้ช่วยให้คุณรักษาความเป็นเจ้าของที่ชัดเจนในแนวคิดที่เฉพาะเจาะจงซึ่งกฎของคุณมีหน้าที่รับผิดชอบ
หากกฎใช้ระบบปฏิบัติการหรือ CPU ตามวัตถุประสงค์ที่กำหนดเอง ควรประกาศเหล่านี้ในที่เก็บของกฎเทียบกับ @platforms
การแมปแพลตฟอร์ม
การแมปแพลตฟอร์มเป็น API ชั่วคราวที่ช่วยให้ผสมตรรกะแบบรับรู้แพลตฟอร์มกับตรรกะเดิมในบิลด์เดียวกันได้ เครื่องมือนี้เป็นชนิดทื่อที่มีไว้เพื่อแก้ไขความไม่เข้ากันกับกรอบเวลาการย้ายข้อมูลที่แตกต่างกันเท่านั้น
การแมปแพลตฟอร์มคือการแมป platform()
กับชุด Flag รุ่นเดิมที่สอดคล้องกัน หรือในทางกลับกัน เช่น
platforms:
# Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
//platforms:ios
--ios_multi_cpus=x86_64
--apple_platform_type=ios
flags:
# Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--ios_multi_cpus=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"
) ส่วนผู้ให้บริการจะส่งข้อมูลนี้ไปยังกฎที่ต้องสร้างด้วยเครื่องมือเหล่านี้
toolchain จะประกาศconstraint_value
ของเครื่องที่กำหนดเป้าหมายได้ (target_compatible_with = ["@platforms//os:linux"]
) และเครื่องที่เครื่องมือของ toolchain ทำงานได้ (exec_compatible_with = ["@platforms//os:mac"]
)
เมื่อสร้าง $ bazel build //:myproject --platforms=//:myplatform
ทาง Bazel จะเลือกชุดเครื่องมือที่ทำงานบนเครื่องที่ใช้สร้างได้และสร้างไบนารีสำหรับ //:myplatform
โดยอัตโนมัติ การดำเนินการนี้เรียกว่าการแก้ไขเครื่องมือทางเทคนิค
คุณสามารถลงทะเบียนชุดเครื่องมือที่ใช้ได้ในไฟล์ MODULE.bazel
ด้วย register_toolchains
หรือที่บรรทัดคำสั่งด้วย --extra_toolchains
ดูข้อมูลเพิ่มเติมที่นี่
คำถาม
หากต้องการการสนับสนุนทั่วไปและคำถามเกี่ยวกับลำดับเวลาการย้ายข้อมูล โปรดติดต่อ bazel-discuss หรือเจ้าของกฎที่เหมาะสม
หากต้องการพูดคุยเกี่ยวกับการออกแบบและพัฒนา API ของแพลตฟอร์ม/เครื่องมือเชน โปรดติดต่อ bazel-dev