Jika Anda baru menggunakan Bazel, harap mulai dengan tutorial Membangun Android dengan Bazel.
Ringkasan
Bazel dapat berjalan dalam berbagai konfigurasi build, termasuk beberapa konfigurasi yang menggunakan toolchain Android Native Development Kit (NDK). Artinya, aturan cc_library dan cc_binary normal dapat dikompilasi untuk Android langsung di dalam Bazel. Bazel melakukannya dengan menggunakan aturan repositori android_ndk_repository.
Prasyarat
Pastikan Anda telah menginstal Android SDK dan NDK.
Untuk menyiapkan SDK dan NDK, tambahkan cuplikan berikut ke WORKSPACE Anda:
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.
)
Untuk mengetahui informasi selengkapnya tentang aturan android_ndk_repository, lihat entri Ensiklopedia
Build.
Jika Anda menggunakan Android NDK versi terbaru (r22 dan yang lebih baru), gunakan implementasi Starlark dari android_ndk_repository.
Ikuti petunjuk dalam
README-nya.
Mulai cepat
Untuk mem-build C++ untuk Android, cukup tambahkan dependensi cc_library ke aturan android_binary atau android_library Anda.
Misalnya, dengan file BUILD berikut untuk aplikasi Android:
# 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",
)
File BUILD ini akan menghasilkan grafik target berikut:

Gambar 1. Grafik build project Android dengan dependensi cc_library.
Untuk mem-build aplikasi, cukup jalankan:
bazel build //app/src/main:appPerintah bazel build mengompilasi file Java, file resource Android, dan aturan cc_library, serta mengemas semuanya ke dalam APK:
$ 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 mengompilasi semua cc_library ke dalam satu file objek bersama (.so), yang ditargetkan untuk ABI armeabi-v7a secara default. Untuk mengubahnya atau mem-build untuk
beberapa ABI secara bersamaan, lihat bagian tentang mengonfigurasi ABI
target.
Contoh penyiapan
Contoh ini tersedia di repositori contoh Bazel.
Dalam file BUILD.bazel, tiga target ditentukan dengan aturan android_binary, android_library, dan cc_library.
Target tingkat atas android_binary mem-build APK.
Target cc_library berisi satu file sumber C++ dengan implementasi fungsi JNI:
#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());
}
Target android_library menentukan sumber Java, file resource, dan dependensi pada target cc_library. Untuk contoh ini, MainActivity.java memuat file objek bersama libapp.so, dan menentukan tanda tangan metode untuk fungsi JNI:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("app");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
public native String stringFromJNI();
}
Mengonfigurasi ABI target
Untuk mengonfigurasi ABI target, gunakan flag --android_platforms sebagai berikut:
bazel build //:app --android_platforms=comma-separated list of platformsSama seperti flag --platforms, nilai yang diteruskan ke --android_platforms adalah
label target platform, menggunakan nilai batasan standar untuk mendeskripsikan perangkat Anda.
Misalnya, untuk perangkat Android dengan prosesor ARM 64-bit, Anda akan menentukan platform seperti ini:
platform(
name = "android_arm64",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:arm64",
],
)
Setiap Android platform harus menggunakan batasan OS @platforms//os:android. Untuk memigrasikan batasan CPU, lihat diagram ini:
| Nilai CPU | Platform |
|---|---|
armeabi-v7a |
@platforms//cpu:armv7 |
arm64-v8a |
@platforms//cpu:arm64 |
x86 |
@platforms//cpu:x86_32 |
x86_64 |
@platforms//cpu:x86_64 |
Dan, tentu saja, untuk APK multi-arsitektur, Anda meneruskan beberapa label, misalnya: --android_platforms=//:arm64,//:x86_64 (dengan asumsi Anda menentukannya dalam file BUILD.bazel tingkat atas).
Bazel tidak dapat memilih platform Android default, sehingga platform harus ditentukan dan ditetapkan dengan --android_platforms.
Bergantung pada revisi NDK dan level API Android, ABI berikut tersedia:
| Revisi NDK | ABI |
|---|---|
| 16 dan yang lebih rendah | armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86_64 |
| 17 dan yang lebih tinggi | armeabi-v7a, arm64-v8a, x86, x86_64 |
Lihat dokumen NDK untuk mengetahui informasi selengkapnya tentang ABI ini.
APK Fat Multi-ABI tidak direkomendasikan untuk build rilis karena meningkatkan ukuran APK, tetapi dapat berguna untuk build pengembangan dan QA.
Memilih standar C++
Gunakan flag berikut untuk mem-build sesuai dengan standar C++:
| Standar C++ | Flag |
|---|---|
| C++98 | Default, tidak memerlukan flag |
| C++11 | --cxxopt=-std=c++11 |
| C++14 | --cxxopt=-std=c++14 |
| C++17 | --cxxopt=-std=c++17 |
Contoh:
bazel build //:app --cxxopt=-std=c++11Baca lebih lanjut tentang cara meneruskan flag compiler dan linker dengan --cxxopt, --copt, dan
--linkopt di Panduan Pengguna.
Flag compiler dan linker juga dapat ditentukan sebagai atribut di cc_library menggunakan copts dan linkopts. Contoh:
cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
copts = ["-std=c++11"],
linkopts = ["-ldl"], # link against libdl
)
Mem-build cc_library untuk Android tanpa menggunakan android_binary
Untuk mem-build cc_binary atau cc_library mandiri untuk Android tanpa menggunakan android_binary, gunakan flag --platforms.
Misalnya, dengan asumsi Anda telah menentukan platform Android di my/platforms/BUILD:
bazel build //my/cc/jni:target \
--platforms=//my/platforms:x86_64Dengan pendekatan ini, seluruh pohon build akan terpengaruh.
Flag ini dapat dimasukkan ke dalam konfigurasi bazelrc (satu untuk setiap ABI), di
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>
Kemudian, untuk mem-build cc_library untuk x86, misalnya, jalankan:
bazel build //my/cc/jni:target --config=android_x86Secara umum, gunakan metode ini untuk target tingkat rendah (seperti cc_library) atau saat Anda mengetahui dengan pasti apa yang Anda build; bergantung pada transisi konfigurasi otomatis dari android_binary untuk target tingkat tinggi tempat Anda berharap untuk mem-build banyak target yang tidak Anda kontrol.