现在的位置: 首页 > 综合 > 正文

Android build System

2013年08月21日 ⁄ 综合 ⁄ 共 8112字 ⁄ 字号 评论关闭

[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 /



抱歉!评论已关闭.