หน้านี้จะอธิบายวิธีสร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel ซึ่งอธิบายความแตกต่างระหว่าง Xcode กับ Bazel และแสดงขั้นตอนในการแปลงโปรเจ็กต์ Xcode เป็นโปรเจ็กต์ Bazel รวมถึงให้วิธีแก้ปัญหาข้อผิดพลาดที่พบบ่อย
ความแตกต่างระหว่าง Xcode กับ Bazel
Bazel กำหนดให้คุณระบุเป้าหมายบิลด์และการขึ้นต่อกันทั้งหมดอย่างชัดแจ้ง รวมถึงการตั้งค่าบิลด์ที่เกี่ยวข้องผ่านกฎบิลด์
Bazel กำหนดให้ไฟล์ทั้งหมดที่โครงการใช้ต้องอยู่ในไดเรกทอรี Workspace หรือระบุเป็นการนำเข้าในไฟล์
WORKSPACE
เมื่อสร้างโปรเจ็กต์ Xcode ด้วย Bazel ไฟล์
BUILD
จะเป็นแหล่งข้อมูล หากทํางานในโปรเจ็กต์ใน Xcode คุณต้องสร้างโปรเจ็กต์ Xcode เวอร์ชันใหม่ที่ตรงกับไฟล์BUILD
โดยใช้ Tulsi ทุกครั้งที่อัปเดตไฟล์BUILD
หากคุณไม่ได้ใช้ Xcode คำสั่งbazel build
และbazel test
จะมีความสามารถในการสร้างและทดสอบโดยมีข้อจำกัดบางอย่างตามที่อธิบายไว้ในส่วนถัดไปของคู่มือนี้เนื่องจากสคีมาการกำหนดค่าบิลด์แตกต่างกัน เช่น เลย์เอาต์ไดเรกทอรีหรือ Flag การสร้าง Xcode จึงอาจไม่เข้าใจ "ภาพรวม" ของการสร้างอย่างสมบูรณ์ และฟีเจอร์บางอย่างของ Xcode จึงอาจไม่ทำงาน ได้แก่
Xcode อาจจัดทําดัชนีแหล่งที่มาของโปรเจ็กต์อย่างไม่ถูกต้อง ทั้งนี้ขึ้นอยู่กับเป้าหมายที่คุณเลือกสําหรับ Conversion ใน 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 หากโปรเจ็กต์ไม่มีทรัพยากร Dependency ภายนอก ไฟล์นี้ก็จะว่างเปล่าได้ หากโปรเจ็กต์ขึ้นอยู่กับไฟล์หรือแพ็กเกจที่ไม่ได้อยู่ในไดเรกทอรีของโปรเจ็กต์ ให้ระบุทรัพยากร Dependency ภายนอกเหล่านี้ในไฟล์ 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
เป้าหมายนี้จะสร้างกลุ่มแอปพลิเคชัน 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
ด้วย