अगर Bazel आपके लिए नया है, तो कृपया Bazel की मदद से Android ऐप्लिकेशन बनाने का ट्यूटोरियल देखें.
खास जानकारी
Bazel को कई अलग-अलग बिल्ड कॉन्फ़िगरेशन में चलाया जा सकता है. इनमें से कुछ में, Android Native Development Kit (NDK) टूलचेन का इस्तेमाल किया जाता है. इसका मतलब है कि सामान्य cc_library और cc_binary नियमों को, Bazel में सीधे Android के लिए कंपाइल किया जा सकता है. Bazel, android_ndk_repository रिपॉज़िटरी नियम का इस्तेमाल करके ऐसा करता है.
ज़रूरी शर्तें
कृपया पक्का करें कि आपने Android SDK और NDK इंस्टॉल किया हो.
SDK और NDK सेट अप करने के लिए, अपने WORKSPACE में यह स्निपेट जोड़ें:
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 नियम के बारे में ज़्यादा जानने के लिए, Build
Encyclopedia की एंट्री देखें.
अगर आपने Android NDK का नया वर्शन (r22 और उसके बाद का वर्शन) इस्तेमाल किया है, तो android_ndk_repository के Starlark लागू करने की सुविधा का इस्तेमाल करें.
इसके
README में दिए गए निर्देशों का पालन करें.
तुरंत शुरू करना
Android के लिए C++ बनाने के लिए, अपने android_binary या android_library नियमों में, cc_library डिपेंडेंसी जोड़ें.
उदाहरण के लिए, Android ऐप्लिकेशन के लिए यह BUILD फ़ाइल दी गई है:
# 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",
)
इस BUILD फ़ाइल से, टारगेट का यह ग्राफ़ बनता है:

पहली इमेज. cc_library डिपेंडेंसी वाले Android प्रोजेक्ट का बिल्ड ग्राफ़.
ऐप्लिकेशन बनाने के लिए, यह कमांड चलाएं:
bazel build //app/src/main:appbazel build कमांड, Java फ़ाइलें, Android रिसॉर्स फ़ाइलें, और cc_library नियम कंपाइल करता है. साथ ही, इन सभी को एक 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, सभी cc_libraries को एक शेयर किए गए ऑब्जेक्ट (.so) फ़ाइल में कंपाइल करता है. इसे डिफ़ॉल्ट रूप से, armeabi-v7a एबीआई के लिए टारगेट किया जाता है. इसे बदलने या एक साथ कई एबीआई के लिए बिल्ड करने के लिए, टारगेट एबीआई को कॉन्फ़िगर करने से जुड़ा सेक्शन देखें.
सेटअप का उदाहरण
यह उदाहरण, Bazel के उदाहरणों वाली रिपॉज़िटरी में उपलब्ध है.
BUILD.bazel फ़ाइल में, android_binary, android_library, और cc_library नियमों के साथ तीन टारगेट तय किए गए हैं.
android_binary टॉप-लेवल टारगेट, APK बनाता है.
cc_library टारगेट में, JNI फ़ंक्शन लागू करने वाली एक C++ सोर्स फ़ाइल शामिल होती है:
#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 टारगेट में, Java सोर्स, रिसॉर्स फ़ाइलें, और cc_library टारगेट पर डिपेंडेंसी की जानकारी दी जाती है. इस उदाहरण के लिए, MainActivity.java, शेयर किए गए ऑब्जेक्ट फ़ाइल libapp.so को लोड करता है. साथ ही, JNI फ़ंक्शन के लिए, तरीके के सिग्नेचर को तय करता है:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("app");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
public native String stringFromJNI();
}
टारगेट एबीआई को कॉन्फ़िगर करना
टारगेट एबीआई को कॉन्फ़िगर करने के लिए, --android_platforms फ़्लैग का इस्तेमाल इस तरह करें:
bazel build //:app --android_platforms=comma-separated list of platforms--platforms फ़्लैग की तरह, --android_platforms को पास की गई वैल्यू,
platform
टारगेट के लेबल होती हैं. इनमें, आपके डिवाइस के बारे में बताने के लिए, स्टैंडर्ड कंस्ट्रेंट वैल्यू का इस्तेमाल किया जाता है.
उदाहरण के लिए, 64-बिट एआरएम प्रोसेसर वाले Android डिवाइस के लिए, अपने प्लैटफ़ॉर्म को इस तरह तय करें:
platform(
name = "android_arm64",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:arm64",
],
)
हर Android platform को @platforms//os:android
ओएस कंस्ट्रेंट का इस्तेमाल करना चाहिए. सीपीयू कंस्ट्रेंट माइग्रेट करने के लिए, यह चार्ट देखें:
| सीपीयू की वैल्यू | प्लैटफ़ॉर्म |
|---|---|
armeabi-v7a |
@platforms//cpu:armv7 |
arm64-v8a |
@platforms//cpu:arm64 |
x86 |
@platforms//cpu:x86_32 |
x86_64 |
@platforms//cpu:x86_64 |
मल्टी-आर्किटेक्चर APK के लिए, एक से ज़्यादा लेबल पास करें. उदाहरण के लिए: --android_platforms=//:arm64,//:x86_64. हालांकि, यह मान लिया जाता है कि आपने इन्हें अपने टॉप-लेवल BUILD.bazel फ़ाइल में तय किया है.
Bazel, डिफ़ॉल्ट Android प्लैटफ़ॉर्म नहीं चुन सकता. इसलिए, एक प्लैटफ़ॉर्म तय करना और --android_platforms के साथ उसकी जानकारी देना ज़रूरी है.
एनडीके के वर्शन और Android एपीआई लेवल के हिसाब से, ये एबीआई उपलब्ध हैं:
| एनडीके का वर्शन | एबीआई |
|---|---|
| 16 और उससे पहले के वर्शन | armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86_64 |
| 17 और उसके बाद के वर्शन | armeabi-v7a, arm64-v8a, x86, x86_64 |
इन एबीआई के बारे में ज़्यादा जानने के लिए, एनडीके के दस्तावेज़ देखें.
रिलीज़ बिल्ड के लिए, मल्टी-एबीआई फ़ैट APK इस्तेमाल करने का सुझाव नहीं दिया जाता. ऐसा इसलिए, क्योंकि इससे APK का साइज़ बढ़ जाता है. हालांकि, डेवलपमेंट और क्यूए बिल्ड के लिए, यह फ़ायदेमंद हो सकता है.
C++ स्टैंडर्ड चुनना
किसी C++ स्टैंडर्ड के मुताबिक बिल्ड करने के लिए, इन फ़्लैग का इस्तेमाल करें:
| C++ स्टैंडर्ड | फ़्लैग |
|---|---|
| C++98 | डिफ़ॉल्ट, किसी फ़्लैग की ज़रूरत नहीं है |
| C++11 | --cxxopt=-std=c++11 |
| C++14 | --cxxopt=-std=c++14 |
| C++17 | --cxxopt=-std=c++17 |
उदाहरण के लिए:
bazel build //:app --cxxopt=-std=c++11कंपाइलर और लिंकर फ़्लैग को, copts और linkopts का इस्तेमाल करके, cc_library में एट्रिब्यूट के तौर पर भी तय किया जा सकता है. उदाहरण के लिए:
cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
copts = ["-std=c++11"],
linkopts = ["-ldl"], # link against libdl
)
android_binary का इस्तेमाल किए बिना, Android के लिए cc_library बनाना
android_binary का इस्तेमाल किए बिना, Android के लिए स्टैंडअलोन cc_binary या cc_library बनाने के लिए, --platforms फ़्लैग का इस्तेमाल करें.
उदाहरण के लिए, मान लें कि आपने my/platforms/BUILD में Android प्लैटफ़ॉर्म तय किए हैं:
bazel build //my/cc/jni:target \
--platforms=//my/platforms:x86_64इस तरीके से, पूरे बिल्ड ट्री पर असर पड़ता है.
इन फ़्लैग को bazelrc कॉन्फ़िगरेशन (हर एबीआई के लिए एक) में,
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>
इसके बाद, उदाहरण के लिए, x86 के लिए cc_library बनाने के लिए, यह कमांड चलाएं:
bazel build //my/cc/jni:target --config=android_x86आम तौर पर, इस तरीके का इस्तेमाल, लो-लेवल टारगेट (जैसे कि cc_library) के लिए या तब करें, जब आपको पता हो कि आपको क्या बनाना है. हाई-लेवल टारगेट के लिए, android_binary से मिलने वाले ऑटोमैटिक कॉन्फ़िगरेशन ट्रांज़िशन पर भरोसा करें. ऐसा तब करें, जब आपको ऐसे कई टारगेट बनाने हों जिन्हें आपने कंट्रोल नहीं किया है.