การย้ายข้อมูลจาก 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 หรือระบุเป็นการนำเข้าในไฟล์ WORKSPACE

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • provisioning_profile - โปรไฟล์การจัดสรรจากนักพัฒนาซอฟต์แวร์ของ Apple (หากสร้างสำหรับอุปกรณ์ iOS)

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

  • 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 โดยเฉพาะ เริ่มจากรายการที่ต้องอาศัยการอ้างอิงน้อยที่สุด แล้วค่อยๆ ไล่ไปตามลําดับชั้นการอ้างอิง

  • เมื่อคุณเพิ่มไฟล์ 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 ได้