TL; DR;
ตั้งค่า "Build Active Architecture Only ( ONLY_ACTIVE_ARCH
)" เป็นYesสำหรับไลบรารี / แอปของคุณแม้กระทั่งในโหมดเผยแพร่
ในขณะที่พยายามระบุสาเหตุที่แท้จริงของปัญหาฉันได้ตระหนักถึงข้อเท็จจริงที่น่าสนใจเกี่ยวกับ Xcode 12
Xcode 12 เป็นก้าวสำคัญของ Apple Silicon ซึ่งน่าเสียดายที่ยังไม่มีวางจำหน่าย แต่ด้วยแพลตฟอร์มนั้นเราจะได้รับ macOS ที่ใช้ arm64 ซึ่งเครื่องจำลองจะทำงานบนสถาปัตยกรรม arm64 ซึ่งแตกต่างจากสถาปัตยกรรม x86_64 ที่ใช้ Intel ในปัจจุบัน
Xcode มักจะขึ้นอยู่กับ "Run Destination" เพื่อสร้างไลบรารี / แอป ดังนั้นเมื่อเครื่องจำลองถูกเลือกเป็น "Run Destination" ระบบจะสร้างแอปสำหรับสถาปัตยกรรมจำลองที่พร้อมใช้งานและเมื่ออุปกรณ์ได้รับเลือกให้เป็น "Run Destination" ระบบจะสร้างสำหรับสถาปัตยกรรมที่อุปกรณ์รองรับ ( arm*
)
xcodebuild
ในระบบสร้าง Xcode 12+ ถือว่าarm64
เป็นสถาปัตยกรรมที่ถูกต้องสำหรับโปรแกรมจำลอง ดังนั้นเมื่อเครื่องจำลองถูกเลือกให้เป็นปลายทางการทำงานก็อาจพยายามรวบรวม / เชื่อมโยง libs / แอปของคุณกับarm64
เครื่องจำลองที่ใช้งานได้เช่นกัน (ยังไม่พร้อมใช้งาน) ดังนั้นมันจึงส่งclang(++)
แฟล็ก - เป้าหมายบางอย่างเช่นarm64-apple-ios13.0-simulator
ในรูปแบบ <architecture> - <os> - <sdk> - <platform> และเสียงดังกราวพยายามสร้าง / เชื่อมโยงกับตัวจำลองที่ใช้ arm64 ซึ่งในที่สุดก็ล้มเหลวบน mac ที่ใช้ Intel
แต่xcodebuild
จะลองใช้กับรุ่นที่วางจำหน่ายเท่านั้น ทำไม? เนื่องจากONLY_ACTIVE_ARCH
โดยปกติแล้วการตั้งค่าบิวด์ "Build Active Architecture Only ( )" จะตั้งค่าเป็น "ไม่ใช่" สำหรับการกำหนดค่า "Release" เท่านั้น และนั่นหมายความว่าxcodebuild
จะพยายามสร้างรูปแบบสถาปัตยกรรมทั้งหมดของ libs / แอพของคุณสำหรับปลายทางการเรียกใช้ที่เลือกสำหรับรุ่นรุ่น และสำหรับปลายทางการทำงานของ Simulator นั้นจะรวมทั้งสองอย่างx86_64
และarm64
ตอนนี้เนื่องจากarm64
ใน Xcode 12+ ยังเป็นสถาปัตยกรรมที่รองรับสำหรับเครื่องจำลองเพื่อรองรับ Apple Silicon
เพียงแค่วาง Xcode จะล้มเหลวในการสร้างแอปของคุณได้ตลอดเวลาก็พยายามที่บรรทัดคำสั่งxcodebuild
(ซึ่งเป็นค่าเริ่มต้นที่จะปล่อยสร้างให้ดูที่แท็บทั่วไปของการตั้งค่าโครงการของคุณ) หรืออื่น ๆ และพยายามที่จะสร้างสายพันธุ์สถาปัตยกรรมการสนับสนุนโดยปลายทางวิ่ง วิธีแก้ปัญหาง่ายๆสำหรับปัญหานี้คือการตั้งค่า "Build Active Architecture Only ( ONLY_ACTIVE_ARCH
)" เป็นใช่ในไลบรารี / แอปของคุณแม้กระทั่งในโหมดเผยแพร่
หากรวมไลบรารีเป็นพ็อดและคุณสามารถเข้าถึงได้.podspec
คุณสามารถตั้งค่า:
spec.pod_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'ใช่'}
spec.user_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'} # ไม่แนะนำ
โดยส่วนตัวแล้วฉันไม่ชอบบรรทัดที่สองเนื่องจากพ็อดไม่ควรก่อให้เกิดมลพิษต่อโครงการเป้าหมายและอาจถูกแทนที่ในการตั้งค่าเป้าหมายเอง ดังนั้นจึงควรเป็นความรับผิดชอบของโครงการผู้บริโภคที่จะลบล้างการตั้งค่าด้วยวิธีการบางอย่าง อย่างไรก็ตามสิ่งนี้อาจจำเป็นสำหรับการขุยพอดสเปคที่ประสบความสำเร็จ
อย่างไรก็ตามหากคุณไม่สามารถเข้าถึงได้.podspec
คุณสามารถอัปเดตการตั้งค่าระหว่างการติดตั้งพ็อดได้ตลอดเวลา:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings["ONLY_ACTIVE_ARCH"] = "YES"
end
end
end
สิ่งหนึ่งที่ฉันกังวลเกี่ยวกับผลกระทบของสิ่งนี้เมื่อเราเก็บ libs / apps จริงๆ ในระหว่างการเก็บแอปโดยปกติจะใช้การกำหนดค่า "Release" และเนื่องจากนี่จะเป็นการสร้างรุ่นโดยพิจารณาเฉพาะสถาปัตยกรรมที่ใช้งานอยู่ของปลายทางการรันปัจจุบันด้วยวิธีนี้เราอาจสูญเสียชิ้นส่วนสำหรับ armv7, armv7s ฯลฯ จากการสร้างเป้าหมาย อย่างไรก็ตามฉันสังเกตเห็นเอกสารระบุว่า (ไฮไลต์ในรูปภาพที่แนบมา) ว่าการตั้งค่านี้จะถูกละเว้นเมื่อเราเลือก "อุปกรณ์ iOS ทั่วไป / อุปกรณ์ใด ๆ " เป็นปลายทางการรันเนื่องจากไม่ได้กำหนดสถาปัตยกรรมเฉพาะใด ๆ ดังนั้นฉันเดาว่าเราน่าจะดีถ้าเราเก็บแอพของเราโดยเลือกว่าเป็นปลายทางการรัน