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

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 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 และแนวคิดของ Bazel โปรดกรอกข้อมูลใน บทแนะนำแอป iOS) คุณควรทำความเข้าใจ Bazel พื้นที่ทำงาน ซึ่งรวมถึงไฟล์ WORKSPACE และ BUILD รวมถึงไฟล์ แนวคิดของเป้าหมาย สร้างกฎ และแพ็กเกจ Bazel

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

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

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

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

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

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

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

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

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

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

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

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

  4. (ไม่บังคับ) อธิบายบิลด์อย่างละเอียด

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ณ จุดนี้ ขอแนะนำให้คุณทดสอบบิลด์:

bazel build //:<application_target>

ขั้นตอนที่ 4: (ไม่บังคับ) อธิบายสิ่งที่สร้างอย่างละเอียด

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

  • ส่วนเพิ่มที่เพิ่มขึ้นของบิลด์

  • เพิ่มการโหลดพร้อมกันสำหรับงานบิลด์

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

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

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

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

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

  • ฟังก์ชัน 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 เพื่อระบุเวอร์ชันที่ถูกต้อง ยอมรับใบอนุญาต และ ล้างสถานะของ Bazel

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