32-बिट और 64-बिट आर्किटेक्चर के लिए बनाएं

बिल्ड सिस्टम, एक ही बिल्ड में दो टारगेट सीपीयू आर्किटेक्चर 32 बिट और 64 बिट के लिए बाइनरी बनाने की सुविधा देता है. दो टारगेट वाले इस बिल्ड को मल्टीलिब बिल्ड कहा जाता है.

बिल्ट-इन स्टैटिक लाइब्रेरी और शेयर की गई लाइब्रेरी के लिए, बिल्ड सिस्टम दोनों आर्किटेक्चर के लिए बाइनरी बनाने के लिए नियम सेट अप करता है. प्रॉडक्ट कॉन्फ़िगरेशन (PRODUCT_PACKAGES) और डिपेंडेंसी ग्राफ़ से यह तय होता है कि सिस्टम इमेज में कौनसी बाइनरी बनाई और इंस्टॉल की जाएंगी.

डिवाइस पर चलाए जा सकने वाले प्रोग्राम और ऐप्लिकेशन के लिए, बिल्ड सिस्टम डिफ़ॉल्ट रूप से सिर्फ़ 64-बिट वर्शन बनाता है. हालांकि, इस सेटिंग को किसी ग्लोबल BoardConfig.mk वैरिएबल या मॉड्यूल के दायरे वाले वैरिएबल की मदद से बदला जा सकता है.

दूसरे सीपीयू आर्किटेक्चर और एबीआई की पहचान करना

BoardConfig.mk में दूसरे सीपीयू आर्किटेक्चर और ऐप्लिकेशन बाइनरी इंटरफ़ेस (एबीआई) को कॉन्फ़िगर करने के लिए, ये वैरिएबल शामिल हैं:

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

इन वैरिएबल का इस्तेमाल करने वाली मेकफ़ाइल का उदाहरण देखने के लिए, build/make/target/board/generic_arm64/BoardConfig.mk देखें.

मल्टीलिब बिल्ड में, PRODUCT_PACKAGES में मौजूद मॉड्यूल के नाम, 32-बिट और 64-बिट, दोनों तरह के बाइनरी को कवर करते हैं. हालांकि, ऐसा तब ही होता है, जब उन्हें बिल्ड सिस्टम से तय किया गया हो. डिपेंडेंसी की वजह से शामिल की गई लाइब्रेरी के लिए, 32-बिट या 64-बिट वाली लाइब्रेरी सिर्फ़ तब इंस्टॉल की जाती है, जब किसी दूसरी 32-बिट या 64-बिट वाली लाइब्रेरी या फिर किसी ऐसी लाइब्रेरी के लिए ज़रूरी हो जिसे चलाया जा सकता हो.

हालांकि, make कमांड लाइन पर मॉड्यूल के नाम सिर्फ़ 64-बिट वर्शन को कवर करते हैं. उदाहरण के लिए, lunch aosp_arm64-eng को चलाने के बाद, make libc सिर्फ़ 64-बिट libc बनाता है. 32-बिट libc को बनाने के लिए, आपको make libc_32 को चलाना होगा.

Android.mk में मॉड्यूल आर्किटेक्चर तय करना

LOCAL_MULTILIB वैरिएबल का इस्तेमाल करके, 32 बिट और 64 बिट के लिए अपना बिल्ड कॉन्फ़िगर किया जा सकता है. साथ ही, ग्लोबल TARGET_PREFER_32_BIT वैरिएबल को बदला जा सकता है.

TARGET_PREFER_32_BIT को बदलने के लिए, LOCAL_MULTILIB को इनमें से किसी एक पर सेट करें:

  • both, 32-बिट और 64-बिट, दोनों वर्शन बनाता है.
  • 32 सिर्फ़ 32 बिट बनाता है.
  • 64 सिर्फ़ 64-बिट वाले वर्शन बनाता है.
  • first को सिर्फ़ पहले आर्किटेक्चर के लिए बनाया जाता है (32-बिट डिवाइसों में 32 बिट और 64-बिट डिवाइसों में 64 बिट).

डिफ़ॉल्ट रूप से, LOCAL_MULTILIB सेट नहीं होता. साथ ही, मॉड्यूल क्लास और LOCAL_MODULE_TARGET_ARCH और LOCAL_32_BIT_ONLY जैसे अन्य LOCAL_* वैरिएबल के आधार पर, बिल्ड सिस्टम यह तय करता है कि किस आर्किटेक्चर को बिल्ड करना है.

अगर आपको किसी खास आर्किटेक्चर के लिए अपना मॉड्यूल बनाना है, तो इन वैरिएबल का इस्तेमाल करें:

  • LOCAL_MODULE_TARGET_ARCH - इस वैरिएबल को आर्किटेक्चर की सूची पर सेट करें, जैसे कि arm x86 arm64. अगर बनाया जा रहा आर्किटेक्चर उस सूची में है, तो बिल्ड सिस्टम मौजूदा मॉड्यूल को शामिल कर लेता है.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH - यह वैरिएबल, LOCAL_MODULE_TARGET_ARCH के उलट होता है. अगर बनाया जा रहा आर्किटेक्चर उस सूची में not शामिल है, तो मौजूदा मॉड्यूल को बिल्ड सिस्टम में शामिल किया जाता है.

इन दोनों वैरिएबल के छोटे वैरिएंट होते हैं:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

अगर सूची में मौजूद आर्किटेक्चर की वजह से मौजूदा मॉड्यूल को छोड़ा जाता है, तो बिल्ड सिस्टम चेतावनी देता है.

किसी खास आर्किटेक्चर के लिए बिल्ड फ़्लैग सेट अप करने के लिए, आर्किटेक्चर के हिसाब से LOCAL_* वैरिएबल का इस्तेमाल करें. यहां *, आर्किटेक्चर के हिसाब से दिया गया सफ़िक्स है. उदाहरण के लिए:

  • LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
  • LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
  • LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,

ये वैरिएबल सिर्फ़ तब लागू होते हैं, जब उस आर्किटेक्चर के लिए कोई बाइनरी बनाई जा रही हो.

कभी-कभी, फ़्लैग को इस आधार पर सेट अप करना आसान होता है कि बाइनरी को 32-बिट या 64-बिट के लिए बनाया जा रहा है या नहीं. LOCAL_* वैरिएबल का इस्तेमाल _32 या _64 सफ़िक्स के साथ करें. उदाहरण के लिए:

  • LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
  • LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
  • LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,

लाइब्रेरी इंस्टॉल करने का पाथ सेट करें

नॉन-मल्टीलिब बिल्ड के लिए, LOCAL_MODULE_PATH का इस्तेमाल करके लाइब्रेरी को डिफ़ॉल्ट जगह के अलावा किसी दूसरी जगह पर इंस्टॉल किया जा सकता है. उदाहरण के लिए, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw.

हालांकि, मल्टीलिब बिल्ड में, इसके बजाय LOCAL_MODULE_RELATIVE_PATH का इस्तेमाल करें:

LOCAL_MODULE_RELATIVE_PATH := hw

इस फ़ॉर्मैट में, 64-बिट और 32-बिट, दोनों लाइब्रेरी सही जगह पर इंस्टॉल होती हैं.

अगर 32 बिट और 64 बिट दोनों के रूप में एक्ज़ीक्यूटेबल बनाया जाता है, तो इंस्टॉल पाथ में अंतर करने के लिए इनमें से किसी एक वैरिएबल का इस्तेमाल करें:

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64 - इंस्टॉल की गई फ़ाइल का नाम बताता है.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 - इंस्टॉल पाथ के बारे में जानकारी देता है.

सोर्स फ़ाइलों के लिए इंटरमीडिएट डायरेक्ट्री पाना

मल्टीलिब बिल्ड में, अगर $(local-intermediates-dir) (या साफ़ तौर पर वैरिएबल के साथ $(intermediates-dir-for)) के लिए सोर्स फ़ाइलें जनरेट की जाती हैं, तो यह भरोसेमंद तरीके से काम नहीं करती. ऐसा इसलिए है, क्योंकि जनरेट किए गए इंटरमीडिएट सोर्स, 32-बिट और 64-बिट, दोनों तरह के बिल्ड के लिए ज़रूरी होते हैं. हालांकि, $(local-intermediates-dir) सिर्फ़ दो इंटरमीडिएट डायरेक्ट्री में से किसी एक पर ले जाता है.

बिल्ड सिस्टम, सोर्स जनरेट करने के लिए खास तौर पर, मल्टीलिब-फ़्रेंडली, इंटरमीडिएट डायरेक्ट्री उपलब्ध कराता है. इंटरमीडिएट डायरेक्ट्री का पाथ पाने के लिए, $(local-generated-sources-dir) या $(generated-sources-dir-for) मैक्रो का इस्तेमाल करें. इन मैक्रो का इस्तेमाल, $(local-intermediates-dir) और $(intermediates-dir-for) के इस्तेमाल से मिलता-जुलता है.

अगर कोई सोर्स फ़ाइल इस खास डायरेक्ट्री में जनरेट की जाती है और LOCAL_GENERATED_SOURCES इसे चुनता है, तो इसे मल्टीलिब बिल्ड में 32 बिट और 64 बिट, दोनों के लिए बनाया जाता है.

पहले से बने बाइनरी टारगेट के सिस्टम आर्किटेक्चर के बारे में बताएं

मल्टीलिब बिल्ड में, पहले से बने बाइनरी टारगेट का सिस्टम आर्किटेक्चर दिखाने के लिए, TARGET_ARCH या TARGET_2ND_ARCH के साथ TARGET_ARCH का इस्तेमाल नहीं किया जा सकता. इसके बजाय, LOCAL_* वैरिएबल LOCAL_MODULE_TARGET_ARCH या LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH का इस्तेमाल करें.

इन वैरिएबल की मदद से, बिल्ड सिस्टम 32-बिट वाला पहले से बना बाइनरी चुन सकता है. भले ही, वह 64-बिट वाले मल्टीलिब बिल्ड पर काम कर रहा हो.

अगर आपको पहले से बने बाइनरी के सोर्स पाथ का हिसाब लगाने के लिए, चुने गए आर्किटेक्चर का इस्तेमाल करना है, तो $(get-prebuilt-src-arch) को कॉल करें.

32-बिट और 64-बिट ODEX फ़ाइल जनरेट करना पक्का करें

64-बिट डिवाइसों के लिए, Google डिफ़ॉल्ट रूप से बूट इमेज और किसी भी Java लाइब्रेरी के लिए, 32-बिट और 64-बिट, दोनों तरह की ODEX फ़ाइलें जनरेट करता है. APKs के लिए, Google डिफ़ॉल्ट रूप से सिर्फ़ मुख्य 64-बिट आर्किटेक्चर के लिए ODEX जनरेट करता है. अगर कोई ऐप्लिकेशन 32-बिट और 64-बिट, दोनों प्रोसेस में लॉन्च किया जाता है, तो LOCAL_MULTILIB := both का इस्तेमाल करके पक्का करें कि 32-बिट और 64-बिट, दोनों ODEX फ़ाइलें जनरेट की गई हों. अगर ऐप्लिकेशन में कोई 32-बिट या 64-बिट JNI लाइब्रेरी है, तो यह फ़्लैग, बिल्ड सिस्टम को उन्हें शामिल करने के लिए भी कहता है.