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

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

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

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

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

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

  • เนื่องจากความแตกต่างในสคีมาการกำหนดค่าการสร้าง เช่น เลย์เอาต์ไดเรกทอรี หรือแฟล็กการสร้าง Xcode จึงอาจไม่ทราบ "ภาพรวม" ของ การสร้างอย่างเต็มที่ และฟีเจอร์บางอย่างของ Xcode อาจไม่ทำงาน ได้แก่

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

    • การวิเคราะห์แบบคงที่, Address Sanitizer และ Thread Sanitizer อาจไม่ทำงาน เนื่องจาก Bazel ไม่สร้างเอาต์พุตที่ Xcode คาดหวังสำหรับฟีเจอร์เหล่านั้น

    • หากคุณสร้างโปรเจ็กต์ Xcode ด้วย Tulsi และใช้โปรเจ็กต์นั้นเพื่อเรียกใช้การทดสอบจากภายใน Xcode แล้ว Xcode จะเรียกใช้การทดสอบแทน Bazel หากต้องการเรียกใช้การทดสอบด้วย Bazel ให้เรียกใช้คำสั่ง bazel test ด้วยตนเอง

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

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

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

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

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

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

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

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

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

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

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

  2. (ทดลอง) ผสานรวมทรัพยากร Dependency ของ CocoaPods

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

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

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

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

  4. (ไม่บังคับ) แยกย่อยการสร้าง

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

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

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

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

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

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

ขั้นตอนที่ 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 รองรับ การเรียกใช้การทดสอบหน่วยที่อิงตามไลบรารีใน iOS และ macOS รวมถึงการทดสอบที่อิงตามแอปพลิเคชัน ใน macOS สำหรับการทดสอบที่อิงตามแอปพลิเคชันใน iOS หรือการทดสอบ UI ในแพลตฟอร์มใดก็ตาม Bazel จะสร้างเอาต์พุตการทดสอบ แต่การทดสอบต้องทำงานภายใน Xcode ผ่านโปรเจ็กต์ที่สร้างด้วย Tulsi เพิ่มเป้าหมายการทดสอบดังนี้

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

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

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

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

ขั้นตอนที่ 3ค: เพิ่มเป้าหมายห้องสมุด

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

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

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

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

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

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

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

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

การแก้ปัญหา

ข้อผิดพลาดของ 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