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.
分享到:
相关推荐
在Android Studio中,每个项目都有一个`build.gradle`文件,用于定义项目的构建规则和依赖关系。 1. **构建过程**:Android构建系统主要包括以下几个步骤: - **配置阶段**:读取`build.gradle`文件,解析其中的...
### Android构建系统详解 #### 目标与原则 在探讨Android构建系统之前,我们先来了解其主要目标和基本原则。 **目标:** 1. **增强依赖管理可靠性:**确保当项目中的文件发生变化时,能够准确地识别出哪些部分...
根据提供的文件内容,这本书名为《Gradle Recipes for Android Master the New Build System for Android》,由Ken Kousen所著。这本书专注于教授Android开发人员如何掌握Gradle这一新的构建系统。该书是O'Reilly ...
### Android Makefile与Build System深度解析 #### 一、引言 随着移动互联网技术的快速发展,尤其是近十年间,智能手机已成为人们日常生活中不可或缺的一部分。在众多操作系统中,Google推出的Android系统因其开放...
本文将深入探讨“Android源码编译参考文档”中的关键知识点,包括高通编译参考和Android Build System。 首先,我们关注的是“高通编译参考文档”。高通是Android设备中广泛使用的芯片制造商,其编译过程涉及到特定...
在Android系统中,SystemUI是用户界面的核心组成部分,它负责管理状态栏、通知中心、快速设置等关键功能。本文将深入探讨Android 8.1版本的SystemUI源码,介绍其结构、工作原理以及如何利用提供的gradle配置进行开发...
选择`Appearance & Behavior` -> `System Settings` -> `Android SDK`,然后在`SDK Tools`选项卡中更新`build-tools`。 7. **检查Gradle配置**:确保你的`build.gradle`文件中的配置正确无误,特别是`apply plugin:...
Who This Book Is For, If you are an experienced Android developer wanting to enhance your skills with the Gradle Android build system, then this book is for you. As a prerequisite, you will need some...
If you are an experienced Android developer wanting to enhance your skills with the Gradle Android build system, then this book is for you. As a prerequisite, you will need some knowledge of the ...
同时,了解Makefile的工作原理和Android.bp(Android Build System的组件描述文件)的语法,也能提高解决问题的能力。 总的来说,Android源码编译是一个复杂而深入的过程,涉及多方面的技术知识。从源码下载、环境...
3. 在左侧导航栏中选择`Appearance & Behavior` -> `System Settings` -> `Android SDK`。 4. 在右侧的`SDK Tools`选项卡中,找到`Android SDK Build-Tools`条目。 5. 在这里,你可以勾选`25.0.2`版本,如果未安装,...
11. **Android Build System**:理解Android的构建系统(如Gradle)和Makefile,有助于自定义编译过程,提高开发效率。 12. **Android性能优化**:通过源码,可以深入分析系统如何调度线程、管理内存,从而优化应用...
本文档主要介绍如何将Android系统中的SystemUI模块导入到Eclipse中并进行编译的过程。 首先需要明确SystemUI(System User Interface)模块在Android系统中的作用。SystemUI是系统用户界面部分,它负责显示状态栏、...
Android Build System 4 In this document 4 Building the Android Platform 6 Building the Android Kernel 8 Build Variants 9 Configuring a New Product 10 In this document 10 Detailed Instructions 11 New ...
4. **Android Build System**:AOSP(Android Open Source Project)的构建系统是基于Makefile和Gradle的复杂流程,开发者需了解编译脚本和变量,以定制自己的Android系统。 5. **Bootloader和Recovery**:这部分...
首先,本书针对的是有一定Android平台开发基础和经验的开发者,他们需要了解如何使用Android Build System构建平台、如何定制和扩展系统服务,以及如何将新的硬件驱动集成进Android系统中。本书还涉及了一些高级主题...