Re: New variables and macros of make system in android 64/32-bit build

1,769 views
Skip to first unread message

Ying Wang

unread,
Mar 2, 2015, 1:56:00 PM3/2/15
to Brian Carlstrom, Android Building, Madan Ankapura, andro...@googlegroups.com, Kevin Kim, Torne (Richard Coles)
The 64-bit build instructions are now on source.android.com website:

On Wed, Sep 3, 2014 at 12:50 PM, Ying Wang <wang...@android.com> wrote:
Yes, the build system's documentation needs a major revamp.
It has been on my radar for long time. I'll do it when I get some free cycles.

As for the multilib build, thanks for Amit's good summary!
Here is the document mentioned by Torne. It's certain there must be something missing. Also new things have been added since I wrote it.


From the build system’s perspective, the most prominent change is that now it supports building binaries for two target CPU architectures (64-bit and 32-bit) in the same build. That’s also known as multilib build.

For native static libraries and shared libraries, the build system sets up rules to build for both architectures. The product configuration (PRODUCT_PACKAGES) together with the dependency graph decides what binaries will be built and installed to the system image.

For executables, by default the build system builds only the 64-bit version, but it can be overridden by a global BoardConfig.mk variable or a module-scoped variable.


As of 2014/05/15, host 64-bit multilib build is also supported. In 64-bit multilib build, HOST_ARCH is x86_64 and the HOST_2ND_ARCH is x86. By default we only build for the first arch. You can use the LOCAL variables described below to change the default behavior.

Product Configuration

In BoardConfig.mk, we added the following variables to configure the second CPU architecture and ABI:

TARGET_2ND_ARCH

TARGET_2ND_ARCH_VARIANT

TARGET_2ND_CPU_VARIANT

TARGET_2ND_CPU_ABI

TARGET_2ND_CPU_ABI2

You can see an example in build/target/board/generic_arm64/BoardConfig.mk

If you want the build system to build 32-bit executables by default, set:

TARGET_PREFER_32_BIT := true

However it can be overridden by module-specific variables in Android.mks.


In multilib build module names in PRODUCT_PACKAGES cover both the 32-bit and 64-bit binaries, if they are defined by the build system. For libraries pulled in by dependency, a 32-bit library is only installed if it’s required by a 32-bit library or executable. The same is true for 64-bit libraries.

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”.


Module Definition in Android.mk

You can use the following two variables to build just for 32-bit or 64-bit and override the global TARGET_PREFER_32_BIT:

- LOCAL_32_BIT_ONLY

  set to “true” if you want to build a module only for 32-bit.

- LOCAL_MULTILIB, which can replace LOCAL_32_BIT_ONLY and LOCAL_NO_2ND_ARCH

  “both”: build both 32-bit and 64-bit;

  “32”: build only 32-bit, the same as “LOCAL_32_BIT_ONLY := true”;

  “64”: build only 64-bit;

  “first”: build for only the first arch, the same as “LOCAL_NO_2ND_ARCH := true”

   “”: the default; the build system decides what arch to build based on the module class and other LOCAL_ variables, such as LOCAL_MODULE_TARGET_ARCH, LOCAL_32_BIT_ONLY, etc.  



In multilib build, conditionals like “ifeq $(TARGET_ARCH)” usually don’t work any more.

If you want to build your module for some specific arch(s), the following variables can help you:

- LOCAL_MODULE_TARGET_ARCH

 It can be set to a list of archs, something like “arm x86 arm64”. Only if the arch being built is among that list will the current module be included by the build system.



- LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH

 The opposite of LOCAL_MODULE_TARGET_ARCH. Only if the arch being built is not among the list, the current module will be included.

There are minor variants of the above two variables:

LOCAL_MODULE_TARGET_ARCH_WARN

LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

The build system will give warning if the current module is skipped due to archs limited by them.



To set up arch-specific build flags, use the arch-specific LOCAL_ variables. An arch-specific LOCAL_ variable is a normal LOCAL_ variable with an arch suffix, for example:

LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,

LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,

LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,

etc.

Those variables will be applied only if it’s currently being built for that arch.


Sometimes it’s more convenient to set up flags just based on whether it’s currently being built for 32-bit or 64-bit. In that case you can 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,

etc.


Note that not all of the LOCAL_ variables support the arch-specific variants. For an up-to-date list of such variables, refer to build/core/clear_vars.mk.


Install path

Previously you can use LOCAL_MODULE_PATH to install a library to a location other than the default one. For example:

LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw

In multilib build, use LOCAL_MODULE_RELATIVE_PATH instead:

LOCAL_MODULE_RELATIVE_PATH := hw

so both the 64-bit and 32-bit libraries can be installed to the right place.

If you build an executable as both 32-bit and 64-bit, you’ll need to use one of the following variables to distinguish the install path:

LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64: they specify the installed file name;

LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64: they specify the install path.


Generated sources

In multilib build if you generate source files to $(local-intermediates-dir) (or $(intermediates-dir-for) with explicit variables), it usually won’t work any more. That’s because the generated sources will be required by both 32-bit and 64-bit build, but $(local-intermediates-dir) only points to one of the two intermediate directories.

The build system now provides a dedicated, multilib-friendly intermediate directory for generating sources. You can call $(local-generated-sources-dir) or $(generated-sources-dir-for) to get the directory’s path. Their usages are similar to $(local-intermediates-dir) and $(intermediates-dir-for).

If a source file is generated to the new dedicated directory and picked up by LOCAL_GENERATED_SOURCES, it will be built for both 32-bit and 64-bit in multilib build.



Prebuilts

In multilib you can’t use TARGET_ARCH (or together with TARGET_2ND_ARCH) to tell the build system what arch the prebuilt is targeted for. Use the aforementioned LOCAL_ variable LOCAL_MODULE_TARGET_ARCH or LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH instead.

With these variables, the build system can choose the corresponding 32-bit prebuilt even if it’s currently doing a 64-bit multilib build.

If you want to use the chosen arch to calculate the source path for the prebuilt, you can call $(get-prebuilt-src-arch).



On Mon, Sep 1, 2014 at 10:52 PM, 'Brian Carlstrom' via android-64 <andro...@googlegroups.com> wrote:
The problem is that it is out of date, not where it is published.

-bri

On Mon, Sep 1, 2014 at 10:11 PM, Madan Ankapura <mank...@google.com> wrote:
> Can be published on source.android. com if needed ...
>
> On Sep 1, 2014 9:25 PM, "'Brian Carlstrom' via android-64"
> <andro...@googlegroups.com> wrote:
>>
>> presumably build/core/build-system.html needs to be updated.
>>
>> -bri
>>
>> On Mon, Sep 1, 2014 at 4:20 AM, 'Torne (Richard Coles)' via android-64
>> <andro...@googlegroups.com> wrote:
>> > There's an internal document which describes these variables in detail
>> > with
>> > migration suggestions (by wangying@) - we should probably tidy it up and
>> > publish it somewhere, as it's useful to anyone migrating to 64-bit
>> > support?
>> >
>> >
>> > On 1 September 2014 12:18, Kevin Kim <liket...@gmail.com> wrote:
>> >>
>> >> Hi, Mr. Pundir,
>> >>
>> >> I really appreciate your prompt and detailed reply.
>> >> It contains useful information and helps me very much.
>> >>
>> >> Regards & thanks,
>> >> Kevin Kim
>> >>
>> >>
>> >> On Monday, September 1, 2014 4:48:35 PM UTC+9, Amit Pundir wrote:
>> >>>
>> >>> On 1 September 2014 12:54, Kevin Kim <liket...@gmail.com> wrote:
>> >>> > Hi all,
>> >>> >
>> >>> > In android-L 64/32-bit build environment,  there are kind of newly
>> >>> > introduced variables like
>> >>> > LOCAL_MULTILIB, LOCAL_32_BIT_ONLY, LOCAL_MODULE_TARGET_ARCH, and so
>> >>> > on.
>> >>> >
>> >>> > Could anyone let me know the information precisely about all kind of
>> >>> > newly
>> >>> > introduced variables and macros ?
>> >>>
>> >>> Hi, I may not have the complete list of such variables but this is
>> >>> what I have based on my understanding of AOSP logs. It may not be an
>> >>> up-to-date list either since I have not looked into the recent changes
>> >>> for a while now.
>> >>>
>> >>> Device Config changes:
>> >>> ------------------------------------
>> >>> Primary Arch: TARGET_ARCH and TARGET_CPU_* variables defined as usual.
>> >>> TARGET_ARCH := arm64
>> >>> TARGET_ARCH_VARIANT := armv8-a
>> >>> TARGET_CPU_VARIANT := generic
>> >>> TARGET_CPU_ABI := arm64-v8a
>> >>>
>> >>> Secondary Arch: This is the first step to build 32-bit libraries in a
>> >>> 64-bit product. The build system uses TARGET_2ND_* variables to set up
>> >>> an additional compiler environment for the second arch.
>> >>> TARGET_2ND_ARCH := arm
>> >>> TARGET_2ND_ARCH_VARIANT := armv7-a-neon
>> >>> TARGET_2ND_CPU_VARIANT := cortex-a15
>> >>> TARGET_2ND_CPU_ABI := armeabi-v7a
>> >>> TARGET_2ND_CPU_ABI2 := armeabi
>> >>>
>> >>> Set "TARGET_USES_64_BIT_BINDER" to use 64bit binder IPC on ARMv8. Make
>> >>> sure this variable is set to true even if you are doing a 32bit only
>> >>> Android builds for ARMv8.
>> >>>
>> >>> Multilib Support: Set "TARGET_SUPPORTS_32_BIT_APPS" and
>> >>> "TARGET_SUPPORTS_64_BIT_APPS" to determine which native libraries to
>> >>> build for an app.  If both are set, it will use 64-bit unless
>> >>> "TARGET_PREFER_32_BIT" is set. If only one is set, it will only build
>> >>> apps that work on that architecture.  If neither is set it will fall
>> >>> back to only building 32-bit apps.
>> >>>
>> >>> Zygote init config is not a part of init.rc anymore. init.rc include
>> >>> “init.${ro.zygote}.rc” at runtime and do Zygote bringup. 64bit Zygote
>> >>> is the "primary" and 32bit Zygote is the “secondary”. The system
>> >>> server will run as a 64 bit process.
>> >>> zygote --> /system/bin/app_process64 --> To kick start 64bit VM
>> >>> zygote_secondary --> /system/bin/app_process32 --> To kick start 32bit
>> >>> VM
>> >>>
>> >>> PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote64_32
>> >>> PRODUCT_COPY_FILES +=
>> >>> system/core/rootdir/init.zygote64_32.rc:root/init.zygote64_32.rc
>> >>> ------------------------------------
>> >>>
>> >>>
>> >>> Building An Android Module With Multilib Support:
>> >>> ------------------------------------
>> >>> Set "LOCAL_MULTILIB := first" to always build a module for the first
>> >>> architecture (64-bit on a 64-bit target, 32-bit on a 32-bit target).
>> >>>
>> >>> Set "LOCAL_MULTILIB := 32" to always build a module 32-bit. This is
>> >>> the same as specifying LOCAL_32_BIT_ONLY.
>> >>>
>> >>> If "LOCAL_MULTILIB := 64" is set then package.mk will use it to only
>> >>> install 64-bit native apps on devices that only have a 64-bit zygote.
>> >>>
>> >>> Set "LOCAL_MULTILIB := both" to build for both architectures on a
>> >>> mulitlib (64-bit) target. If LOCAL_MULTILIB is not set libraries will
>> >>> default to "both", and executables, packages, and prebuilts will
>> >>> default to building for the first architecture if supported by the
>> >>> module, otherwise the second. /system/lib always contain 32-bit
>> >>> libraries, and /system/lib64 will always have 64-bit libraries. Some
>> >>> executables will need to be built for both 32-bit and 64-bit as well
>> >>> i.e. "LOCAL_MULTILIB := both". For linker/linker64,
>> >>> debuggerd/debuggerd64, and a few more, they will be installed in the
>> >>> same path (/system/bin), but with different filenames. Set
>> >>> "LOCAL_MODULE_STEM_32" and "LOCAL_MODULE_STEM_64" to name the two
>> >>> versions.
>> >>>
>> >>> Set arch-specific local flags, LOCAL_*_$(TARGET_ARCH) and
>> >>> LOCAL_*_$(TARGET_2ND_ARCH) e.g. LOCAL_CFLAGS_arm64,
>> >>> LOCAL_SRC_FILES_arm, etc etc
>> >>>
>> >>> Set "LOCAL_MODULE_RELATIVE_PATH" in multilib builds to set the install
>> >>> location instead of "LOCAL_MODULE_PATH". In multilib builds the
>> >>> install location depends on the arch. HALs will generally use:
>> >>> "LOCAL_MODULE_RELATIVE_PATH := hw"
>> >>>
>> >>> "LOCAL_MODULE_TARGET_ARCH" specifies that a module is only supported
>> >>> for one or more architectures.  Any architecture not in the list will
>> >>> not attempt to build the module.  The expected use case is prebuilts
>> >>> that are only suitable for a single architecture, or modules like llvm
>> >>> that need per-architecture support.
>> >>> "LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH" specifies that a module cannot
>> >>> be built for one or more architectures.
>> >>> "LOCAL_MODULE_TARGET_ARCH_WARN" and
>> >>> "LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN" are the same, but warn
>> >>> that the arch is not supported, which is useful for modules that are
>> >>> critical but not yet working.
>> >>>
>> >>> If "TARGET_PREFER_32_BIT" is set then it needs to try the 32-bit build
>> >>> rule first, then fall back to the 64-bit rule in case the module
>> >>> specifies "LOCAL_MODULE_TARGET_ARCH" or
>> >>> "LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH" to disallow the 32-bit build.
>> >>>
>> >>> Multilib build example in AOSP:
>> >>>
>> >>>
>> >>> https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/Android.mk
>> >>> ------------------------------------
>> >>>
>> >>>
>> >>> Regards,
>> >>> Amit Pundir
>> >>>
>> >>> >
>> >>> > regards,
>> >>> > Kevin Kim
>> >>> >
>> >>> > --
>> >>> > You received this message because you are subscribed to the Google
>> >>> > Groups
>> >>> > "android-64" group.
>> >>> > To unsubscribe from this group and stop receiving emails from it,
>> >>> > send
>> >>> > an
>> >>> > email to android-64+...@googlegroups.com.
>> >>> > For more options, visit https://groups.google.com/d/optout.
>> >>
>> >> --
>> >> You received this message because you are subscribed to the Google
>> >> Groups
>> >> "android-64" group.
>> >> To unsubscribe from this group and stop receiving emails from it, send
>> >> an
>> >> email to android-64+...@googlegroups.com.
>> >> For more options, visit https://groups.google.com/d/optout.
>> >
>> >
>> >
>> >
>> > --
>> > Torne (Richard Coles)
>> > to...@google.com
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "android-64" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an
>> > email to android-64+...@googlegroups.com.
>> > For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "android-64" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to android-64+...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "android-64" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-64+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Reply all
Reply to author
Forward
0 new messages