Bitcode là một biểu diễn trung gian của chương trình ở giai đoạn biên dịch của một ứng dụng iOS. Không giống như mã máy, Bitcode không bị ràng buộc vào một kiến trúc bộ xử lý cụ thể. Theo Apple Developer Documentation, App Store có thể biên dịch lại Bitcode cho kiến trúc mục tiêu, cải thiện hiệu suất và giảm kích thước tệp cài đặt. Nhà phát triển gửi Bitcode lên App Store, và chính cửa hàng sẽ tạo tệp nhị phân được tối ưu hóa cho từng loại thiết bị.
Các Điểm Chính
Bitcode là một biểu diễn trung gian của chương trình (Intermediate Representation, IR) được tạo ra bởi cơ sở hạ tầng trình biên dịch LLVM. Apple đã giới thiệu hỗ trợ Bitcode từ Xcode 7 và iOS 9 như một yêu cầu bắt buộc đối với ứng dụng watchOS và tùy chọn cho iOS và tvOS. Từ Xcode 14, yêu cầu này đã được loại bỏ cho tất cả các nền tảng ngoại trừ watchOS.
Khái niệm biểu diễn mã trung gian đã tồn tại từ những năm 2000 như một phần của dự án LLVM, do Chris Lattner thành lập tại Đại học Illinois. Apple đã thích ứng LLVM cho Xcode vào năm 2011, và năm 2015 đã giới thiệu Bitcode như một cách để cập nhật ứng dụng mà không cần gửi lại lên App Store. Công nghệ này đã được công bố tại WWDC 2015 trong phiên “What's New in Xcode”.
Mã máy bao gồm các lệnh nhị phân cho một bộ xử lý cụ thể: arm64, armv7 hoặc x86_64. Bitcode được lưu trữ ở định dạng độc lập với phần cứng, cho phép App Store tạo các tệp nhị phân được tối ưu hóa cho các kiến trúc khác nhau từ một biểu diễn nguồn duy nhất. Sự khác biệt chính này xác định tất cả các lợi thế của công nghệ.
| Đặc tính | Bitcode | Mã máy |
|---|---|---|
| Phụ thuộc kiến trúc | Độc lập | Phụ thuộc CPU |
| Kích thước tệp nhị phân | Nhỏ gọn | Lớn hơn |
| Khả năng biên dịch lại | Có | Không |
| Hỗ trợ App Store | Được biên dịch lại | Được sử dụng nguyên trạng |
| Gỡ lỗi | Hạn chế | Hỗ trợ đầy đủ |
Bitcode không phải là một tệp thực thi. Nó là LLVM IR ở định dạng nhị phân mà nhà phát triển gửi đến App Store cùng với siêu dữ liệu dự án. Cửa hàng ứng dụng chạy quá trình biên dịch lại, điều chỉnh mã cho từng nền tảng mục tiêu và phiên bản hệ điều hành.
Quá trình tạo Bitcode bắt đầu với giao diện trước của trình biên dịch, nơi chuyển đổi mã nguồn Swift hoặc Objective-C thành LLVM IR. Ở giai đoạn liên kết, Xcode đóng gói IR vào các tệp định dạng .bc (Bitcode), sau đó được gửi đến App Store cùng với tệp .xcarchive. App Store, đến lượt mình, chạy quá trình biên dịch lại ở phía mình.
Cơ sở hạ tầng LLVM bao gồm ba phần: giao diện trước (Clang cho C/ObjC, Swift Frontend cho Swift), trình tối ưu Middle-End và giao diện sau (trình tạo mã máy). Bitcode là kết quả của hai giai đoạn đầu tiên mà không chuyển sang tạo lệnh hợp ngữ. Middle-End thực hiện các tối ưu hóa độc lập nền tảng: loại bỏ mã chết, nội tuyến và gấp hằng số.
// Ví dụ mã nguồn Swift
func calculateSum(a: Int, b: Int) -> Int {
return a + b
}
// LLVM IR sau khi biên dịch (đơn giản hóa)
; define i32 @calculateSum(i32 %a, i32 %b)
; %result = add i32 %a, %b
; ret i32 %result
Sau khi tạo IR, trình biên dịch thực hiện một loạt các tối ưu hóa ở cấp độ biểu diễn: loại bỏ mã chết, nội tuyến hàm và gấp hằng số. Các tối ưu hóa này không phụ thuộc vào kiến trúc và được giữ lại trong Bitcode. Trong quá trình biên dịch lại trong App Store, các tối ưu hóa phụ thuộc kiến trúc được thêm vào, như sắp xếp lại lệnh cho một bộ xử lý cụ thể.
App Store Connect nhận được tệp lưu trữ với Bitcode và chạy cơ sở hạ tầng biên dịch riêng của nó. Hệ thống xác định kiến trúc mục tiêu của thiết bị người dùng và tạo mã máy, tối ưu hóa thêm cho các đặc tính cụ thể của bộ xử lý. Đối với arm64e (bộ xử lý A12+ và dòng M), các tối ưu hóa bảo mật bổ sung được áp dụng.
Quá trình này được gọi là App Thinning — một công nghệ chỉ gửi đến thiết bị những tài nguyên và mã cần thiết cho kiến trúc của nó. Người dùng iPhone với bộ xử lý A17 Pro nhận được tệp nhị phân được tối ưu hóa cho arm64e, không có các lệnh không cần thiết cho các kiến trúc cũ hơn. Điều này giảm thời gian tải xuống và tiết kiệm dung lượng trên thiết bị.
Bitcode mang lại một số lợi ích chính cho các nhà phát triển ứng dụng iOS. Lợi ích chính là tối ưu hóa tự động cho các bộ xử lý Apple mới mà không cần gửi lại bản cập nhật lên App Store. Điều này đặc biệt phù hợp khi chuyển đổi sang các kiến trúc mới, như chuyển từ armv7 sang arm64.
Khi Apple phát hành bộ xử lý với kiến trúc mới, các ứng dụng được gửi với Bitcode sẽ tự động được biên dịch lại cho nó. Nhà phát triển không cần xây dựng lại dự án và xuất bản bản cập nhật — App Store thực hiện điều này ở phía mình khi người dùng tải xuống lần đầu tiên. Điều này đặc biệt quan trọng đối với các ứng dụng lâu dài được duy trì trong nhiều năm.
App Thinning kết hợp với Bitcode có thể giảm kích thước ứng dụng đã cài đặt từ 15 đến 40%. App Store chỉ tạo các lệnh máy cần thiết cho một thiết bị cụ thể, loại bỏ mã cho các kiến trúc khác và các biến thể cho các phiên bản iOS khác nhau. Trong thực tế, điều này có nghĩa là người dùng iPhone mới nhận được tệp nhị phân nhỏ gọn.
Theo Apple WWDC 2015 Session 102, việc sử dụng Bitcode và App Thinning có thể giảm kích thước ứng dụng được tải xuống trung bình 25% so với tệp nhị phân phổ quát chứa tất cả các kiến trúc. Đối với ứng dụng 100 MB, mức tiết kiệm có thể lên tới 40 MB trên thiết bị của người dùng.
Cấu hình Bitcode được thực hiện trong cài đặt xây dựng Xcode. Tham số Enable Bitcode nằm trong Build Settings và được bật theo mặc định cho các dự án mới, nhưng nhà phát triển có thể tắt nó để gỡ lỗi hoặc khi sử dụng thư viện bên thứ ba không hỗ trợ Bitcode.
// Build Settings -> Apple Clang - Code Generation
// Enable Bitcode = YES
// Hoặc qua Info.plist cho các target riêng lẻ
@property (nonatomic, assign) BOOL enableBitcode;
- (void)configureBuildSettings {
// Kiểm tra trạng thái Bitcode trong cấu hình
if (self.enableBitcode) {
NSLog(@"Bitcode is enabled for this target");
} else {
NSLog(@"Bitcode is disabled");
}
}
Để kiểm tra xem tệp lưu trữ có chứa Bitcode hay không, hãy mở tệp .xcarchive qua Xcode Organizer hoặc chạy lệnh otool -l trong Terminal. Sự hiện diện của phần __LLVM trong tệp nhị phân xác nhận rằng Bitcode đã được kích hoạt và đóng gói chính xác. Nếu phần này bị thiếu, Bitcode đã không được tạo ra trong quá trình xây dựng.
# Kiểm tra sự hiện diện của Bitcode trong tệp lưu trữ
otool -l YourApp.app/YourApp | grep __LLVM
# Đầu ra: nếu có phần __LLVM — Bitcode tồn tại
# Nếu đầu ra trống — Bitcode không được kích hoạt hoặc không được tạo
# Bạn cũng có thể kiểm tra bằng lệnh size
size -m -l YourApp.app/YourApp | grep __LLVM
Khi sử dụng thư viện bên thứ ba qua CocoaPods hoặc SPM, hãy đảm bảo tất cả các phụ thuộc đều được xây dựng với Bitcode. Nếu chỉ một thư viện không hỗ trợ Bitcode, Xcode sẽ tạo lỗi liên kết trong quá trình lưu trữ. Đối với CocoaPods, hãy kiểm tra cờ bitcode_enabled trong subspecs hoặc sử dụng use_frameworks! với enable_bitcode.
Bitcode không phải là giải pháp phổ biến cho tất cả các loại dự án iOS. Công nghệ này có những giới hạn mà nhà phát triển cần xem xét trước khi kích hoạt tùy chọn trong cấu hình xây dựng. Hiểu những giới hạn này giúp tránh các sự cố trong quá trình lưu trữ và xuất bản.
Không phải tất cả các thư viện bên thứ ba đều được cung cấp với hỗ trợ Bitcode. Nếu một thư viện chỉ được phân phối dưới dạng tệp nhị phân đã biên dịch mà không có Bitcode, dự án với tùy chọn được kích hoạt sẽ không xây dựng được. Trong trường hợp này, nhà phát triển sẽ phải tắt Bitcode hoặc yêu cầu nhà cung cấp phiên bản có hỗ trợ Bitcode. Điều này đặc biệt phù hợp với các thư viện cũ không còn được cập nhật.
Báo cáo sự cố từ các ứng dụng được xây dựng với Bitcode yêu cầu xử lý bổ sung. Các ký hiệu (dSYM) cho mã được biên dịch lại được tạo bởi App Store và có sẵn để tải xuống qua Xcode Organizer. Nếu không tải các tệp dSYM tương ứng, ngăn xếp cuộc gọi trong các báo cáo sự cố sẽ không thể đọc được, gây khó khăn cho việc chẩn đoán sự cố.
Từ iOS 17 và Xcode 15, Apple không yêu cầu bật Bitcode bắt buộc để xuất bản trên App Store. Tuy nhiên, đối với các ứng dụng watchOS, Bitcode vẫn là yêu cầu bắt buộc ở cấp chính sách App Store Connect. Các nhà phát triển được khuyên nên bật Bitcode cho các dự án mới nếu tất cả các phụ thuộc hỗ trợ nó.
Câu hỏi thường gặp
Đối với ứng dụng iOS và tvOS, Bitcode không bắt buộc kể từ Xcode 14. Đối với watchOS, hỗ trợ Bitcode vẫn là bắt buộc. Apple khuyên bật Bitcode cho các dự án mới nhưng không chặn xuất bản nếu không có nó.
Bitcode cho phép App Store áp dụng App Thinning — tạo mã máy chỉ cho kiến trúc thiết bị của người dùng. Điều này giảm kích thước tệp nhị phân được tải xuống từ 15–40% tùy thuộc vào số lượng kiến trúc được hỗ trợ trong dự án.
Có, tệp dSYM là cần thiết để tạo ký hiệu cho các báo cáo sự cố từ các tệp nhị phân được biên dịch lại. App Store cung cấp khả năng tải dSYM qua Xcode Organizer sau khi xử lý tệp lưu trữ. Nếu không có chúng, ngăn xếp cuộc gọi trong Crashlytics và bảng điều khiển sẽ chỉ chứa các địa chỉ bộ nhớ.
SPM hỗ trợ Bitcode nếu các phụ thuộc được phân phối dưới dạng mã nguồn thay vì tệp nhị phân. Các phụ thuộc nhị phân qua SPM phải cung cấp phiên bản có Bitcode, nếu không dự án với tùy chọn được kích hoạt sẽ không biên dịch được.
Bitcode là biểu diễn LLVM IR trung gian, độc lập với phần cứng và không thể được thực thi trực tiếp bởi bộ xử lý. Mã máy chứa các lệnh có sẵn cho một kiến trúc cụ thể (arm64, x86_64) và được thực thi mà không cần biên dịch thêm.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm