หน้านี้จะอธิบายวิธีสร้างหรือทดสอบโปรเจ็กต์ 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
มอบความสามารถในการสร้างและทดสอบ โดยมีข้อจำกัดบางประการที่อธิบายไว้ภายหลังในคู่มือนี้
ก่อนเริ่มต้น
ก่อนที่จะเริ่มต้น ให้ทำดังนี้
ติดตั้ง Bazel หากยังไม่ได้ติดตั้ง
หากคุณยังไม่คุ้นเคยกับ Bazel และแนวคิดของ Bazel โปรดกรอกข้อมูลใน บทแนะนำแอป iOS คุณควรทำความเข้าใจ Bazel พื้นที่ทำงาน ซึ่งรวมถึงไฟล์
WORKSPACE
และBUILD
รวมถึงไฟล์ แนวคิดของเป้าหมาย สร้างกฎ และแพ็กเกจ Bazelวิเคราะห์และทำความเข้าใจทรัพยากร Dependency ของโปรเจ็กต์
วิเคราะห์ทรัพยากร Dependency ของโปรเจ็กต์
Bazel กำหนดให้คุณประกาศ Dependency ทั้งหมดอย่างชัดเจน ซึ่งต่างจาก Xcode
ทุกเป้าหมายในไฟล์ BUILD
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับทรัพยากร Dependency ภายนอก โปรดดู การทํางานกับทรัพยากร Dependency ภายนอก
สร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel
ในการสร้างหรือทดสอบโปรเจ็กต์ Xcode ด้วย Bazel ให้ทำดังนี้
ขั้นตอนที่ 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 และกำหนดค่าให้
บิลด์เริ่มต้นของโปรเจ็กต์ ดังนี้
- ขั้นตอนที่ 3ก: เพิ่มเป้าหมายแอปพลิเคชัน
- ขั้นตอนที่ 3ข: (ไม่บังคับ) เพิ่มเป้าหมายทดสอบ
- ขั้นตอนที่ 3ค: เพิ่มเป้าหมายไลบรารี
เคล็ดลับ: ดูข้อมูลเพิ่มเติมเกี่ยวกับแพ็กเกจและแนวคิดอื่นๆ ของ 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 การเรียกใช้การทดสอบหน่วยตามไลบรารีบน iOS และ macOS รวมถึงการทดสอบตามแอปพลิเคชัน ใน macOS สำหรับการทดสอบตามแอปพลิเคชันในการทดสอบ iOS หรือ UI ใน Bazel จะสร้างเอาต์พุตทดสอบ แต่การทดสอบต้องทำงานภายใน Xcode ผ่านโปรเจ็กต์ที่สร้างด้วย rules_xcodeproj เพิ่มเป้าหมายทดสอบดังนี้
macos_unit_test
เพื่อเรียกใช้การทดสอบหน่วยตามไลบรารีและตามแอปพลิเคชันใน macOSios_unit_test
เพื่อเรียกใช้การทดสอบ 1 หน่วยที่อิงตามไลบรารีใน iOS สำหรับการทดสอบที่ต้องใช้ iOS เครื่องมือจำลอง Bazel จะสร้างเอาต์พุตทดสอบแต่ไม่เรียกใช้การทดสอบ คุณต้อง สร้างโปรเจ็กต์ Xcode ด้วย rules_xcodeproj และทำการทดสอบจากภายใน Xcodeios_ui_test
เพื่อสร้างเอาต์พุตที่จำเป็นสำหรับการเรียกใช้การทดสอบอินเทอร์เฟซผู้ใช้ในเครื่องจำลอง iOS โดยใช้ Xcode คุณต้องสร้างโปรเจ็กต์ Xcode ที่มี rules_xcodeproj และทำการทดสอบจากภายใน 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
คุณสามารถเรียกดูตัวอย่างที่มีอยู่สำหรับแอปพลิเคชันประเภทต่างๆ ได้โดยตรงใน ไดเรกทอรีตัวอย่างกฎ [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
ได้