The build system supports building binaries for two target CPU architectures, 32 bit and 64 bit, in the same build. This two-target build is known as a multilib build.
For built-in static libraries and shared libraries, the build system sets up
rules to build binaries for both architectures. The product configuration
(PRODUCT_PACKAGES
), together with the dependency graph, determines which
binaries are built and installed to the system image.
For executables and apps, the build system builds only the 64-bit version by
default, but you can override this setting with a global
BoardConfig.mk
variable or a module-scoped variable.
Identify a second CPU architecture and ABI
BoardConfig.mk
includes the following variables to configure the second CPU
architecture and application binary interface (ABI):
TARGET_2ND_ARCH
TARGET_2ND_ARCH_VARIANT
TARGET_2ND_CPU_VARIANT
TARGET_2ND_CPU_ABI
TARGET_2ND_CPU_ABI2
For an example makefile that uses these variables, see
build/make/target/board/generic_arm64/BoardConfig.mk
.
In a multilib build, module names in PRODUCT_PACKAGES
cover
both the 32-bit and 64-bit binaries, as long as they're defined by the build
system. For libraries included by dependency, a 32-bit or 64-bit library is
installed only if it's required by another 32-bit or 64-bit library or
executable.
However, module names on the make
command line cover only the
64-bit version. For example, after running lunch aosp_arm64-eng
,
make libc
builds only the 64-bit libc. To
build the 32-bit libc, you need to run make libc_32
.
Define module architecture in Android.mk
You can use the LOCAL_MULTILIB
variable to configure your build
for 32 bit and 64 bit and override the global TARGET_PREFER_32_BIT
variable.
To override TARGET_PREFER_32_BIT
, set LOCAL_MULTILIB
to one of the
following:
both
builds both 32 bit and 64 bit.32
builds only 32 bit.64
builds only 64 bit.first
builds for only the first architecture (32 bit in 32-bit devices and 64 bit in 64-bit devices).
By default, LOCAL_MULTILIB
isn't set and the build system decides which
architecture to build based on the module class and other
LOCAL_*
variables, such as LOCAL_MODULE_TARGET_ARCH
and LOCAL_32_BIT_ONLY
.
If you want to build your module for specific architectures, use the following variables:
LOCAL_MODULE_TARGET_ARCH
- Set this variable to a list of architectures, such asarm x86 arm64
. If the architecture being built is in that list, the current module is included by the build system.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
- This variable is the opposite ofLOCAL_MODULE_TARGET_ARCH
. If the architecture being built isnot
in that list, the current module is included by the build system.
There are minor variants of these two variables:
LOCAL_MODULE_TARGET_ARCH_WARN
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
The build system warns if the current module is skipped because of the architectures listed.
To set up build flags for a particular architecture, use the
architecture-specific LOCAL_*
variables where
*
is an architecture-specific suffix, for example:
LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,
These variables are applied only if a binary is being built for that architecture.
Sometimes it's easier to set up flags based on whether the binary is
being built for 32-bit or 64-bit. Use the LOCAL_*
variable with a _32
or _64
suffix, for example:
LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,
Set library installation path
For a non-multilib build, you can use LOCAL_MODULE_PATH
to install a library
to a location other than the default location. For example,
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
.
However, in a multilib build, use LOCAL_MODULE_RELATIVE_PATH
instead:
LOCAL_MODULE_RELATIVE_PATH := hw
With this format, both the 64-bit and 32-bit libraries are installed in the correct location.
If you build an executable as both 32 bit and 64 bit, use one of the following variables to distinguish the install path:
LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64
- Specifies the installed filename.LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
- Specifies the install path.
Obtain intermediate directory for source files
In a multilib build, if you generate source files to
$(local-intermediates-dir)
(or $(intermediates-dir-for)
with explicit variables), it doesn't work reliably. That's
because the intermediate generated sources are required by both the 32-bit and
64-bit builds, but $(local-intermediates-dir)
points to only one of
the two intermediate directories.
The build system provides a dedicated, multilib-friendly,
intermediate directory for generating sources. To retrieve the intermediate
directory's path, use the
$(local-generated-sources-dir)
or
$(generated-sources-dir-for)
macro. The uses of these macros are similar to
$(local-intermediates-dir)
and $(intermediates-dir-for)
.
If a source file is generated to this dedicated directory and picked up
by LOCAL_GENERATED_SOURCES
, it's built for both 32 bit and 64 bit
in a multilib build.
Indicate system architecture of prebuilt binary targets
In a multilib build, you can't use TARGET_ARCH
, or TARGET_ARCH
combined with
TARGET_2ND_ARCH
, to indicate the system architecture of the prebuilt
binary targets. Instead, use the LOCAL_*
variables
LOCAL_MODULE_TARGET_ARCH
or
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
With these variables, the build system can choose the corresponding 32-bit prebuilt binary even if it's working on a 64-bit multilib build.
If you want to use the chosen architecture to compute the source path for the
prebuilt binary, call $(get-prebuilt-src-arch)
.
Ensure 32-bit and 64-bit ODEX file generation
For 64-bit devices, by default Google generates both 32-bit and 64-bit ODEX
files for the boot image and any Java libraries. For APKs, by default Google
generates ODEX only for the primary 64-bit architecture. If an app is launched
in both 32-bit and 64-bit processes, use LOCAL_MULTILIB := both
to make sure
that both 32-bit and 64-bit ODEX files are generated. If the app has any 32-bit
or 64-bit JNI libraries, that flag also tells the build system to include them.