Система сборки поддерживает сборку двоичных файлов для двух целевых архитектур ЦП (64-разрядной и 32-разрядной) в одной сборке. Это называется мультибиблиотечной сборкой .
Для собственных статических библиотек и общих библиотек система сборки устанавливает правила для сборки двоичных файлов для обеих архитектур. Конфигурация продукта ( PRODUCT_PACKAGES
) вместе с графом зависимостей определяет, какие двоичные файлы собираются и устанавливаются в образ системы.
Для исполняемых файлов и приложений система сборки по умолчанию создает только 64-разрядную версию, но вы можете переопределить этот параметр с помощью глобальной переменной BoardConfig.mk
или переменной области модуля.
Конфигурация продукта
BoardConfig.mk
включает следующие переменные для настройки архитектуры второго процессора и 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
.
В сборке с несколькими библиотеками имена модулей в PRODUCT_PACKAGES
охватывают как 32-разрядные, так и 64-разрядные двоичные файлы, если они определены системой сборки. Для библиотек, подключенных по зависимости, 32-разрядная библиотека устанавливается только в том случае, если она требуется для другой 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
.
Установите 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
.
В сборке с несколькими библиотеками вместо этого используйте 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
), чтобы сообщить системе сборки, на какую архитектуру нацелен предварительно созданный двоичный файл. Вместо этого используйте переменные LOCAL_
LOCAL_MODULE_TARGET_ARCH
или LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
С помощью этих переменных система сборки может выбрать соответствующий 32-разрядный предварительно собранный двоичный файл, даже если он работает с 64-разрядной мультибиблиотечной сборкой.
Если вы хотите использовать выбранную архитектуру для вычисления исходного пути для предварительно созданного двоичного файла, вызовите $(get-prebuilt-src-arch)
.
Генерация файла ODEX
Для 64-битных устройств по умолчанию мы генерируем как 32-битные, так и 64-битные файлы ODEX для загрузочного образа и любых библиотек Java. Для APK по умолчанию мы генерируем ODEX только для основной 64-битной архитектуры. Если приложение будет запускаться как в 32-разрядных, так и в 64-разрядных процессах, используйте LOCAL_MULTILIB := both
, чтобы убедиться, что создаются как 32-разрядные, так и 64-разрядные файлы ODEX. Если в приложении есть какие-либо 32-разрядные или 64-разрядные библиотеки JNI, этот флаг также указывает системе сборки включить их.