آشنایی با سازه های 64 بیتی

سیستم ساخت از ساخت باینری ها برای دو معماری CPU هدف (64 بیت و 32 بیت) در یک ساخت پشتیبانی می کند. این به عنوان یک ساخت multilib شناخته می شود.

برای کتابخانه‌های استاتیک بومی و کتابخانه‌های مشترک، سیستم ساخت قوانینی را برای ساختن باینری‌ها برای هر دو معماری تنظیم می‌کند. پیکربندی محصول ( PRODUCT_PACKAGES )، همراه با نمودار وابستگی، تعیین می کند که کدام باینری ها در تصویر سیستم ساخته و نصب شوند.

برای فایل های اجرایی و برنامه ها، سیستم ساخت تنها نسخه 64 بیتی را به طور پیش فرض ایجاد می کند، اما می توانید این تنظیم را با یک متغیر جهانی BoardConfig.mk یا یک متغیر با محدوده ماژول لغو کنید.

پیکربندی محصول

BoardConfig.mk شامل متغیرهای زیر برای پیکربندی معماری CPU دوم و ABI است:

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

می توانید یک نمونه را در build/target/board/generic_arm64/BoardConfig.mk کنید.

در ساخت multilib، نام ماژول ها در PRODUCT_PACKAGES هر دو باینری 32 بیتی و 64 بیتی را پوشش می دهند، تا زمانی که توسط سیستم ساخت تعریف شده باشند. برای کتابخانه‌هایی که با وابستگی وارد می‌شوند، یک کتابخانه 32 بیتی فقط در صورتی نصب می‌شود که توسط یک کتابخانه 32 بیتی دیگر یا قابل اجرا مورد نیاز باشد. همین امر در مورد کتابخانه های 64 بیتی نیز صادق است.

با این حال، نام ماژول در خط فرمان make فقط نسخه 64 بیتی را پوشش می دهد. به عنوان مثال، پس از اجرای lunch aosp_arm64-eng ، make libc فقط libc 64 بیتی را می سازد. برای ساختن libc 32 بیتی، باید make libc_32 اجرا کنید.

تعریف ماژول در Android.mk

می توانید از متغیر LOCAL_MULTILIB برای پیکربندی ساخت خود برای 32 بیت/64 بیت و نادیده گرفتن متغیر جهانی TARGET_PREFER_32_BIT استفاده کنید.

LOCAL_MULTILIB را روی یکی از موارد زیر تنظیم کنید:

  • "both" هم 32 بیتی و هم 64 بیتی را می سازد.
  • "32" فقط 32 بیت می سازد.
  • "64" فقط 64 بیت می سازد.
  • "first" فقط برای اولین معماری ساخته می شود (32 بیت در دستگاه های 32 بیتی و 64 بیت در دستگاه های 64 بیتی).
  • "" پیش فرض است. سیستم ساخت بر اساس کلاس ماژول و سایر متغیرهای 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 است. اگر معماری در حال ساخت در آن لیست نباشد ، ماژول فعلی توسط سیستم ساخت گنجانده شده است.

انواع کوچکی از این دو متغیر وجود دارد:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

اگر ماژول فعلی به دلیل معماری های ذکر شده نادیده گرفته شود، سیستم ساخت هشدار می دهد.

برای تنظیم پرچم‌های ساخت برای یک معماری خاص، از متغیرهای LOCAL_ خاص معماری استفاده کنید. یک متغیر LOCAL_ خاص معماری، یک متغیر 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 .

در ساخت multilib، به جای آن از 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
    مسیر نصب را مشخص می کند.

منابع تولید شده

در یک ساخت multilib، اگر فایل‌های منبع را در $(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 ) استفاده کنید تا به سیستم بیلد بگویید که باینری از پیش ساخته شده چه معماری را هدف قرار می‌دهد. در عوض، از متغیرهای LOCAL_ LOCAL_MODULE_TARGET_ARCH یا LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH استفاده کنید.

با این متغیرها، سیستم ساخت می‌تواند باینری از پیش ساخته شده 32 بیتی مربوطه را انتخاب کند، حتی اگر روی یک ساخت چندلیبی 64 بیتی کار کند.

اگر می خواهید از معماری انتخاب شده برای محاسبه مسیر منبع برای باینری از پیش ساخته شده استفاده کنید، $(get-prebuilt-src-arch) فراخوانی کنید.

تولید فایل ODEX

برای دستگاه‌های 64 بیتی، به‌طور پیش‌فرض، فایل‌های ODEX 32 بیتی و 64 بیتی را برای تصویر بوت و هر کتابخانه جاوا تولید می‌کنیم. برای فایل‌های APK، به‌طور پیش‌فرض، ما ODEX را فقط برای معماری 64 بیتی اولیه تولید می‌کنیم. اگر برنامه ای در هر دو فرآیند 32 بیتی و 64 بیتی راه اندازی می شود، از LOCAL_MULTILIB := both استفاده کنید تا مطمئن شوید که فایل های ODEX 32 بیتی و 64 بیتی تولید می شوند. اگر برنامه دارای کتابخانه‌های JNI 32 بیتی یا 64 بیتی باشد، آن پرچم به سیستم ساخت می‌گوید که آنها را نیز شامل شود.