Сборка для 32-битных и 64-битных архитектур.

Система сборки поддерживает сборку бинарных файлов для двух целевых архитектур ЦП, 32-битной и 64-битной, в рамках одной сборки. Такая сборка для двух целевых платформ известна как многобиблиотечная сборка .

Для встроенных статических и разделяемых библиотек система сборки устанавливает правила для сборки бинарных файлов для обеих архитектур. Конфигурация продукта ( PRODUCT_PACKAGES ) вместе с графом зависимостей определяет, какие бинарные файлы будут собраны и установлены в образ системы.

Для исполняемых файлов и приложений система сборки по умолчанию собирает только 64-битную версию, но вы можете переопределить этот параметр с помощью глобальной переменной BoardConfig.mk или переменной, ограниченной областью действия модуля.

Определите вторую архитектуру ЦП и ABI.

BoardConfig.mk содержит следующие переменные для настройки архитектуры второго процессора и двоичного интерфейса приложения (ABI):

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Пример файла makefile, использующего эти переменные, можно найти в файле 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_ * , таких как 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_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_ARCH в сочетании с TARGET_2ND_ARCH для указания архитектуры системы предварительно собранных бинарных целевых объектов. Вместо этого используйте переменные LOCAL_ * LOCAL_MODULE_TARGET_ARCH или LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH .

Благодаря этим переменным система сборки может выбрать соответствующий 32-битный предварительно собранный бинарный файл, даже если она работает с 64-битной многобиблиотековой сборкой.

Если вы хотите использовать выбранную архитектуру для вычисления пути к исходному коду предварительно собранного бинарного файла, вызовите функцию $(get-prebuilt-src-arch) .

Обеспечьте генерацию ODEX-файлов в 32-битном и 64-битном режимах.

Для 64-битных устройств по умолчанию Google генерирует как 32-битные, так и 64-битные ODEX-файлы для образа загрузки и любых библиотек Java. Для APK-файлов по умолчанию Google генерирует ODEX-файлы только для основной 64-битной архитектуры. Если приложение запускается как в 32-битном, так и в 64-битном процессе, используйте LOCAL_MULTILIB := both , чтобы убедиться, что генерируются как 32-битные, так и 64-битные ODEX-файлы. Если приложение содержит какие-либо 32-битные или 64-битные библиотеки JNI, этот флаг также указывает системе сборки включить их.