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

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

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

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

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

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

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

ก่อนเริ่มต้น ให้ทำดังนี้

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

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

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

วิเคราะห์การขึ้นต่อกันของโปรเจ็กต์

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

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

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

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

  1. สร้างไฟล์ MODULE.bazel

  2. (ทดลอง) ผสานรวมการขึ้นต่อกันของ SwiftPM

  3. สร้างไฟล์ BUILD โดยทำดังนี้

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

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

    ค. เพิ่มเป้าหมายของไลบรารี

  4. (ไม่บังคับ) แยกย่อยบิลด์

  5. เรียกใช้การสร้าง

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

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

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

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

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

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

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

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

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

เพิ่มเป้าหมายกฎ macos_application หรือ ios_application เป้าหมายนี้จะสร้างชุดแอปพลิเคชัน 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ข: (ไม่บังคับ) เพิ่มเป้าหมายการทดสอบ

กฎการสร้าง แอปเปิล ของ Bazel รองรับการเรียกใช้ การทดสอบหน่วยและการทดสอบ UI ในแพลตฟอร์ม Apple ทั้งหมด เพิ่มเป้าหมายการทดสอบดังนี้

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

  • ios_unit_test เพื่อสร้างและเรียกใช้การทำ Unit Test ที่อิงตามไลบรารีใน iOS

  • ios_ui_test เพื่อสร้างและเรียกใช้การทดสอบอินเทอร์เฟซผู้ใช้ในโปรแกรมจำลอง iOS

  • กฎการทดสอบที่คล้ายกันมีไว้สำหรับ tvOS, watchOS และ visionOS

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

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

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

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

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

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

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

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

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

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

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

bazel build //:<application_target>

ขั้นตอนที่ 4: (ไม่บังคับ) แยกย่อยบิลด์

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

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

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

  • การดูแลรักษาที่ดีขึ้นสำหรับผู้ใช้ในอนาคต

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

เคล็ดลับในการแยกย่อยโปรเจ็กต์

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

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

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

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

  • บังคับใช้ขีดจำกัดการแสดงผลที่เหมาะสมในแพ็กเกจ

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

ขั้นตอนที่ 5: เรียกใช้การสร้าง

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

เช่น

bazel build //:my-target

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

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

การแก้ปัญหา

ข้อผิดพลาดของ Bazel อาจเกิดขึ้นเมื่อ 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