หน้านี้จะอธิบายวิธีสร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel ซึ่งอธิบายความแตกต่างระหว่าง Xcode กับ Bazel และแสดงขั้นตอนในการแปลงโปรเจ็กต์ Xcode เป็นโปรเจ็กต์ Bazel รวมถึงให้วิธีแก้ปัญหาเพื่อแก้ไขข้อผิดพลาดที่พบบ่อย
ความแตกต่างระหว่าง Xcode กับ Bazel
Bazel กำหนดให้คุณระบุเป้าหมายการสร้างและทรัพยากร Dependency ทั้งหมดอย่างชัดเจน รวมถึงการตั้งค่าการสร้างที่เกี่ยวข้องผ่านกฎการสร้าง
Bazel กำหนดให้ไฟล์ทั้งหมดที่โครงการใช้ต้องอยู่ในไดเรกทอรี Workspace หรือระบุเป็นการนำเข้าในไฟล์
WORKSPACE
เมื่อสร้างโปรเจ็กต์ Xcode ด้วย Bazel ไฟล์
BUILD
จะเป็นแหล่งข้อมูล หากทํางานในโปรเจ็กต์ใน Xcode คุณต้องสร้างโปรเจ็กต์ Xcode เวอร์ชันใหม่ที่ตรงกับไฟล์BUILD
โดยใช้ Tulsi ทุกครั้งที่อัปเดตไฟล์BUILD
หากคุณไม่ได้ใช้ Xcode คำสั่งbazel build
และbazel test
จะมีความสามารถในการสร้างและทดสอบโดยมีข้อจำกัดบางอย่างตามที่อธิบายไว้ในส่วนถัดไปของคู่มือนี้เนื่องจากสคีมาการกำหนดค่าบิลด์แตกต่างกัน เช่น เลย์เอาต์ไดเรกทอรีหรือ Flag การสร้าง Xcode จึงอาจไม่เข้าใจ "ภาพรวม" ของการสร้างอย่างสมบูรณ์ และฟีเจอร์บางอย่างของ Xcode จึงอาจไม่ทำงาน ได้แก่
Xcode อาจจัดทำดัชนีแหล่งที่มาของโปรเจ็กต์อย่างไม่ถูกต้อง ทั้งนี้ขึ้นอยู่กับเป้าหมายที่คุณเลือกสำหรับการแปลงใน Tulsi ซึ่งส่งผลต่อฟีเจอร์เติมโค้ดอัตโนมัติและการไปยังส่วนต่างๆ ใน Xcode เนื่องจาก Xcode จะไม่เห็นซอร์สโค้ดทั้งหมดของโปรเจ็กต์
การวิเคราะห์แบบคงที่ ตัวตรวจสอบที่อยู่ และตัวตรวจสอบเธรดอาจไม่ทำงาน เนื่องจาก Bazel ไม่ได้สร้างเอาต์พุตที่ Xcode คาดหวังสำหรับฟีเจอร์เหล่านั้น
หากคุณสร้างโปรเจ็กต์ Xcode ด้วย Tulsi และใช้โปรเจ็กต์นั้นเพื่อเรียกใช้การทดสอบจากภายใน Xcode ทาง Xcode จะเรียกใช้การทดสอบแทน Bazel หากต้องการเรียกใช้การทดสอบด้วย Bazel ให้เรียกใช้คําสั่ง
bazel test
ด้วยตนเอง
ก่อนเริ่มต้น
โปรดทำตามขั้นตอนต่อไปนี้ก่อนเริ่มต้น
ติดตั้ง Bazel หากยังไม่ได้ทำ
หากคุณไม่คุ้นเคยกับ Bazel และแนวคิดต่างๆ โปรดดูบทแนะนำสำหรับแอป iOS คุณควรทำความเข้าใจเวิร์กสเปซ Bazel ซึ่งรวมถึงไฟล์
WORKSPACE
และBUILD
ตลอดจนแนวคิดเกี่ยวกับเป้าหมาย กฎการสร้าง และแพ็กเกจ Bazelวิเคราะห์และทำความเข้าใจทรัพยากร Dependency ของโปรเจ็กต์
วิเคราะห์ทรัพยากร Dependency ของโปรเจ็กต์
ซึ่งแตกต่างจาก Xcode เนื่องจาก Bazel กำหนดให้คุณประกาศการอ้างอิงทั้งหมดสำหรับเป้าหมายทุกรายการในไฟล์ BUILD
อย่างชัดเจน
ดูข้อมูลเพิ่มเติมเกี่ยวกับทรัพยากรภายนอกได้ที่หัวข้อการทํางานกับทรัพยากรภายนอก
บิลด์หรือทดสอบโปรเจ็กต์ 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ก: เพิ่มเป้าหมายแอปพลิเคชัน
- ขั้นตอนที่ 3ข: (ไม่บังคับ) เพิ่มเป้าหมายการทดสอบ
- ขั้นตอนที่ 3ค: เพิ่มเป้าหมายคลัง
เคล็ดลับ: ดูข้อมูลเพิ่มเติมเกี่ยวกับแพ็กเกจและแนวคิดอื่นๆ ของ Bazel ได้ที่หัวข้อเวิร์กช็อป แพ็กเกจ และเป้าหมาย
ขั้นตอนที่ 3ก: เพิ่มเป้าหมายแอปพลิเคชัน
เพิ่มเป้าหมายกฎ macos_application
หรือ ios_application
เป้าหมายนี้จะสร้าง App Bundle ของ macOS หรือ iOS ตามลำดับ
ในเป้าหมาย ให้ระบุข้อมูลต่อไปนี้เป็นอย่างน้อย
bundle_id
- รหัสกลุ่ม (เส้นทาง DNS แบบย้อนกลับตามด้วยชื่อแอป) ของไฟล์ไบนารีprovisioning_profile
- โปรไฟล์การกําหนดค่าจากบัญชีนักพัฒนาแอป Apple (หากสร้างสําหรับอุปกรณ์ iOS)families
(iOS เท่านั้น) - เลือกว่าจะสร้างแอปพลิเคชันสำหรับ iPhone, iPad หรือทั้ง 2 อย่างinfoplists
- รายการไฟล์ .plist ที่จะผสานลงในไฟล์ Info.plist สุดท้ายminimum_os_version
- เวอร์ชัน macOS หรือ iOS ขั้นต่ำที่แอปพลิเคชันรองรับ วิธีนี้ช่วยให้มั่นใจว่า Bazel จะสร้างแอปพลิเคชันด้วยระดับ API ที่ถูกต้อง
ขั้นตอนที่ 3ข: (ไม่บังคับ) เพิ่มเป้าหมายการทดสอบ
กฎการสร้างของ Apple ของ Bazel รองรับการเรียกใช้การทดสอบยูนิตที่อิงตามไลบรารีใน iOS และ macOS รวมถึงการทดสอบที่อิงตามแอปพลิเคชันใน macOS สําหรับการทดสอบที่อิงตามแอปพลิเคชันใน iOS หรือการทดสอบ UI บนแพลตฟอร์มใดแพลตฟอร์มหนึ่ง Bazel จะสร้างเอาต์พุตการทดสอบ แต่การทดสอบต้องทํางานภายใน Xcode ผ่านโปรเจ็กต์ที่สร้างด้วย Tulsi เพิ่มเป้าหมายการทดสอบดังนี้
macos_unit_test
เพื่อเรียกใช้การทดสอบ 1 หน่วยที่อิงตามไลบรารีและที่อิงตามแอปพลิเคชันใน 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 แต่ละรายการที่แอปพลิเคชันและ/หรือการทดสอบใช้
เพิ่มเป้าหมายของไลบรารีดังนี้
เพิ่มเป้าหมายของไลบรารีแอปพลิเคชันเป็นข้อกำหนดของเป้าหมายแอปพลิเคชัน
เพิ่มเป้าหมายของไลบรารีทดสอบเป็นข้อกําหนดของเป้าหมายการทดสอบ
แสดงแหล่งที่มาของการติดตั้งใช้งานในแอตทริบิวต์
srcs
แสดงรายการส่วนหัวในแอตทริบิวต์
hdrs
ดูข้อมูลเพิ่มเติมเกี่ยวกับกฎการสร้างได้ที่กฎของ 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 ด้วย 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
ด้วย