Bazel'i yeni kullanmaya başlıyorsanız lütfen Android'i Bazel ile Oluşturma eğitiminden başlayın.
Genel Bakış
Bazel, Android Native Development Kit (NDK) araç zincirini kullananlar 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'de derlenebileceği anlamına gelir. Bazel, bu işlemi android_ndk_repository deposu kuralını kullanarak gerçekleştirir.
Ön koşullar
Lütfen Android SDK ve NDK'yı yüklediğinizden emin olun.
SDK ve NDK'yı ayarlamak için WORKSPACE dosyanıza aşağıdaki snippet'i 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 Build
Encyclopedia entry başlıklı makaleyi inceleyin.
Android NDK'nın yeni bir sürümünü (r22 ve sonrası) kullanıyorsanız android_ndk_repository için Starlark uygulamasını kullanın.
README dosyasındaki talimatları uygulayın.
Hızlı başlangıç
Android için C++ oluşturmak üzere cc_library bağımlılıklarını android_binary veya android_library kurallarınıza eklemeniz yeterlidir.
Örneğin, bir Android uygulaması için aşağıdaki BUILD dosyası verildiğinde:
# 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ı aşağıdaki hedef grafiği oluşturur:

1. şekil. cc_library bağımlılıklarıyla Android projesinin grafiğini oluşturun.
Uygulamayı oluşturmak için şu komutu çalıştırmanız yeterlidir:
bazel build //app/src/main:appbazel build komutu Java dosyalarını, Android kaynak dosyalarını ve cc_library kurallarını derler ve 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.MFBazel, tüm cc_libraries'i tek bir paylaşılan nesne (.so) dosyasında derler ve varsayılan olarak armeabi-v7a ABI'yi hedefler. Bunu değiştirmek veya aynı anda birden fazla ABI için derleme yapmak istiyorsanız 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ımlanmıştır.
android_binary üst düzey hedefi, APK'yı oluşturur.
cc_library hedefi, JNI işlevi uygulaması içeren 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 cc_library hedefindeki bağımlılığı belirtir. Bu örnekte, MainActivity.java paylaşılan nesne dosyasını yükler libapp.so 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'yi 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'ye iletilen değerler, cihazınızı tanımlamak için standart kısıtlama değerlerini kullanan platform hedeflerinin etiketleridir.
Örneğin, 64 bit ARM işlemcili 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 bu tabloya bakın:
| CPU Değeri | Platform |
|---|---|
armeabi-v7a |
@platforms//cpu:armv7 |
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 iletirsiniz. Ö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çemez. Bu nedenle, bir platform tanımlanmalı ve --android_platforms ile 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 daha düşük | armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86_64 |
| 17 yaş ve üzeri | armeabi-v7a, arm64-v8a, x86, x86_64 |
Bu ABI'ler hakkında daha fazla bilgi için NDK belgelerine bakın.
Çoklu ABI Fat APK'lar, APK'nın boyutunu artırdığı için yayın derlemeleri için önerilmez ancak geliştirme ve kalite güvencesi derlemeleri için yararlı olabilir.
C++ standardı seçme
Bir C++ standardına göre derleme yapmak için aşağıdaki işaretleri kullanın:
| C++ Standard | İş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--cxxopt, --copt ve --linkopt ile derleyici ve bağlayıcı işaretlerini iletme hakkında daha fazla bilgiyi Kullanıcı Kılavuzu'nda bulabilirsiniz.
Derleyici ve bağlayıcı işaretleri, cc_library içinde copts ve linkopts kullanılarak ö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
)
cc_library kullanmadan Android için android_binary 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 içinde Android platformlarını tanımladığınızı varsayarsak:
bazel build //my/cc/jni:target \
--platforms=//my/platforms:x86_64Bu yaklaşımla, derleme ağacının tamamı etkilenir.
Bu işaretler, bazelrc yapılandırmasına (her ABI için bir tane) yerleştirilebilir. project/.bazelrc:
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 cc_library oluşturmak üzere şu komutu çalıştırın:
bazel build //my/cc/jni:target --config=android_x86Genel olarak, bu yöntemi düşük düzeyli hedefler (ör. cc_library) için veya ne oluşturduğunuzu tam olarak bildiğinizde kullanın. Kontrol etmediğiniz birçok hedef oluşturmayı beklediğiniz yüksek düzeyli hedefler için android_binary'den otomatik yapılandırma geçişlerini kullanın.