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++ กับแพลตฟอร์ม โปรดดู การย้ายข้อมูลโปรเจ็กต์และ การกำหนดค่า Toolchain ของ 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
แทนที่จะใช้แฟล็กเดิม เช่น --android_crosstool_top
, --android_cpu
และ --fat_apk_cpu
ซึ่งจะเปิดใช้โดยค่าเริ่มต้นใน Bazel 7.0 (#16285)
หากต้องการทดสอบโปรเจ็กต์ Android กับแพลตฟอร์มต่างๆ โปรดดูการย้ายข้อมูลโปรเจ็กต์
Apple
กฎของ Apple ไม่รองรับแพลตฟอร์มและยังไม่มีกำหนดการ ที่จะรองรับ
คุณยังคงใช้ API ของแพลตฟอร์มกับบิลด์ของ Apple ได้ (เช่น เมื่อสร้างโดยใช้กฎของ Apple และ C++ ล้วน) ด้วยการแมปแพลตฟอร์ม
ภาษาอื่นๆ
- กฎ Go รองรับแพลตฟอร์มอย่างเต็มรูปแบบ
- กฎการเชื่อถือรองรับแพลตฟอร์มอย่างเต็มรูปแบบ
หากคุณเป็นเจ้าของชุดกฎภาษา โปรดดูการย้ายข้อมูลชุดกฎเพื่อเพิ่ม การสนับสนุน
ฉากหลัง
แพลตฟอร์มและทูลเชนได้รับการเปิดตัวเพื่อกำหนดมาตรฐานวิธีที่โปรเจ็กต์ซอฟต์แวร์ กำหนดเป้าหมายสถาปัตยกรรมต่างๆ และคอมไพล์ข้าม
ฟีเจอร์นี้ได้แรงบันดาลใจ
จากการสังเกตว่าผู้ดูแลภาษาได้ทำสิ่งนี้อยู่แล้วในลักษณะเฉพาะกิจที่ไม่เข้ากัน เช่น กฎ C++ ใช้ --cpu
และ
--crosstool_top
เพื่อประกาศ CPU เป้าหมายและเครื่องมือ ทั้ง 2 อย่างนี้
ไม่ได้จำลอง "แพลตฟอร์ม" อย่างถูกต้อง ซึ่งทำให้เกิดการสร้างที่ไม่เหมาะสมและไม่ถูกต้อง
Java, Android และภาษาอื่นๆ ได้พัฒนาฟีเจอร์ของตนเองเพื่อวัตถุประสงค์ที่คล้ายกัน แต่ไม่มีฟีเจอร์ใดที่ทำงานร่วมกันได้ ซึ่งทำให้การสร้างข้ามภาษา ซับซ้อนและสับสน
Bazel ออกแบบมาสำหรับโปรเจ็กต์ขนาดใหญ่ที่มีหลายภาษาและหลายแพลตฟอร์ม ซึ่งต้องมีการสนับสนุนแนวคิดเหล่านี้อย่างมีหลักการมากขึ้น รวมถึง API มาตรฐานที่ชัดเจน
ความจำเป็นในการย้ายข้อมูล
การอัปเกรดเป็น API ใหม่ต้องใช้ความพยายาม 2 อย่าง ได้แก่ การเปิดตัว API และการอัปเกรด ตรรกะของกฎเพื่อใช้ API
โดยการดำเนินการแรกเสร็จสมบูรณ์แล้ว แต่การดำเนินการที่ 2 ยังคงดำเนินอยู่ ซึ่งประกอบด้วยการตรวจสอบว่าได้กำหนดแพลตฟอร์มและชุดเครื่องมือเฉพาะภาษาแล้ว ตรรกะของภาษาจะอ่านชุดเครื่องมือผ่าน API ใหม่แทนที่จะใช้แฟล็กเก่า เช่น --crosstool_top
และ config_setting
s จะเลือกใน API ใหม่แทนที่จะใช้แฟล็กเก่า
งานนี้ตรงไปตรงมา แต่ต้องใช้ความพยายามที่แตกต่างกันสำหรับแต่ละภาษา รวมถึงคำเตือนที่ชัดเจนสำหรับเจ้าของโปรเจ็กต์ในการทดสอบกับการเปลี่ยนแปลงที่กำลังจะเกิดขึ้น
ด้วยเหตุนี้ การย้ายข้อมูลจึงเป็นกระบวนการที่ต้องดำเนินการอย่างต่อเนื่อง
เป้าหมาย
การย้ายข้อมูลนี้จะเสร็จสมบูรณ์เมื่อโปรเจ็กต์ทั้งหมดที่สร้างด้วยแบบฟอร์มมีลักษณะดังนี้
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
โดยทั่วไปแล้ว เจ้าของโปรเจ็กต์มีหน้าที่ กำหนดแพลตฟอร์ม เนื่องจากโปรเจ็กต์ต่างๆ มีเป้าหมายเป็นเครื่องที่แตกต่างกัน ดูแพลตฟอร์มเริ่มต้นต้องมี Toolchain ที่คุณต้องการใช้ หากใช้เครื่องมือเชนในสต็อก เจ้าของภาษาควรระบุวิธีการลงทะเบียนเครื่องมือเชนเหล่านั้น หากเขียนเครื่องมือที่กำหนดเอง คุณต้องลงทะเบียนเครื่องมือเหล่านั้นในไฟล์
MODULE.bazel
หรือใช้--extra_toolchains
select()
และการเปลี่ยนการกำหนดค่าต้อง ได้รับการแก้ไขอย่างถูกต้อง ดู select() และการเปลี่ยนฉากหากบิลด์ของคุณมีทั้งภาษาที่รองรับและไม่รองรับแพลตฟอร์ม คุณอาจต้องมีการแมปแพลตฟอร์มเพื่อช่วยให้ภาษาเดิมทำงานร่วมกับ 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
s อย่างน้อย 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 รูปแบบในระหว่างการย้ายข้อมูล
window
การย้ายข้อมูลชุดกฎ
หากคุณเป็นเจ้าของชุดกฎและต้องการรองรับแพลตฟอร์ม คุณต้องดำเนินการต่อไปนี้
มีตรรกะของกฎที่แก้ไข Toolchain ด้วย Toolchain API ดูAPI ของชุดเครื่องมือ (
ctx.toolchains
)ไม่บังคับ: กำหนดแฟล็ก
--incompatible_enable_platforms_for_my_language
เพื่อให้ตรรกะของกฎ แก้ไข Toolchain สลับกันผ่าน API ใหม่หรือแฟล็กเก่า เช่น--crosstool_top
ระหว่างการทดสอบการย้ายข้อมูลกำหนดพร็อพเพอร์ตี้ที่เกี่ยวข้องซึ่งประกอบกันเป็นคอมโพเนนต์ของแพลตฟอร์ม ดูพร็อพเพอร์ตี้แพลตฟอร์มทั่วไป
กำหนด Toolchain มาตรฐานและทำให้ผู้ใช้เข้าถึงได้ผ่านวิธีการลงทะเบียนของกฎ (รายละเอียด)
ตรวจสอบว่าแพลตฟอร์มรองรับ
select()
และการเปลี่ยนการกำหนดค่า นี่เป็น ความท้าทายที่ยิ่งใหญ่ที่สุด โดยเฉพาะอย่างยิ่งสำหรับโปรเจ็กต์ที่มีหลายภาษา (ซึ่งอาจล้มเหลวหากทุกภาษาอ่าน--platforms
ไม่ได้)
หากต้องการใช้ร่วมกับกฎที่ไม่รองรับแพลตฟอร์ม คุณอาจต้องใช้การแมปแพลตฟอร์มเพื่อเชื่อมช่องว่าง
พร็อพเพอร์ตี้แพลตฟอร์มทั่วไป
พร็อพเพอร์ตี้แพลตฟอร์มทั่วไปที่ใช้ได้หลายภาษา เช่น OS
และ CPU
ควรประกาศใน @platforms
ซึ่งจะช่วยกระตุ้นการแชร์ การสร้างมาตรฐาน และความเข้ากันได้ข้ามภาษา
ควรประกาศพร็อพเพอร์ตี้เฉพาะของกฎในที่เก็บของกฎ ซึ่งจะช่วยให้คุณรักษาความเป็นเจ้าของที่ชัดเจนในแนวคิดที่เฉพาะเจาะจงซึ่งกฎของคุณ รับผิดชอบ
หากกฎของคุณใช้ระบบปฏิบัติการหรือ CPU ที่มีวัตถุประสงค์ที่กำหนดเอง คุณควรประกาศไว้ในที่เก็บของกฎเทียบกับ
@platforms
การแมปแพลตฟอร์ม
การแมปแพลตฟอร์มเป็น API ชั่วคราวที่ช่วยให้ตรรกะที่รับรู้แพลตฟอร์มผสมกับตรรกะเดิมในการสร้างเดียวกันได้ นี่เป็นเครื่องมือที่ตรงไปตรงมาซึ่งมีไว้เพื่อ ลดความไม่เข้ากันกับกรอบเวลาการย้ายข้อมูลที่แตกต่างกันเท่านั้น
การแมปแพลตฟอร์มคือการแมปplatform()
กับชุดฟีเจอร์เดิมที่เกี่ยวข้องหรือในทางกลับกัน เช่น
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"
จะประกาศเครื่องมือของภาษา (เช่น compiler =
"//mytoolchain:custom_gcc"
) ส่วน providers จะส่งต่อข้อมูลนี้ไปยังกฎที่ต้องสร้างด้วยเครื่องมือเหล่านี้
Toolchain จะประกาศ constraint_value
ของเครื่องที่สามารถ
กำหนดเป้าหมาย
(target_compatible_with = ["@platforms//os:linux"]
) และเครื่องที่เครื่องมือสามารถ
เรียกใช้
(exec_compatible_with = ["@platforms//os:mac"]
)
เมื่อสร้าง $ bazel build //:myproject --platforms=//:myplatform
, Bazel
จะเลือก Toolchain ที่สามารถเรียกใช้ในเครื่องบิลด์และ
สร้างไบนารีสำหรับ //:myplatform
โดยอัตโนมัติ การดำเนินการนี้เรียกว่าการแก้ปัญหา Toolchain
คุณสามารถลงทะเบียนชุดเครื่องมือที่พร้อมใช้งานในไฟล์ MODULE.bazel
ด้วย register_toolchains
หรือใน
บรรทัดคำสั่งด้วย --extra_toolchains
ดูข้อมูลเพิ่มเติมที่นี่
คำถาม
หากต้องการรับการสนับสนุนทั่วไปและมีคำถามเกี่ยวกับไทม์ไลน์การย้ายข้อมูล โปรดติดต่อ bazel-discuss หรือเจ้าของกฎที่เหมาะสม
หากต้องการพูดคุยเกี่ยวกับการออกแบบและวิวัฒนาการของ API แพลตฟอร์ม/เครื่องมือ โปรดติดต่อ bazel-dev