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 बिट के लिए अपना बिल्ड कॉन्फ़िगर किया जा सकता है. साथ ही, ग्लोबल LOCAL_MULTILIB वैरिएबल को बदला जा सकता है.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_* वैरिएबल के आधार पर, किस आर्किटेक्चर को बिल्ड करना है. जैसे, LOCAL_MODULE_TARGET_ARCH और LOCAL_32_BIT_ONLY.

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

  • 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_*, आर्किटेक्चर के हिसाब से सफ़िक्स है. उदाहरण के लिए:*

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

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

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

  • 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_ARCH के साथ TARGET_2ND_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 फ़ाइलें जनरेट करता है. एपीके के लिए, Google डिफ़ॉल्ट रूप से सिर्फ़ मुख्य 64-बिट आर्किटेक्चर के लिए ओडीईएक्स जनरेट करता है. अगर किसी ऐप्लिकेशन को 32-बिट और 64-बिट, दोनों प्रोसेस में लॉन्च किया जाता है, तो LOCAL_MULTILIB := both का इस्तेमाल करके यह पक्का करें कि 32-बिट और 64-बिट, दोनों ओडीईएक्स फ़ाइलें जनरेट की गई हैं. अगर ऐप्लिकेशन में कोई 32-बिट या 64-बिट JNI लाइब्रेरी है, तो यह फ़्लैग बिल्ड सिस्टम को उन्हें शामिल करने के लिए भी कहता है.