การย้ายข้อมูลจาก Xcode ไปยัง Bazel

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

ความแตกต่างระหว่าง Xcode และ Bazel

  • Bazel กำหนดให้คุณระบุเป้าหมายการสร้างและทรัพยากร Dependency ทั้งหมดอย่างชัดเจน รวมถึงการตั้งค่าการสร้างที่เกี่ยวข้องผ่านกฎการสร้าง

  • Bazel กำหนดให้ไฟล์ทั้งหมดที่ต้องใช้โปรเจ็กต์อยู่ภายในไดเรกทอรีพื้นที่ทำงานหรือระบุเป็นการนำเข้าในไฟล์ WORKSPACE

  • เมื่อสร้างโปรเจ็กต์ Xcode ด้วย Bazel ไฟล์ BUILD จะเป็นแหล่งข้อมูล หากทำงานในโปรเจ็กต์ใน Xcode คุณต้องสร้างโปรเจ็กต์ Xcode เวอร์ชันใหม่ที่ตรงกับไฟล์ BUILD โดยใช้ rules_xcodeproj เมื่อใดก็ตามที่คุณอัปเดตไฟล์ BUILD การเปลี่ยนแปลงบางอย่างในไฟล์ BUILD เช่น การเพิ่มทรัพยากร Dependency ไปยังเป้าหมายไม่จำเป็นต้องสร้างโปรเจ็กต์อีกครั้งซึ่งช่วยให้การพัฒนาเร็วขึ้นได้ หากคุณไม่ได้ใช้ Xcode คำสั่ง bazel build และ bazel test จะมีความสามารถในการสร้างและทดสอบ โดยมีข้อจำกัดบางอย่างที่อธิบายไว้ในส่วนถัดไปของคู่มือนี้

ก่อนเริ่มต้น

โปรดทำตามขั้นตอนต่อไปนี้ก่อนเริ่มต้น

  1. ติดตั้ง Bazel หากยังไม่ได้ทำ

  2. หากคุณไม่คุ้นเคยกับ Bazel และแนวคิดต่างๆ โปรดดูบทแนะนำสำหรับแอป iOS คุณควรทำความเข้าใจเวิร์กสเปซ Bazel ซึ่งรวมถึงไฟล์ WORKSPACE และ BUILD ตลอดจนแนวคิดเกี่ยวกับเป้าหมาย กฎการสร้าง และแพ็กเกจ Bazel

  3. วิเคราะห์และทำความเข้าใจทรัพยากร Dependency ของโปรเจ็กต์

วิเคราะห์ทรัพยากร Dependency ของโปรเจ็กต์

ซึ่งแตกต่างจาก Xcode เนื่องจาก Bazel กำหนดให้คุณประกาศการอ้างอิงทั้งหมดสำหรับเป้าหมายทุกรายการในไฟล์ BUILD อย่างชัดเจน

ดูข้อมูลเพิ่มเติมเกี่ยวกับทรัพยากรภายนอกได้ที่หัวข้อการทํางานกับทรัพยากรภายนอก

สร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel

หากต้องการสร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel ให้ทำดังนี้

  1. สร้างไฟล์ WORKSPACE

  2. (ทดลอง) ผสานรวมข้อกําหนดของ SwiftPM

  3. สร้างไฟล์ BUILD

    ก. เพิ่มเป้าหมายแอปพลิเคชัน

    ข. (ไม่บังคับ) เพิ่มเป้าหมายการทดสอบ

    ค. เพิ่มเป้าหมายของคลัง

  4. (ไม่บังคับ) ปรับแต่งบิลด์

  5. เรียกใช้บิลด์

  6. สร้างโปรเจ็กต์ Xcode ด้วย rules_xcodeproj

ขั้นตอนที่ 1: สร้างไฟล์ WORKSPACE

สร้างไฟล์ WORKSPACE ในไดเรกทอรีใหม่ ไดเรกทอรีนี้จะกลายเป็นรูทของ พื้นที่ทำงาน Bazel หากโปรเจ็กต์ไม่ใช้ทรัพยากรภายนอก ไฟล์นี้อาจเป็นไฟล์ว่าง หากโปรเจ็กต์ใช้ไฟล์หรือแพ็กเกจที่ไม่ได้อยู่ในไดเรกทอรีของโปรเจ็กต์ ให้ระบุการพึ่งพาภายนอกเหล่านี้ในไฟล์ WORKSPACE

ขั้นตอนที่ 2: (ทดลอง) ผสานรวมทรัพยากร Dependency ของ SwiftPM

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

ขั้นตอนที่ 3: สร้างไฟล์ BUILD

เมื่อกำหนดพื้นที่ทำงานและไลบรารีภายนอกแล้ว คุณจะต้องสร้างไฟล์ BUILD เพื่อบอก Bazel ว่าโปรเจ็กต์มีโครงสร้างอย่างไร สร้างไฟล์ BUILD ที่รูทของพื้นที่ทํางาน Bazel และกำหนดค่าให้ทำการบิลด์โปรเจ็กต์ครั้งแรกดังนี้

เคล็ดลับ: ดูข้อมูลเพิ่มเติมเกี่ยวกับแพ็กเกจและแนวคิดอื่นๆ ของ Bazel ได้ที่พื้นที่ทำงาน แพ็กเกจ และเป้าหมาย

ขั้นตอนที่ 3ก: เพิ่มเป้าหมายแอปพลิเคชัน

เพิ่มเป้าหมายกฎ macos_application หรือ ios_application เป้าหมายนี้จะสร้าง App Bundle ของ macOS หรือ iOS ตามลำดับ ในเป้าหมาย ให้ระบุข้อมูลต่อไปนี้เป็นอย่างน้อย

  • bundle_id - รหัสชุด (เส้นทาง DNS ย้อนกลับตามด้วยชื่อแอป) ของไบนารี

  • provisioning_profile - โปรไฟล์การกําหนดค่าจากบัญชีนักพัฒนาแอป Apple (หากสร้างสําหรับอุปกรณ์ iOS)

  • families (iOS เท่านั้น) - เลือกว่าจะสร้างแอปพลิเคชันสำหรับ iPhone, iPad หรือทั้ง 2 อย่าง

  • infoplists - รายการไฟล์ .plist ที่จะผสานลงในไฟล์ Info.plist สุดท้าย

  • minimum_os_version - เวอร์ชัน macOS หรือ iOS ขั้นต่ำที่แอปพลิเคชันรองรับ วิธีนี้ช่วยให้มั่นใจได้ว่า Bazel จะสร้างแอปพลิเคชันด้วยระดับ API ที่ถูกต้อง

ขั้นตอนที่ 3ข: (ไม่บังคับ) เพิ่มเป้าหมายการทดสอบ

กฎการสร้างของ Apple ของ Bazel รองรับการเรียกใช้การทดสอบยูนิตที่อิงตามไลบรารีใน iOS และ macOS รวมถึงการทดสอบที่อิงตามแอปพลิเคชันใน macOS สําหรับการทดสอบที่อิงตามแอปพลิเคชันใน iOS หรือการทดสอบ UI บนแพลตฟอร์มใดแพลตฟอร์มหนึ่ง Bazel จะสร้างเอาต์พุตการทดสอบ แต่การทดสอบต้องทํางานภายใน Xcode ผ่านโปรเจ็กต์ที่สร้างด้วย rules_xcodeproj เพิ่มเป้าหมายการทดสอบดังนี้

  • macos_unit_test เพื่อเรียกใช้การทดสอบ 1 หน่วยที่อิงตามไลบรารีและที่อิงตามแอปพลิเคชันใน macOS

  • ios_unit_test เพื่อเรียกใช้การทดสอบ 1 หน่วยที่อิงตามไลบรารีใน iOS สําหรับการทดสอบที่ต้องใช้โปรแกรมจําลอง iOS Bazel จะสร้างเอาต์พุตการทดสอบ แต่ไม่เรียกใช้การทดสอบ คุณต้องสร้างโปรเจ็กต์ Xcode ด้วย rules_xcodeproj และเรียกใช้การทดสอบจากภายใน Xcode

  • ios_ui_test เพื่อสร้างเอาต์พุตที่จําเป็นสําหรับการเรียกใช้การทดสอบอินเทอร์เฟซผู้ใช้ในโปรแกรมจําลอง iOS ใช้ Xcode คุณต้องสร้างโปรเจ็กต์ Xcode ด้วย rules_xcodeproj และเรียกใช้การทดสอบจากภายใน Xcode Bazel ไม่สามารถเรียกใช้การทดสอบ UI เองได้

ระบุค่าสำหรับแอตทริบิวต์ minimum_os_version เป็นอย่างน้อย แม้ว่าแอตทริบิวต์แพ็กเกจอื่นๆ เช่น bundle_identifier และ infoplists จะมีค่าเริ่มต้นเป็นค่าที่ใช้บ่อยที่สุด แต่โปรดตรวจสอบว่าค่าเริ่มต้นเหล่านั้นเข้ากันได้กับโปรเจ็กต์และปรับเปลี่ยนตามความเหมาะสม สำหรับการทดสอบที่ต้องใช้เครื่องจำลอง iOS ให้ระบุชื่อเป้าหมาย ios_application เป็นค่าของแอตทริบิวต์ test_host ด้วย

ขั้นตอนที่ 3ค: เพิ่มเป้าหมายไลบรารี

เพิ่มเป้าหมาย objc_library ให้กับไลบรารี Objective-C แต่ละรายการ และเป้าหมาย swift_library ให้กับไลบรารี Swift แต่ละรายการที่แอปพลิเคชันและ/หรือการทดสอบใช้

เพิ่มเป้าหมายไลบรารีดังนี้

  • เพิ่มเป้าหมายของไลบรารีแอปพลิเคชันเป็นข้อกำหนดของเป้าหมายแอปพลิเคชัน

  • เพิ่มเป้าหมายไลบรารีทดสอบเป็นทรัพยากร Dependency ไปยังเป้าหมายทดสอบ

  • แสดงแหล่งที่มาของการติดตั้งใช้งานในแอตทริบิวต์ srcs

  • แสดงรายการส่วนหัวในแอตทริบิวต์ hdrs

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับกฎการสร้างได้ที่กฎของ Apple สำหรับ Bazel

ตอนนี้คุณควรทดสอบบิลด์ โดยทำดังนี้

bazel build //:<application_target>

ขั้นตอนที่ 4: (ไม่บังคับ) ปรับแต่งบิลด์ให้ละเอียดยิ่งขึ้น

หากโปรเจ็กต์มีขนาดใหญ่หรือเมื่อโตขึ้น ให้พิจารณาแบ่งโปรเจ็กต์ออกเป็นแพ็กเกจ Bazel หลายๆ แพ็กเกจ รายละเอียดที่ละเอียดยิ่งขึ้นนี้ให้ประโยชน์ดังนี้

  • การเพิ่มจำนวนบิลด์

  • เพิ่มการทํางานแบบขนานของงานสร้าง

  • ความสามารถในการบำรุงรักษาที่ดียิ่งขึ้นสำหรับผู้ใช้ในอนาคต

  • ควบคุมการมองเห็นซอร์สโค้ดในเป้าหมายและแพ็กเกจได้ดียิ่งขึ้น วิธีนี้ช่วยป้องกันปัญหาต่างๆ เช่น ไลบรารีที่มีรายละเอียดการใช้งานรั่วไหลไปยัง API สาธารณะ

เคล็ดลับในการทำให้โปรเจ็กต์มีรายละเอียดมากขึ้น

  • ใส่ไลบรารีแต่ละรายการในแพ็กเกจ Bazel ของตัวเอง ให้เริ่มต้นจากทรัพยากรที่ต้องใช้ทรัพยากร Dependency น้อยที่สุดและค่อยๆ เลื่อนขึ้นไปยังแผนผัง Dependency

  • เมื่อคุณเพิ่มไฟล์ BUILD และระบุเป้าหมาย ให้เพิ่มเป้าหมายใหม่เหล่านี้ลงในแอตทริบิวต์ deps ของเป้าหมายที่ขึ้นอยู่กับไฟล์ BUILD

  • ฟังก์ชัน glob() ไม่ข้ามขอบเขตของแพ็กเกจ ดังนั้นเมื่อจำนวนแพ็กเกจเพิ่มจำนวนขึ้น ไฟล์ที่ตรงกับ glob() จะลดขนาดลง

  • เมื่อเพิ่มไฟล์ BUILD ลงในไดเรกทอรี main ให้เพิ่มไฟล์ BUILD ลงในไดเรกทอรี test ที่เกี่ยวข้องด้วย

  • บังคับใช้ขีดจำกัดระดับการเข้าถึงที่มีประสิทธิภาพดีในแพ็กเกจต่างๆ

  • สร้างโปรเจ็กต์หลังการเปลี่ยนแปลงที่สำคัญแต่ละรายการในไฟล์ BUILD และแก้ไขข้อผิดพลาดทันทีที่พบข้อผิดพลาด

ขั้นตอนที่ 5: เรียกใช้บิลด์

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

เช่น

bazel build //:my-target

ขั้นตอนที่ 6: สร้างโปรเจ็กต์ Xcode ด้วย rules_xcodeproj

เมื่อสร้างด้วย Bazel ไฟล์ WORKSPACE และ BUILD จะกลายเป็นแหล่งข้อมูลที่แท้จริงเกี่ยวกับบิลด์ หากต้องการให้ Xcode ทราบถึงการดำเนินการนี้ คุณต้องสร้างโปรเจ็กต์ Xcode ที่เข้ากันได้กับ Bazel โดยใช้ rules_xcodeproj

การแก้ปัญหา

ข้อผิดพลาดของ Bazel อาจเกิดขึ้นเมื่อไม่ซิงค์กับเวอร์ชัน Xcode ที่เลือก เช่น เมื่อคุณใช้การอัปเดต ลองทำตามขั้นตอนต่อไปนี้หากพบข้อผิดพลาดเกี่ยวกับ Xcode เช่น "ต้องระบุเวอร์ชัน Xcode เพื่อใช้ Apple CROSSTOOL"

  • เรียกใช้ Xcode ด้วยตนเองและยอมรับข้อกำหนดและเงื่อนไข

  • ใช้ Xcode Select เพื่อระบุเวอร์ชันที่ถูกต้อง ยอมรับใบอนุญาต และล้างสถานะของ Bazel

  sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  sudo xcodebuild -license
  bazel sync --configure
  • หากไม่ได้ผล ให้ลองเรียกใช้ bazel clean --expunge ด้วย