AOSP Build Notes
Notes when working with AOSP
Last update: 2022-07-14
Table of Content
Bionic#
Bionic is an implementation of the standard C library, developed by Google for its Android operating system. It differs from the GNU C Library (glibc) in being designed for devices with less memory and processor power than a typical Linux system.
Bionic is a C library for use with the Linux kernel, and provides libc
, libdl
, and libm
(libpthread
functionality is part of libc
, not a separate library as on some other systems).
Repo: https://android.googlesource.com/platform/bionic/
Bionic only supports Linux kernels, but currently supports the arm
, arm64
, x86
, and x86-64
architectures.
inherit-product
#
In Makefiles, we usually see the command to inherit another product:
$(call inherit-product, <makefile.mk>)
# or
$(call inherit-product-if-exist, <makefile.mk>)
The function inherit-product
is defined in build/core/product.mk
:
#
# Functions for including product makefiles
#
# $(1): product to inherit
#
# To be called from product makefiles, and is later evaluated during the import-nodes
# call below. It does three things:
# 1. Inherits all of the variables from $1.
# 2. Records the inheritance in the .INHERITS_FROM variable
# 3. Records the calling makefile in PARENT_PRODUCT_FILES
#
# (2) and (3) can be used together to reconstruct the include hierarchy
# See e.g. product-graph.mk for an example of this.
#
define inherit-product
$(if $(findstring ../,$(1)),\
$(eval np := $(call normalize-paths,$(1))),\
$(eval np := $(strip $(1))))\
$(foreach v,$(_product_var_list), \
$(eval $(v) := $($(v)) $(INHERIT_TAG)$(np))) \
$(eval current_mk := $(strip $(word 1,$(_include_stack)))) \
$(eval inherit_var := PRODUCTS.$(current_mk).INHERITS_FROM) \
$(eval $(inherit_var) := $(sort $($(inherit_var)) $(np))) \
$(eval PARENT_PRODUCT_FILES := $(sort $(PARENT_PRODUCT_FILES) $(current_mk)))
endef
Let’s say you have:
PRODUCT_VAR := a
in A.mkPRODUCT_VAR := b
in B.mk
If you include
B.mk in_ A.mk_, you will get PRODUCT_VAR := b
at last.
If you inherit-product
B.mk in A.mk, you will getPRODUCT_VAR := a b
, note the order is a
then b
.
And inherit-product
makes sure that you won’t include a makefile twice because it Records that we’ve visited this node, in PARENT_PRODUCT_FILES
.
PRODUCT_COPY_FILES
#
When using inherit-product
, there are cases that a destination file is copied from many sources.
For example:
PRODUCT_COPY_FILES += \
/path/a.txt:/path/target.txt
$(call inherit-product, B.mk)
PRODUCT_COPY_FILES += \
/path/b.txt:/path/target.txt
After the inherit-product
call, the variable has been changed as:
PRODUCT_COPY_FILES += \
/path/a.txt:/path/target.txt \
/path/b.txt:/path/target.txt
The rule for PRODUCT_COPY_FILES
is:
only eval the copy rule if this src:dest
pair is the first one to match the same dest
.
Therefore, only the rule /path/a.txt:/path/target.txt
is evaluated.
The rules for PRODUCT_COPY_FILES
is defined in build/core/Makefile
:
build/core/Makefile
# -----------------------------------------------------------------
# Define rules to copy PRODUCT_COPY_FILES defined by the product.
# PRODUCT_COPY_FILES contains words like <source file>:<dest file>[:<owner>].
# <dest file> is relative to $(PRODUCT_OUT), so it should look like,
# e.g., "system/etc/file.xml".
# The filter part means "only eval the copy-one-file rule if this
# src:dest pair is the first one to match the same dest"
#$(1): the src:dest pair
#$(2): the dest
define check-product-copy-files
$(if $(filter-out $(TARGET_COPY_OUT_SYSTEM_OTHER)/%,$(2)), \
$(if $(filter %.apk, $(2)),$(error \
Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!)))
endef
# filter out the duplicate <source file>:<dest file> pairs.
unique_product_copy_files_pairs :=
$(foreach cf,$(PRODUCT_COPY_FILES), \
$(if $(filter $(unique_product_copy_files_pairs),$(cf)),,\
$(eval unique_product_copy_files_pairs += $(cf))))
unique_product_copy_files_destinations :=
product_copy_files_ignored :=
$(foreach cf,$(unique_product_copy_files_pairs), \
$(eval _src := $(call word-colon,1,$(cf))) \
$(eval _dest := $(call word-colon,2,$(cf))) \
$(call check-product-copy-files,$(cf),$(_dest)) \
$(if $(filter $(unique_product_copy_files_destinations),$(_dest)), \
$(eval product_copy_files_ignored += $(cf)), \
$(eval _fulldest := $(call append-path,$(PRODUCT_OUT),$(_dest))) \
$(if $(filter %.xml,$(_dest)),\
$(eval $(call copy-xml-file-checked,$(_src),$(_fulldest))),\
$(if $(and $(filter %.jar,$(_dest)),$(filter $(basename $(notdir $(_dest))),$(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))),\
$(eval $(call copy-and-uncompress-dexs,$(_src),$(_fulldest))), \
$(if $(filter init%rc,$(notdir $(_dest)))$(filter %/etc/init,$(dir $(_dest))),\
$(eval $(call copy-init-script-file-checked,$(_src),$(_fulldest))),\
$(eval $(call copy-one-file,$(_src),$(_fulldest)))))) \
$(eval unique_product_copy_files_destinations += $(_dest))))
# Dump a list of overriden (and ignored PRODUCT_COPY_FILES entries)
pcf_ignored_file := $(PRODUCT_OUT)/product_copy_files_ignored.txt
$(pcf_ignored_file): PRIVATE_IGNORED := $(sort $(product_copy_files_ignored))
$(pcf_ignored_file):
echo "$(PRIVATE_IGNORED)" | tr " " "\n" >$@
$(call dist-for-goals,droidcore,$(pcf_ignored_file):logs/$(notdir $(pcf_ignored_file)))
pcf_ignored_file :=
product_copy_files_ignored :=
unique_product_copy_files_pairs :=
unique_product_copy_files_destinations :=