Bazel'i kullanmaya yeni başladıysanız lütfen Bazel ile Android oluşturma eğiticisiyle başlayın.
Genel bakış
Bazel, Android Yerel Geliştirme Kiti (NDK) araç zincirini kullanan birkaç yapılandırma da dahil olmak üzere
birçok farklı derleme yapılandırmasında çalışabilir. Bu, normal cc_library
ve cc_binary
kurallarının Android için doğrudan Bazel'da derlenebileceği anlamına gelir. Bazel, bunu android_ndk_repository
deposu kuralını kullanarak gerçekleştirir.
Ön koşullar
Lütfen Android SDK'sını ve NDK'yı yüklediğinizden emin olun.
SDK'yı ve NDK'yı ayarlamak için aşağıdaki snippet'i WORKSPACE
cihazınıza ekleyin:
android_sdk_repository(
name = "androidsdk", # Required. Name *must* be "androidsdk".
path = "/path/to/sdk", # Optional. Can be omitted if `ANDROID_HOME` environment variable is set.
)
android_ndk_repository(
name = "androidndk", # Required. Name *must* be "androidndk".
path = "/path/to/ndk", # Optional. Can be omitted if `ANDROID_NDK_HOME` environment variable is set.
)
android_ndk_repository
kuralı hakkında daha fazla bilgi için Ansiklopedi Oluşturma girişi'ne bakın.
Android NDK'nın yeni bir sürümünü (r22 ve sonrası) kullanıyorsanız android_ndk_repository
Starlark uygulamasını kullanın.
README bölümündeki talimatları uygulayın.
Hızlı başlangıç
Android için C++ oluşturmak istiyorsanız android_binary
veya android_library
kurallarınıza cc_library
bağımlılıkları eklemeniz yeterlidir.
Örneğin, bir Android uygulaması için aşağıdaki BUILD
dosyası göz önünde bulundurulduğunda:
# In <project>/app/src/main/BUILD.bazel
cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
)
android_library(
name = "lib",
srcs = ["java/com/example/android/bazel/MainActivity.java"],
resource_files = glob(["res/**/*"]),
custom_package = "com.example.android.bazel",
manifest = "LibraryManifest.xml",
deps = [":jni_lib"],
)
android_binary(
name = "app",
deps = [":lib"],
manifest = "AndroidManifest.xml",
)
Bu BUILD
dosyası şu hedef grafiğinle sonuçlanıyor:
Şekil 1. cc_library bağımlılıkları ile Android projesinin grafiğini oluşturun.
Uygulamayı oluşturmak için şu komutu çalıştırmanız yeterlidir:
bazel build //app/src/main:app
bazel build
komutu; Java dosyalarını, Android kaynak dosyalarını ve cc_library
kurallarını derleyip her şeyi bir APK'da paketler:
$ zipinfo -1 bazel-bin/app/src/main/app.apk
nativedeps
lib/armeabi-v7a/libapp.so
classes.dex
AndroidManifest.xml
...
res/...
...
META-INF/CERT.SF
META-INF/CERT.RSA
META-INF/MANIFEST.MF
Bazel, tüm cc_libraries öğelerini varsayılan olarak armeabi-v7a
ABI'yı hedefleyen tek bir paylaşılan nesne (.so
) dosyasında derler. Bunu değiştirmek veya aynı anda birden çok ABI oluşturmak için hedef ABI'yi yapılandırma bölümüne bakın.
Örnek kurulum
Bu örneği Bazel örnekleri deposunda bulabilirsiniz.
BUILD.bazel
dosyasında android_binary
, android_library
ve cc_library
kurallarıyla üç hedef tanımlanır.
APK'yı android_binary
üst düzey hedefi oluşturur.
cc_library
hedefi, JNI işlevi uygulamasına sahip tek bir C++ kaynak dosyası içerir:
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_android_bazel_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
android_library
hedefi; Java kaynaklarını, kaynak dosyalarını ve bir cc_library
hedefine bağımlılığı belirtir. Bu örnekte MainActivity.java
, libapp.so
paylaşılan nesne dosyasını yükler ve JNI işlevi için yöntem imzasını tanımlar:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("app");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
public native String stringFromJNI();
}
Hedef ABI'yı yapılandırma
Hedef ABI'yi yapılandırmak için --android_platforms
işaretini aşağıdaki gibi kullanın:
bazel build //:app --android_platforms=comma-separated list of platforms
--platforms
işaretinde olduğu gibi, --android_platforms
öğesine iletilen değerler platform
hedeflerinin etiketleridir ve cihazınızı tanımlamak için standart kısıtlama değerleri kullanılır.
Örneğin, 64 bit ARM işlemciye sahip bir Android cihaz için platformunuzu şu şekilde tanımlarsınız:
platform(
name = "android_arm64",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:arm64",
],
)
Her Android platform
, @platforms//os:android
işletim sistemi kısıtlamasını kullanmalıdır. CPU kısıtlamasını taşımak için aşağıdaki grafiği kontrol edin:
CPU Değeri | Platform |
---|---|
armeabi-v7a |
@platforms//cpu:arm |
arm64-v8a |
@platforms//cpu:arm64 |
x86 |
@platforms//cpu:x86_32 |
x86_64 |
@platforms//cpu:x86_64 |
Elbette, çok mimarili bir APK için birden fazla etiket geçirirsiniz. Örneğin: --android_platforms=//:arm64,//:x86_64
(bunları üst düzey BUILD.bazel
dosyanızda tanımladığınız varsayılır).
Bazel, varsayılan bir Android platformu seçemediğinden bir platform --android_platforms
ile tanımlanmalı ve belirtilmelidir.
NDK düzeltmesine ve Android API düzeyine bağlı olarak aşağıdaki ABI'ler kullanılabilir:
NDK düzeltmesi | ABI'lar |
---|---|
16 ve altı | armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86_64 |
17 ve üzeri | armeabi-v7a, arm64-v8a, x86, x86_64 |
Bu ABI'ler hakkında daha fazla bilgi için NDK belgelerine bakın.
Multi-ABI Fat APK'ları, APK'nın boyutunu büyüttükleri için sürüm derlemeleri için önerilmez, ancak geliştirme ve KG derlemeleri için yararlı olabilirler.
C++ standardı seçme
C++ standardına göre derlemek için aşağıdaki işaretleri kullanın:
C++ Standart | İşaret |
---|---|
C++98 | Varsayılan, işaret gerekmez |
C++11 | --cxxopt=-std=c++11 |
C++14 | --cxxopt=-std=c++14 |
C++17 | --cxxopt=-std=c++17 |
Örneğin:
bazel build //:app --cxxopt=-std=c++11
Kullanıcı Kılavuzu'nda --cxxopt
, --copt
ve --linkopt
ile derleyici ve bağlayıcı işaretlerini iletme hakkında daha fazla bilgi edinin.
Derleyici ve bağlayıcı işaretleri, copts
ve linkopts
kullanılarak cc_library
içinde özellik olarak da belirtilebilir. Örneğin:
cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
copts = ["-std=c++11"],
linkopts = ["-ldl"], # link against libdl
)
android_binary
kullanmadan Android için cc_library
oluşturma
android_binary
kullanmadan Android için bağımsız bir cc_binary
veya cc_library
oluşturmak istiyorsanız --platforms
işaretini kullanın.
Örneğin, my/platforms/BUILD
bölgesinde Android platformlarını tanımladığınızı varsayarsak:
bazel build //my/cc/jni:target \
--platforms=//my/platforms:x86_64
Bu yaklaşımda tüm yapı ağacı etkilenir.
Bu işaretler, project/.bazelrc
içinde bir bazelrc
yapılandırmasına (her ABI için bir tane) eklenebilir:
common:android_x86 --platforms=//my/platforms:x86
common:android_armeabi-v7a --platforms=//my/platforms:armeabi-v7a
# In general
common:android_<abi> --platforms=//my/platforms:<abi>
Ardından, örneğin x86
için bir cc_library
oluşturmak üzere şu komutu çalıştırın:
bazel build //my/cc/jni:target --config=android_x86
Genel olarak bu yöntemi düşük seviyeli hedefler (cc_library
gibi) için veya ne geliştirdiğinizi tam olarak biliyorsanız kullanın. Kontrol etmediğiniz çok sayıda hedef oluşturmayı beklediğiniz üst düzey hedefler için android_binary
ürününden yapılan otomatik yapılandırma geçişlerini kullanın.