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

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

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

  • 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. วิเคราะห์และทำความเข้าใจทรัพยากร Dependency ของโปรเจ็กต์

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

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

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

สร้างหรือทดสอบโปรเจ็กต์ 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: (ทดลอง) ผสานรวมทรัพยากร 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 Developer (หากสร้างสำหรับอุปกรณ์ iOS)

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

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

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

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

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

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

  • ios_unit_test เพื่อสร้างและเรียกใช้การทดสอบ 1 หน่วยที่อิงตามไลบรารีใน 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 แต่ละรายการที่แอปพลิเคชันและ/หรือการทดสอบขึ้นอยู่ด้วย

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

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

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

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

  • ระบุส่วนหัวในhdrsแอตทริบิวต์

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับกฎการสร้างได้ที่กฎของ 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 อาจเกิดขึ้นเมื่อไม่ซิงค์กับ 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