Farklı Android cihazlar farklı CPU'lar kullanır, bu da farklı CPU'ları destekler talimat setlerinden yararlanın. Her CPU ve talimat grubu kombinasyonunun kendine ait Uygulama İkili Arabirimi (ABI). ABI aşağıdaki bilgileri içerir:
- Kullanılabilen CPU talimat grubu (ve uzantıları).
- Çalışma zamanında depolanan bellek ve yüklemelerin sabitliği. Android her zaman küçük Endian.
- Uygulamalar ile sistem arasında veri aktarımına yönelik kurallar ve ve sistemin, yığın ve yapılandırma kullandığı işlevi çağırdığında kaydedilir.
- Programlar ve paylaşılan kitaplıklar gibi yürütülebilir ikili programların biçimi, içerik türlerini açıkladık. Android her zaman ELF'yi kullanır. Daha fazla bkz. ELF System V Uygulama İkili Arabirimi.
- C++ adlarının nasıl karıştırıldığı. Daha fazla bilgi için bkz. Genel/Itanyum C++ ABI.
Bu sayfa, NDK'nın desteklediği ABI'leri sıralar ve bilgi sağlar her bir ABI'nın işleyiş şekli hakkında.
ABI, platform tarafından desteklenen yerel API'ye de başvurabilir. Örneğin, 32 bit sistemleri etkileyen bu ABI sorunlarının listesini görmek için 32 bit ABI hataları.
Desteklenen ABI'ler
Tablo 1. ABI'ler ve desteklenen talimat grupları.
ABI | Desteklenen Talimat Setleri | Notlar |
---|---|---|
armeabi-v7a |
|
ARMv5/v6 cihazlarla uyumlu değildir. |
arm64-v8a |
Yalnızca Armv8.0. | |
x86 |
MOVBE veya SSE4 desteklenmemektedir. | |
x86_64 |
|
Tam x86-64-v1, ancak yalnızca kısmi x86-64-v2 (CMPXCHG16B veya LAHF-SAHF yok). |
Not: NDK tarafından desteklenen ARMv5 geçmişte (armeabi) ve 32 bit ve 64 bit MIPS'ye sahiptir, ancak bu ABI'ler için sağlanan destek NDK r17.
ermeabi-v7a
Bu ABI, 32 bit ARM CPU'lar içindir. Thumb-2 ve Neon dahildir.
ABI'nın Android'e özgü olmayan bölümleri hakkında bilgi için bkz. ARM Mimarisi için Uygulama İkili Arabirimi (ABI)
NDK'nın derleme sistemleri
Android.mk
içindeki LOCAL_ARM_MODE
CMake'i yapılandırırken ndk-build veya ANDROID_ARM_MODE
adresine gidin.
Neon geçmişi hakkında daha fazla bilgi için Neon Desteği bölümüne bakın.
Bu ABI, geçmişe dönük nedenlerle, tüm float
nedenlerinden dolayı -mfloat-abi=softfp
tam sayı kayıtlarında iletilecek değerler ve tüm double
değerleri iletilecek
tamsayı kayıt çiftleri kullanarak fonksiyon çağrıları yaparken dikkate alınmaz. Adının aksine,
yalnızca kayan nokta çağrı kuralını etkiler: derleyici yine de
aritmetik için donanım kayan nokta talimatlarını kullanın.
Bu ABI, 64 bit bir long double
kullanır (IEEE ikili programı64 ve double
ile aynıdır).
kol64-v8a
Bu ABI, 64 bit ARM CPU'lar içindir.
Bkz. Arm's Mimariyi Öğrenme sayfasına göz atın. Kol bazı taşıma tavsiyeleri de sunar. 64 bit Android Geliştirme.
Neon yerleşik özelliklerini kullanabilirsiniz? C ve C++ koduna ekleyebilirsiniz. İlgili içeriği oluşturmak için kullanılan Armv8-A için Neon Programcı Kılavuzu dahili Neon programlama ve Neon programlama hakkında daha fazla bilgi sağlar.
Android'de platforma özel x18 kaydı,
ShadowCallStack
ve kodunuzdan dokunulmamalıdır. Clang'in mevcut sürümleri varsayılan olarak
Android'de -ffixed-x18
seçeneğini kullanabilirsiniz. Dolayısıyla, el yazısıyla
(veya çok eski bir derleyici) bu konuda endişelenmeniz gerekmez.
Bu ABI, 128 bit bir long double
(IEEE ikili 128) kullanır.
x86
Bu ABI, yaygın olarak "x86" olarak bilinen talimat setini destekleyen CPU'lar ve "i386" veya "IA-32".
Android'in ABI'si, temel talimat setini ve MMX SSE, SSE2, SSE3 ve SSSE3 uzantıları hakkında daha fazla bilgi edinin.
ABI, başka isteğe bağlı IA-32 talimat seti içermez MOVBE veya SSE4'ün herhangi bir varyantı gibi uzantılar bulunmalıdır. Bu uzantıları kullanmaya devam etmek için çalışma zamanı özellik incelemesini ve desteklemeyen cihazlar için yedekler sağlar.
NDK araç zincirinde, işlev çağrısından önce 16 baytlık yığın hizalaması varsayılır. Varsayılan araçlar ve bu kuralı zorunlu kılar. Derleme kodu yazıyorsanız yığında diğer derleyicilerin de bu kurala uyduğundan emin olun.
Daha fazla bilgi için aşağıdaki belgelere bakın:
- Arama farklı C++ derleyicileri ve işletim sistemleri için kurallar
- Intel IA-32 Intel Mimari Yazılım Geliştirici Kılavuzu, 2. Cilt: Talimat grubu referansı
- Intel IA-32 Intel Mimari Yazılım Geliştirici Kılavuzu, 3. Cilt: Sistem Yayın Planı Hazırlama Kılavuzu
- Sistem V Uygulama İkili Programı Arayüz: Intel386 İşlemci Mimarisi Eki
Bu ABI, 64 bit bir long double
kullanır (IEEE ikili programı64 double
ile aynıdır ve daha fazlası değil
genel 80 bit yalnızca Intel long double
).
x86_64
Bu ABI, yaygın olarak adı verilen talimat grubunu destekleyen CPU'lar içindir. "x86-64".
Android'in ABI'si, temel talimat setini ve MMX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 ve POPCNT talimatı.
ABI, başka isteğe bağlı x86-64 talimat seti içermez MOVBE, SHA veya AVX'in herhangi bir varyantı gibi uzantılar. Bu uzantıları kullanmaya devam etmek için çalışma zamanı özelliğini ve desteklemeyen cihazlar için yedekler sağlar.
Daha fazla bilgi için aşağıdaki belgelere bakın:
- Şunun için arama kuralları: farklı C++ derleyicileri ve işletim sistemleri
- Intel64 ve IA-32 Mimarileri Yazılım Geliştirici Kılavuzu, 2. Cilt: Talimat Seti Referans
- Intel64 ve IA-32 Intel Mimari Yazılım Geliştiricisi Kılavuzu 3: Sistem Programlama
Bu ABI, 128 bit bir long double
(IEEE ikili 128) kullanır.
Belirli bir ABI için kod oluşturun
Gradle
Gradle derlemeleri (ister Android Studio aracılığıyla ister komut satırından olsun)
varsayılan olarak, desteği sonlandırılmamış tüm ABI'lerdir. Ayarladığınız ABI grubunu kısıtlamak için:
için abiFilters
kullanın. Örneğin,
64 bit ABI'ler varsa build.gradle
cihazınızda aşağıdaki yapılandırmayı ayarlayın:
android {
defaultConfig {
ndk {
abiFilters 'arm64-v8a', 'x86_64'
}
}
}
ndk-kurum
ndk-build derlemeleri için varsayılan olarak kullanımdan kaldırılmamış tüm ABI'ler kullanılır. Bir
Application.mk dosyanızda APP_ABI
ayarlayarak belirli ABI'leri oluşturun. İlgili içeriği oluşturmak için kullanılan
aşağıdaki snippet'te APP_ABI
kullanımıyla ilgili birkaç örnek gösterilmektedir:
APP_ABI := arm64-v8a # Target only arm64-v8a
APP_ABI := all # Target all ABIs, including those that are deprecated.
APP_ABI := armeabi-v7a x86_64 # Target only armeabi-v7a and x86_64.
APP_ABI
için belirtebileceğiniz değerler hakkında daha fazla bilgi edinmek üzere
Application.mk.
CMake
CMake ile, aynı anda tek bir ABI için derleme yaparsınız ve ABI'nızı belirtmeniz gerekir
açık bir şekilde belirtmelisiniz. Bu işlemi, ANDROID_ABI
değişkeniyle yapabilirsiniz.
belirtilmiş olmalıdır (CMakeLists.txt dosyanızda ayarlanamaz). Örneğin,
örnek:
$ cmake -DANDROID_ABI=arm64-v8a ...
$ cmake -DANDROID_ABI=armeabi-v7a ...
$ cmake -DANDROID_ABI=x86 ...
$ cmake -DANDROID_ABI=x86_64 ...
NDK ile derlemek için CMake'e iletilmesi gereken diğer flag'ler için bkz. CMake kılavuzu'na bakabilirsiniz.
Derleme sisteminin varsayılan davranışı, her ABI için ikili programları eklemektir şişman APK olarak da bilinen tek bir APK içinde kullanılabilir. Yağlı APK, önemli ölçüde daha büyük tek bir ABI için ikili programları içeren bir ayardan daha iyidir; eşitlik kazanıyor daha büyük bir APK pahasına daha geniş kapsamlı uyumluluk sağlamaya çalışır. Kesinlikle iOS ve Android cihazınızda App Bundle veya APK Bölmelerinden maksimum cihaz değerini korurken APK'larınızın boyutunu küçültün uyumluluk.
Yükleme sırasında, paket yöneticisi yalnızca en uygun hedef cihazın makine koduna uygulanır. Ayrıntılar için yerel koda karşılık gelecek şekilde gönderin.
Android platformunda ABI yönetimi
Bu bölümde, Android platformunun yerel reklamları nasıl yönettiği hakkında ayrıntılar verilmiştir için de geçerlidir.
Uygulama paketlerinde yerel kod
Hem Play Store hem de Paket Yöneticisi, NDK tarafından oluşturulan içerikleri bulmayı bekler APK'nın içindeki dosya yollarında bulunan kitaplıklar:
/lib/<abi>/lib<name>.so
Burada <abi>
, Desteklenen ABI'ler altında listelenen ABI adlarından biridir.
<name>
ise LOCAL_MODULE
için tanımladığınız kitaplığın adıdır
değişkenini Android.mk
dosyasında görebilirsiniz. Başlangıç
APK dosyaları yalnızca zip dosyalarıdır. Bunları açmak ve paylaşılan yerel dosyanın
kitaplıklar da buradadır.
Sistem, beklediği yerde paylaşılan yerel kitaplıkları bulamazsa
gerekir. Böyle bir durumda, uygulamanın kendisi kitaplıkları kopyalayın ve ardından
dlopen()
gerçekleştir.
Yağ APK'sında her kitaplık, adı karşılık gelen ABI ile eşleşen bir dizin altında bulunur. Örneğin, yağlı bir APK şunları içerebilir:
/lib/armeabi/libfoo.so /lib/armeabi-v7a/libfoo.so /lib/arm64-v8a/libfoo.so /lib/x86/libfoo.so /lib/x86_64/libfoo.so
Not: 4.0.3 veya önceki sürümleri çalıştıran ARMv7 tabanlı Android cihazlar
armeabi-v7a
yerine armeabi
dizininden yerel kitaplıklar yükle
dizini de oluşturur. Çünkü /lib/armeabi/
,
APK'da /lib/armeabi-v7a/
. Bu sorun 4.0.4 sürümünde düzeltilmiştir.
Android platformu ABI desteği
Derlemeye özgü sistem, Android sistemi çalışma zamanında hangi ABI'leri desteklediğini bilir özellikleri şunları gösterir:
- Cihaz için, kullanılan makine koduna karşılık gelen birincil ABI sistem görüntüsünün kendisini.
- İsteğe bağlı olarak, sistem görüntüsünün kullandığı diğer ABI'lere karşılık gelen ikincil ABI'ler desteği de sunar.
Bu mekanizma, sistemin Google Cloud Platform'dan en iyi makine kodunu dikkat edin.
En iyi performans için doğrudan birincil ABI için derleme yapmanız gerekir. Örneğin,
tipik ARMv5TE tabanlı cihazlar yalnızca birincil ABI'yı tanımlar: armeabi
. Buna karşılık,
ARMv7 tabanlı normal bir cihaz, birincil ABI'yı armeabi-v7a
ve ikincil ABI olarak tanımlar
Her biri için oluşturulan uygulama yerel ikili programlarını çalıştırabileceğinden, bir armeabi
olarak ayarlanmalıdır.
64 bit cihazlar da 32 bit varyantlarını destekler. arm64-v8a cihazlarını kullanma cihaz, armeabi ve armeabi-v7a kodunu da çalıştırabilir. Not, 64 bit cihazlarda ise uygulamanızın çok daha iyi performans göstereceğini armeabi-v7a çalıştıran cihaza güvenmek yerine arm64-v8a'yı hedeflediğinden sürümünü kullandığınızdan emin olun.
x86 tabanlı birçok cihaz, armeabi-v7a
ve armeabi
NDK ikililerini de çalıştırabilir. Örneğin,
birincil ABI x86
, ikincisi ise armeabi-v7a
olur.
Belirli bir ABI için apk'yi zorunlu yükleyebilirsiniz. Bu, test için yararlıdır. Aşağıdaki komutu kullanın:
adb install --abi abi-identifier path_to_apk
Yükleme sırasında yerel kodu otomatik olarak ayıklama
Paket yöneticisi hizmeti, bir uygulama yüklerken APK'yı tarar ve uygulama yüklenirken, biçimin paylaşılan kitaplıklarını:
lib/<primary-abi>/lib<name>.so
Hiçbir şey bulunamazsa ve ikincil bir ABI tanımladıysanız hizmet, şu formu kullanın:
lib/<secondary-abi>/lib<name>.so
Aradığı kitaplıkları bulduğunda paket yöneticisi,
bunları, uygulamanın yerel kitaplık dizinindeki /lib/lib<name>.so
konumuna taşıma
(<nativeLibraryDir>/
). Aşağıdaki snippet'ler nativeLibraryDir
öğesini alır:
Kotlin
import android.content.pm.PackageInfo import android.content.pm.ApplicationInfo import android.content.pm.PackageManager ... val ainfo = this.applicationContext.packageManager.getApplicationInfo( "com.domain.app", PackageManager.GET_SHARED_LIBRARY_FILES ) Log.v(TAG, "native library dir ${ainfo.nativeLibraryDir}")
Java
import android.content.pm.PackageInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; ... ApplicationInfo ainfo = this.getApplicationContext().getPackageManager().getApplicationInfo ( "com.domain.app", PackageManager.GET_SHARED_LIBRARY_FILES ); Log.v( TAG, "native library dir " + ainfo.nativeLibraryDir );
Paylaşılan nesne dosyası yoksa uygulama derlenir ve yüklenir ancak belirler.
ARMv9: C/C++ için PAC ve BTI'yı etkinleştirme
PAC/BTI'nin etkinleştirilmesi bazı saldırı vektörlerine karşı koruma sağlar. PAC, iade adreslerini bir işlevin dosyasında kriptografik olarak imzalayarak korur. ve iade adresinde hâlâ doğru e-posta adresinin bölüm. BTI, Her şube hedefinin özel bir talimat olduğunu, başka hiçbir şey yapmayan kabul etmesini sağlayan taraftır.
Android, mevcut işlemcilerde herhangi bir işlem yapmayan PAC/BTI talimatlarını yeni talimatları desteklemez. PAC/BTI yalnızca ARMv9 cihazlarda bulunur ancak aynı kodu ARMv8 cihazlarda da çalıştırabilirsiniz: kitaplığınızın birden fazla varyantını bulabilirsiniz. ARMv9 cihazlarda bile PAC/BTI yalnızca geçerlidir 64 bit koda dönüştürün.
PAC/BTI'nin etkinleştirilmesi, kod boyutunda küçük bir artışa (genellikle %1) neden olur.
Arm'ın Mimari hakkında bilgi edinin: karmaşık yazılımlar (PDF) PAC/BTI hedefine ait saldırı vektörlerinin ve bu hedefin nasıl çalıştığını anlıyoruz.
Derleme değişiklikleri
ndk-kurum
Android.mk dosyanızın her modülünde LOCAL_BRANCH_PROTECTION := standard
değerini ayarlayın.
CMake
target_compile_options($TARGET PRIVATE -mbranch-protection=standard)
hesabını kullan
sizin CMakeLists.txt dosyanızdaki her hedef için.
Diğer derleme sistemleri
Kodunuzu -mbranch-protection=standard
kullanarak derleyin. Yalnızca bu işaret kullanılabilir
arm64-v8a ABI için derleme yaparken Aşağıdaki durumlarda bu işareti kullanmanız gerekmez:
bağlanıyor.
Sorun giderme
PAC/BTI için derleyici desteğiyle ilgili herhangi bir sorundan haberdar değiliz, ancak:
- Bağlama işlemi sırasında BTI ve BTI olmayan kodları birlikte kullanmamaya dikkat edin. BTI korumasının etkin olmadığı bir kitaplıkla sonuçlanır. Tekliflerinizi otomatikleştirmek ve optimize etmek için llvm-readelf adresini ziyaret ederek sonuç kitaplığınızda BTI notu olup olmadığını kontrol edebilirsiniz.
$ llvm-readelf --notes LIBRARY.so [...] Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 (property note) Properties: aarch64 feature: BTI, PAC [...] $
OpenSSL'nin eski (1.1.1i öncesi) sürümlerinde elle yazılmış derleyicide hata bulunuyor bu da PAC hatalarına neden olur. Geçerli OpenSSL'ye yükseltin.
Bazı uygulamaların DRM sistemlerinin eski sürümleri, PAC/BTI kodunu ihlal eden kod oluşturuyor. gereksinimlerini karşılayın. Uygulama DRM kullanıyorsanız ve PAC/BTI'yı etkinleştirirken sorun yaşıyorsanız sabit sürüm için DRM tedarikçi firmanızla görüşün.