หน้านี้อธิบายวิธีสร้างหรือทดสอบโปรเจ็กต์ 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ด้วยตนเอง
ก่อนเริ่มต้น
ก่อนเริ่มต้น ให้ทำดังนี้
ติดตั้ง Bazel หากยังไม่ได้ติดตั้ง
หากคุณไม่คุ้นเคยกับ Bazel และแนวคิดของ Bazel ให้ทำตามบทแนะนำเกี่ยวกับแอป iOS) คุณควรทำความเข้าใจพื้นที่ทำงานของ Bazel ซึ่งรวมถึงไฟล์
WORKSPACEและBUILDตลอดจนแนวคิดของเป้าหมาย กฎการบิลด์ และแพ็กเกจ Bazelวิเคราะห์และทำความเข้าใจทรัพยากร Dependency ของโปรเจ็กต์
วิเคราะห์ทรัพยากร Dependency ของโปรเจ็กต์
Bazel กำหนดให้คุณต้องประกาศทรัพยากร Dependency ทั้งหมดสำหรับทุกเป้าหมายในไฟล์ BUILD อย่างชัดเจน ซึ่งแตกต่างจาก Xcode
ดูข้อมูลเพิ่มเติมเกี่ยวกับทรัพยากรภายนอกได้ที่ การทำงานกับทรัพยากรภายนอก
สร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel
หากต้องการสร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel ให้ทำดังนี้
ขั้นตอนที่ 1: สร้างไฟล์ WORKSPACE
สร้างไฟล์ WORKSPACE ในไดเรกทอรีใหม่ ไดเรกทอรีนี้จะกลายเป็นรูทของพื้นที่ทำงาน Bazel
หากโปรเจ็กต์ไม่ได้ใช้ทรัพยากรภายนอก ไฟล์นี้จะว่างเปล่าได้ หากโปรเจ็กต์ขึ้นอยู่กับไฟล์หรือแพ็กเกจที่ไม่ได้อยู่ในไดเรกทอรีของโปรเจ็กต์ ให้ระบุการอ้างอิงภายนอกเหล่านี้ในไฟล์ WORKSPACE
ขั้นตอนที่ 2: (ทดลอง) ผสานรวมทรัพยากร Dependency ของ CocoaPods
หากต้องการผสานรวมทรัพยากร Dependency ของ CocoaPods เข้ากับพื้นที่ทำงาน Bazel คุณต้องแปลง ทรัพยากรเหล่านั้นเป็นแพ็กเกจ Bazel ตามที่อธิบายไว้ในการแปลงทรัพยากร Dependency ของ CocoaPods
ขั้นตอนที่ 3: สร้างไฟล์ BUILD
เมื่อกำหนดพื้นที่ทำงานและการอ้างอิงภายนอกแล้ว คุณจะต้อง
สร้างไฟล์ BUILD ที่บอก Bazel ว่าโปรเจ็กต์มีโครงสร้างอย่างไร สร้างไฟล์ BUILD ที่รูทของพื้นที่ทำงาน Bazel แล้วกำหนดค่าให้สร้างโปรเจ็กต์ครั้งแรกดังนี้
- ขั้นตอนที่ 3ก: เพิ่มเป้าหมายแอปพลิเคชัน
- ขั้นตอนที่ 3b: (ไม่บังคับ) เพิ่มเป้าหมายการทดสอบ
- ขั้นตอนที่ 3ค: เพิ่มเป้าหมายไลบรารี
เคล็ดลับ: ดูข้อมูลเพิ่มเติมเกี่ยวกับแพ็กเกจและแนวคิดอื่นๆ ของ 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เพื่อเรียกใช้การทดสอบหน่วยที่อิงตามไลบรารีและที่อิงตามแอปพลิเคชันใน macOSios_unit_testเพื่อเรียกใช้การทดสอบ 1 หน่วยที่อิงตามไลบรารีใน iOS สำหรับการทดสอบที่ต้องใช้โปรแกรมจำลอง iOS Bazel จะสร้างเอาต์พุตการทดสอบแต่จะไม่เรียกใช้การทดสอบ คุณต้อง สร้างโปรเจ็กต์ Xcode ด้วย Tulsi และเรียกใช้การทดสอบจากภายใน Xcodeios_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/Developersudo xcodebuild -licensebazel sync --configure
- หากไม่ได้ผล คุณอาจลองเรียกใช้
bazel clean --expunge