您的位置:首页 > 产品设计 > UI/UE

Android build System

2010-07-13 14:27 260 查看

[First written by Steve Guo, please keep the mark if
forwarding.]

Device/docs/design/build-system.html
is a good start point to understand Android build system. In this
topic, I will describe the behind details using mm to compile an
executable and shared library.

Basic

In envsetup.sh
, mm macro is defined.

function mm()

{

# If we're sitting in the root of the build tree, just do a

# normal make.

if [ -f config/envsetup.make -a -f Makefile ]; then

make $@

else

# Find the closest Android.mk file.

T=$(gettop)

M=$(findmakefile)

if [ ! "$T" ]; then

echo "Couldn't locate the top of the tree.
Try setting TOP."

elif [ ! "$M" ]; then

echo "Couldn't locate a makefile from the current directory."

else

ONE_SHOT_MAKEFILE=$M make -C $T files $@

fi

fi

}

In top layer Makefile

ifneq ($(
ONE_SHOT_MAKEFILE
),)

# We've probably been
invoked by the "mm" shell function

# with a
subdirectory's makefile.

include
$(ONE_SHOT_MAKEFILE)

# Change
CUSTOM_MODULES to include only modules that were

# defined by this
makefile; this will install all of those

# modules as a
side-effect.
Do this after including ONE_SHOT_MAKEFILE

# so that the modules
will be installed in the same place they

# would have been
with a normal make.

CUSTOM_MODULES :=
$(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS),))

FULL_BUILD :=

INTERNAL_DEFAULT_DOCS_TARGETS
:=

# Stub out the notice
targets, which probably aren't defined

# when using
ONE_SHOT_MAKEFILE.

NOTICE-HOST-%: ;

NOTICE-TARGET-%: ;

So
if we type mm in a directory, it will finally include our own
Android.mk. Android will put every Android.mk into one huge Makefile.

In top layer Makefile, it includes base_rules.make
, while in base_rules.make it defines a target for LOCAL_MODULE which
must be specified in our own Android.mk.

# Provide a
short-hand for building this module.

# We name both BUILT
and INSTALLED in case

#
LOCAL_UNINSTALLABLE_MODULE is set.

.PHONY:
$(LOCAL_MODULE)

$(LOCAL_MODULE):
$(LOCAL_BUILT_MODULE) $(LOCAL_INSTALLED_MODULE)

definitions.make

contains the most important macros for building
source file. Here lists the two macros for building C++ and C source
files.

###########################################################

## Commands for
running gcc to compile a C++ file

###########################################################

define transform-cpp-to-o

@mkdir -p $(dir $@)

@echo "target
$(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"

$(hide)
$(PRIVATE_CXX) /

$(foreach incdir, /

$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, /

$(TARGET_PROJECT_INCLUDES) /

$(TARGET_C_INCLUDES) /

) /

$(PRIVATE_C_INCLUDES) /

, /

-I $(incdir) /

) /

-c /

$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, /

$(TARGET_GLOBAL_CFLAGS) /

$(TARGET_GLOBAL_CPPFLAGS) /

$(PRIVATE_ARM_CFLAGS) /

) /

$(PRIVATE_CFLAGS) /

$(PRIVATE_CPPFLAGS) /

$(PRIVATE_DEBUG_CFLAGS) /

-fno-rtti /

-MD -o $@ $<

$(hide)
$(transform-d-to-p)

endef

###########################################################

## Commands for
running gcc to compile a C file

###########################################################

# $(1): extra flags

define
transform-c-or-s-to-o-no-deps

@mkdir -p $(dir $@)

$(hide) $(PRIVATE_CC)
/

$(foreach incdir, /

$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, /

$(TARGET_PROJECT_INCLUDES) /

$(TARGET_C_INCLUDES) /

) /

$(PRIVATE_C_INCLUDES) /

, /

-I $(incdir) /

) /

-c /

$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, /

$(TARGET_GLOBAL_CFLAGS) /

$(PRIVATE_ARM_CFLAGS) /

) /

$(PRIVATE_CFLAGS) /

$(1) /

$(PRIVATE_DEBUG_CFLAGS) /

-MD -o $@ $<

endef

Executable

In our own Android.mk we should add two lines.

LOCAL_MODULE := ***

include
$(BUILD_EXECUTABLE)

BUILD_EXECUTALE is defined in config.make
.

BUILD_EXECUTABLE:=
$(BUILD_SYSTEM)/executable.make

In executable.make

include
$(BUILD_SYSTEM)/dynamic_binary.make

ifeq
($(LOCAL_FORCE_STATIC_EXECUTABLE),true)

$(linked_module):
$(TARGET_CRTBEGIN_STATIC_O) $(all_objects) $(all_libraries)
$(TARGET_CRTEND_O)

$(transform-o-to-static-executable)

else

$(linked_module):
$(TARGET_CRTBEGIN_DYNAMIC_O) $(all_objects) $(all_libraries)
$(TARGET_CRTEND_O)

$(transform-o-to-executable)

Endif

So here defined a new target $(linked_module).

transform-o-to-exeuctable macro is defined in defintions.make
.

define
transform-o-to-executable

@mkdir -p $(dir $@)

@echo "target
Executable: $(PRIVATE_MODULE) ($@)"

$(hide)
$(transform-o-to-executable-inner)

endef

combo/linux-arm.make

contains macros to transform o to executable for
ARM.

define
transform-o-to-executable-inner

$(TARGET_CXX)
-nostdlib -Bdynamic -Wl,-T,$(BUILD_SYSTEM)/armelf.x /

-Wl,-dynamic-linker,/system/bin/linker /

-Wl,--gc-sections /

-Wl,-z,nocopyreloc /

-o $@ /

$(TARGET_GLOBAL_LD_DIRS) /

-Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) /

$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) /

$(TARGET_CRTBEGIN_DYNAMIC_O) /

$(PRIVATE_ALL_OBJECTS) /

$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) /

$(PRIVATE_LDFLAGS) /

$(TARGET_LIBGCC) /

$(TARGET_CRTEND_O)

endef

binary.make

contains some PRIVATE_* definitions used by the
above macros.

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_ASFLAGS := $(LOCAL_ASFLAGS)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_CFLAGS := $(LOCAL_CFLAGS)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_CPPFLAGS := $(LOCAL_CPPFLAGS)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_DEBUG_CFLAGS := $(debug_cflags)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_LDFLAGS := $(LOCAL_LDFLAGS)

$(LOCAL_INTERMEDIATE_TARGETS):
PRIVATE_LDLIBS := $(LOCAL_LDLIBS)

combo/linux-arm.make

contains default CFLAGS/CPPFLAGS/C_INCLUDES
definitions.

$(combo_target)GLOBAL_CFLAGS
+= /

-march=armv5te -mtune=xscale /

-msoft-float -fpic /

-mthumb-interwork /

-ffunction-sections /

-funwind-tables /

-fstack-protector /

-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ /

-D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ /

-include include/arch/linux-arm/AndroidConfig.h

$(combo_target)GLOBAL_CPPFLAGS
+= -fvisibility-inlines-hidden

$(combo_target)RELEASE_CFLAGS
:= /

-DSK_RELEASE -DNDEBUG /

-O2 -g /

-Wstrict-aliasing=2 /

-finline-functions /

-fno-inline-functions-called-once /

-fgcse-after-reload /

-frerun-cse-after-loop /

-frename-registers

# unless
CUSTOM_KERNEL_HEADERS is defined, we're going to use

# symlinks located in
out/ to point to the appropriate kernel

# headers. see
'config/kernel_headers.make' for more details

#

KERNEL_HEADERS_COMMON
:= system/bionic/kernel/common

KERNEL_HEADERS_ARCH

:= system/bionic/kernel/arch-$(TARGET_ARCH)

ifneq
($(CUSTOM_KERNEL_HEADERS),)

KERNEL_HEADERS_COMMON := $(CUSTOM_KERNEL_HEADERS)

KERNEL_HEADERS_ARCH
:= $(CUSTOM_KERNEL_HEADERS)

endif

KERNEL_HEADERS :=
$(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)

$(combo_target)C_INCLUDES
:= /

system/bionic/arch-arm/include /

system/bionic/include /

system/libstdc++/include /

$(KERNEL_HEADERS) /

system/libm/include /

system/libm/include/arch/arm /

system/libthread_db/include

Shared Library

In our own Android.mk we should add two lines.

LOCAL_MODULE := ***

include
$(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY is defined in config.make
.

BUILD_SHARED_LIBRARY:=
$(BUILD_SYSTEM)/shared_library.make

In shared_library.make

include
$(BUILD_SYSTEM)/dynamic_binary.make

$(linked_module):
$(all_objects) $(all_libraries) $(LOCAL_ADDITIONAL_DEPENDENCIES)

$(transform-o-to-shared-lib)

So here defined a new target $(linked_module).

transform-o-to-shared-lib macro is defined in defintions.make
.

define
transform-o-to-shared-lib

@mkdir -p $(dir $@)

@echo "target
SharedLib: $(PRIVATE_MODULE) ($@)"

$(hide)
$(transform-o-to-shared-lib-inner)

endef

combo/linux-arm.make

contains macro to transform o to shared lib for ARM.

define
transform-o-to-shared-lib-inner

$(TARGET_CXX) /

-nostdlib -Wl,-soname,$(notdir $@) -Wl,-T,$(BUILD_SYSTEM)/armelf.xsc /

-Wl,--gc-sections /

-Wl,-shared,-Bsymbolic /

$(TARGET_GLOBAL_LD_DIRS) /

$(PRIVATE_ALL_OBJECTS) /

-Wl,--whole-archive /

$(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) /

-Wl,--no-whole-archive /

$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) /

$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) /

-o $@ /

$(PRIVATE_LDFLAGS) /

$(TARGET_LIBGCC)

endef

Tips: “make *** showcommands”can let build system show the
original compile commands.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: