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

รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ขั้นตอนที่ 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 ไฟล์ MODULE.bazel และ BUILD จะกลายเป็นต้นฉบับ เกี่ยวกับงานสร้างนี้ หากต้องการให้ Xcode ทราบถึงเรื่องนี้ คุณต้องสร้าง โปรเจ็กต์ Xcode ที่เข้ากันได้กับ Bazel โดยใช้ rules_xcodeproj ที่ใช้เวลาเพียง 2 นาที

การแก้ปัญหา

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