This book is based on Android5.0, but I use the source code of Android9.0, so there will be some differences with the original book content.

For Android builds, Google has been using Soong since Android7.0 to replace Make. It uses the Kati GNU Make clone and Ninja build system components to speed up Android builds. This is the official construction portal

Reading this book is a guided learning process. The purpose of reading this book is to get a thorough understanding of the Android system. 5.0 is really old. (PS: the company’s projects are 9.0, so compare the two versions.)

The Android Build system is a compilation environment based on GNU Make and Shell. Since Android is a huge system, including many modules, in order to manage the compilation of the entire source code, Android specially developed its own Build system.

The Android Build system can do:

  • Compiling, linking, and packaging system binaries or APK applications
  • Generate an image of the target file system and various configuration files
  • Maintain dependencies between modules
  • Make sure that changes to a module cause a recompilation of dependent files

In general, the Android Build system can be broken down into three parts:

  • AndroidThe Build systemThe framework and core of the build/core directory
  • The configuration files of each product are located in the device directory
  • Configuration files for each module:Android.mk, located in the source file directory of each module

Android The Build systemThe core

Three common instructions for compiling source code are:

source build/envsetup.sh
lunch eva_userdebug
make
Copy the code

We follow these three instructions, step by step analysis of the entire compilation process.

Setup of the compilation environment

envsetup.shFunction of files

To compile for Android, you must first run the envsetup.sh script, which sets up the Android build environment. Let’s look at some of the code for envsetup.sh:

function add_lunch_combo() # ignore implementation
function print_lunch_menu() # ignore implementation
function lunch() # ignore implementation
function m() # ignore implementation
function findmakefile() # ignore implementation
function mm() # ignore implementation
function mmm() # ignore implementation
function mma() # ignore implementation
function mmma() # ignore implementation
function croot() # ignore implementation
function cproj() # ignore implementation
Copy the code

Envsetup.sh defines many shell commands. Here are some common commands that can be invoked after the envsetup.sh script is executed.

The envsetup.sh file will execute the following command:

# add the default one here
add_lunch_combo aosp_arm-eng
add_lunch_combo aosp_arm64-eng
add_lunch_combo aosp_mips-eng
add_lunch_combo aosp_mips64-eng
add_lunch_combo aosp_x86-eng
add_lunch_combo aosp_x86_64-eng

# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
         `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
         `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
do
    echo "including $f"
    . $f
done
unset f
Copy the code

In this section of code:

  • add_lunch_comboAdded 6 compilation options
  • For loop lookupdevice,product,vendorIn the directoryvendorsetup.shFiles and execute them

In the company’s business, for example, in the vendor/formovie/goblin/vendorsetup sh the content is as follows:

add_lunch_combo goblin-eng
add_lunch_combo goblin-user
add_lunch_combo goblin-userdebug
add_lunch_combo goblin_fact-userdebug
Copy the code

Thus, envsetup.sh does three things:

  • createshellThe command
  • Look for third party definedvendorsetup.sh
  • performadd_lunch_combo

So what does add_lunch_combo do? Let’s look at the implementation:

unset LUNCH_MENU_CHOICES
function add_lunch_combo()
{
    local new_combo=The $1
    local c
    The # for loop looks for new elements in the array
    for c in ${LUNCH_MENU_CHOICES[@]} ; do
        if [ "$new_combo" = "$c"];then
            return
        fi
    done
    # Add new elements to LUNCH_MENU_CHOICES
    LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)}Copy the code

The function of add_lunch_combo is to store the parameters passed when the command is called into a global variable array called LUNCH_MENU_CHOICES. There are comments in the code. == Shell syntax rules look arbitrary, but Java is strictly prohibited ==

lunchThe directive prints the contents of this array

Since envsetup.sh defines the compile instruction, let’s look at what it does:

The command instructions
lunch Specifies the currently compiled product
tapas Set the Build environment variable
croot Quickly switch to the source code root directory
m Compile the entire source without switching to the root directory
mm Compile all modules in the current directory, but not their dependencies
mma Compile all modules in the current directory, as well as their dependencies
mmm Compiles all modules in the specified directory, but does not compile their dependencies
mmma Compiles all modules in the specified directory, as well as their dependencies
cgrep Run the grep command for all C/C ++ files in the system
ggrep Run the grep command on all local Gradle files in the system
jgrep Run the grep command for all Java files in the system
resgrep Run the grep command to all the XML files in the res directory
sgrep Run the grep command for all source files in the system
godir Search the entire source directory according to the parameter file name after godir, and then switch to that directory

lunchFunctions of commands

Take a look at the annotated lunch source code:

function lunch()
{
    local answer
    # check if there are any following parameters after lunch command
    if [ "The $1"];then
        answer=The $1
    else
        Print a list of available items without arguments
        print_lunch_menu
        # Force a wave of recommendations
        echo -n "Which would you like? [aosp_arm-eng] "
        Wait for user input and assign to answer
        read answer
    fi

    local selection=
    
    # If answer is empty, give a default value of AOSP_ARM -eng
    if [ -z "$answer" ]
    then
        selection=aosp_arm-eng
    # grep # grep # grep # grep # grep
    If there is a match, 0 is returned immediately
    # grep -e is followed by a matching expression. Multiple expressions require multiple -e
    elif (echo -n $answer | grep -q -e "^ [0-9] [0-9] * $")
    then
        In the array range, assign the value to selection
        if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
        then
            selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
        fi
    else
        # not a number, not empty, just use the argument passed in
        selection=$answer
    fi

    export TARGET_BUILD_APPS=

    local product variant_and_version variant version
    # Discard the first '-' and any characters following it from left to right and assign to product
    product=${selection%%-*} # Trim everything after first dash
    # Discard the occurrence of the first '-' and the character before it from left to right and assign it to variant_and_version
    variant_and_version=${selection#*-} # Trim everything up to first dash
    
    The types of variant are ENG, user, and userDEBUG
    if [ "$variant_and_version"! ="$selection" ]; then
        variant=${variant_and_version%%-*}
        If the version is not resolved, no error will be reported
        if [ "$variant"! ="$variant_and_version" ]; then
            version=${variant_and_version#*-}
        fi
    fi

    # Return error if product is empty
    if [ -z "$product" ]
    then
        echo
        echo "Invalid lunch combo: $selection"
        return 1
    fi
    
    TARGET_PRODUCT=$product \
    TARGET_BUILD_VARIANT=$variant \
    TARGET_PLATFORM_VERSION=$version \
    Set the build variable
    build_build_var_cache
    # Check the return value of build_build_var_cache, if not 0, exit
    if[$?-ne0]then
        return 1
    fi
    
    export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
    export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
    if [ -n "$version" ]; then
      # string length not 0, set TARGET_PLATFORM_VERSION
      export TARGET_PLATFORM_VERSION=$(get_build_var TARGET_PLATFORM_VERSION)
    else
      Unset TARGET_PLATFORM_VERSION if the string length is 0
      unset TARGET_PLATFORM_VERSION
    fi
    export TARGET_BUILD_TYPE=release

    echo
    Set some compile-time environment, such as output path, output image sequence number, etc
    set_stuff_for_environment
    Print the configuration information
    printconfig
    Clear the local cache
    destroy_build_var_cache
}
Copy the code

The lunch code is mainly used to set environment variables related to specific products based on product names entered or selected by users.

The variables assigned in lunch are mainly related (take goblin_fact-userdebug as an example) :

  • TARGET_PRODUCT: the correspondinggoblin_fact
  • TARGET_BUILD_VARIANT: the correspondinguserdebug
  • TARGET_BUILD_TYPE: the correspondingrelease

Build related environment variables

After executing the lunch command, the following output is displayed:

. Here is the compiled item added by add_Lunch_combo and marked with the serial number... Which would you like? [aosp_arm-eng]Copy the code

Waiting to confirm which project to use for compilation, we use the no. 65 Goblin_fact-Userdebug project. The output of the environment variable information is as follows:

Which would you like? [aosp_arm-eng]  65

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
TARGET_PRODUCT=goblin_fact
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9 HOST_ARCH = x86_64 HOST_OS = Linux HOST_OS_EXTRA = Linux - 4.15.0-70 - generic - x86_64 - Ubuntu - 16.04.6 - LTS BUILD_ID = PQ3B. 190705.003 OUT_DIR = outCopy the code

These environment variables affect the compilation process. Let’s take a quick look at what variables represent:

  • PLATFORM_VERSION_CODENAME: Indicates the name of the platform version, usuallyAOSP (Android Open Source Project)
  • PLATFORM_VERSION: Indicates the Android version number
  • TARGET_PRODUCT: The name of the compiled product
  • TARGET_BUILD_VARIANT: Type of compiled product, possibleeng,user,userdebug
  • TARGET_BUILD_TYPE: indicates the compiled type, includingreleaseanddebug. When selectingdebugWill add some debugging information.
  • TARGET_ARCH: Compile the target CPU architecture
  • TARGET_ARCH_VARIANT: Compile the target CPU architecture version
  • TARGET_CPU_VARIANT: CPU architecture code of the compile target
  • HOST_ARCH: The architecture of the compilation platform
  • HOST_OS: Operating system of the compilation platform
  • HOST_OS_EXTRA: Additional information about the compiler platform operating system
  • BUILD_ID:BUILD_IDAppears in the compiled version information and can be used to define company-specific identifiers
  • OUT_DIR: Specifies the output directory for compiling results

The Build systemHierarchical relationship of

After executing the lunch command, you can use the make command to execute the Build.

Let’s first describe the function of the Build system from the perspective of compilation:

  • Generated forflashA variety ofimageFile. The process can be carried out:
    • File copy
    • Modules compiled
    • Generating a Configuration File
  • Flexibly configure and compile modules according to product requirements
  • Can provide the compilation function of a single module

Now that we know the features, let’s look at how the Build system implements these features.

The call flow after executing the make command:

graph LR
build/envsetup.sh-make-->build/soong/soong_ui.bash
build/soong/soong_ui.bash-->build/soong/ui/build/kati.go
build/soong/ui/build/kati.go --> build/make/core/main.mk
Copy the code

This part is actually quite different from the book, there are some more things in 9.0

  • Added katI frame handlesAndroid.mkConvert to Ninja File.
  • Add soong frame handlesAndroid.bpConvert to Ninja File.
  • increaseAndroid.bpAre files organized in the form of Jason, which will be gradually replaced in the futureAndroid.mk

Start with build/make/core/main.mk and include other. Mk files to form a collection of all compiled scripts. This collection is equivalent to a giant Makefile

Although a Makefile may seem large, it is actually made up of three main things:

  • Variable definitions
  • The function definitions
  • Goal dependence rule

Android Makefiles are as follows:

For the three sections of the orange logo above, the Build system introduces the product-specific configuration files AndroidProduct.mk and boardconfig. mk, respectively. And the compilation file of each module Android.mk.

The mk file in the build/make/core/combo directory defines the GCC compiler version and parameters. The mk file in the build/make/core/clang directory defines the path and parameters for LLVM compiler clang.

Build system main.

The file name instructions
main.mk The Android Build system master file. The main purpose of this file is to include other MK files and define several important build targets such as Droid, SDK, NDK, etc. Also check the version of the compilation tool, such as make, GCC, and JAVac.
config.mk The Android Build configuration file defines a number of constants that are responsible for compiling different types of modules, defining the compiler parameters and introducing the productBoardConfig.mkFile to configure the product parameters, but also define the path of some compilation tools, such as aapt, mkbooting, JavaJAR and so on.
envsetup.mk includeproduct_config.mkFile and set the environment variables needed to compile the product based on its contents, such asTARGET_PRODUCT,TARGET_BUILD_VARIANT,HOST_OSAnd so on. And check the validity of the variable value, specify the output path of the compilation result.
product_config.mk All of them in the systemAndroidProduct.mkFile, and set variables related to product compilation based on the current product configuration file
product.mk defineproduct_config.mkThe various functions used in the file
definitions.mk Defines a number of functions used in the Build system.
dexpreopt.mk Define paths and parameters related to dex optimization
Makefile Defines various goals and rules for the system to complete the compilation

== The 5.0 compiled scripts in the book and 9.0 changed too much… Don’t delve into the details of the implementation, complex things to script it, the first simple understanding of the main. Mk file include relationship ==

Android product profile

The function of the product configuration file is to organize the configuration information (such as version number, various parameters, etc.), resources (pictures, fonts, etc.), binary files (APK, JAR package, so library, etc.) needed to generate various image files of the product according to the requirements of the Build system. At the same time, some modules can be added or deleted flexibly.

Typically, the product configuration files are placed in the Device directory, while the Vendor directory hosts HAL libraries of hardware and custom code from third-party vendors.

The goblin configuration file is used as an example

Generally, the device directory is divided into the following subdirectories:

  • Common: stores configuration scripts and files common to each product.
  • Sample: An example of product configuration.
  • Generic: Stores products used in emulators, including x86, ARM, and MIPS architectures
  • Vendor product catalog (Samsung, AmLogic, Formovie, etc.)

For the Goblin project, the configuration files are concentrated in the Device/Formovie/Goblin path, and the core files include vendorsetup.sh, AndroidProduct.mk, and boardconfig. mk. Let’s take a look at each of them.

vendorsetup.sh

As mentioned earlier, vendorsetup.sh is included in the envsetup.sh file when the build environment is initialized. Its main function is to call add_Lunch_combo to add the product name.

In goblin’s case, the vendorsetup.sh content is as follows:

add_lunch_combo goblin-eng
add_lunch_combo goblin-user
add_lunch_combo goblin-userdebug
add_lunch_combo goblin_fact-userdebug
Copy the code

AndroidProduct.mk

Androidproduct. mk is included in the product_config.mk file of the Build system. The most important function of this file is to define a variable PRODUCT_MAKEFILES, which defines all compiled entry files in this configuration directory.

Goblin, for example, has the following androidProduct.mk:

ifeq ($(TARGET_PRODUCT),goblin)
PRODUCT_MAKEFILES := $(LOCAL_DIR)/goblin.mk
else ifeq ($(TARGET_PRODUCT),goblin_fact)
PRODUCT_MAKEFILES := $(LOCAL_DIR)/goblin_fact.mk
Copy the code

Execute different.mk files for different lunch products.

BoardConfig.mk

Boardconfig. mk is included in envsetup.sh of the Build system. This file defines parameters related to the device hardware (including CPU, WIFI, CPS, etc.). Let’s look at some of the compiler variables in action:

  • TARGET_CPU_ABI: indicates the programming interface of the CPU. Such asarmeabi-v7a. = =ABIIs what? Let’s go into detail
  • TARGET_CPU_ABI2: indicates the programming interface of the CPU.
  • TARGET_CPU_SMP: indicates whether the CPU is multi-core.
  • TARGET_ARCH: Defines the CPU architecture. Such asarm.
  • TARGET_ARCH_VARIANT: Defines the architecture version of the CPU. Such as:armv7-a-neon
  • TARGET_CPU_VARIANT: Defines the CPU code. Such as:contex-a9
  • TARGET_NO_BOOTLOADER: If true, the compiled image does not contain the bootloader.
  • BOARD_KERNEL_BASE: base address for loading kernel images. Such as:0x0
  • BOARD_KERNEL_OFFSET: indicates the offset address of the kernel image. Such as:0x1080000
  • BOARD_KERNEL_CMDLINE: command line parameter passed to the kernel when the kernel is loaded. Such as:--cmdline "root=/dev/mmcblc0p20"
  • BOARD_MKBOOTIMG_ARGS: Use the mkbooting tool to generate boot.img parameters. Such as:--kernel_offset 0x1080000
  • BOARD_USES_ALSA_AUDIO: If the value is true, it indicates that the sound system on the mainboard uses the ALSA architecture.
  • BOARD_HAVE_BLUETOOTH: If the value is true, the mainboard supports Bluetooth.
  • BOARD_WLAN_DEVICE: Defines the WiFi device name.
  • TARGET_BOARD_PLATFORM: Indicates the mainboard platform model. Such astl1
  • TARGET_USERIMAGES_USE_EXT4: If the value is true, the target file system uses EXT4 format.
  • TARGET_NO_RADIOIMAGEIf the value is true, the compiled image has no RF part.
  • WPA_SPPLICANT_VERSION: Defines the WIFI WPA version.
  • BOARD_WPA_SUPPLICANT_DRIVER: Specifies a typeWPA_SUPPLICANTThe driver.
  • BOARD_HOSTAPD_DRIVER: Specifies the driver of the WiFi hotspot.
  • WIFI_DRIVER_FW_PATH_PARAM: Specifies the WiFi driver parameter path.
  • WIFI_DRIVER_FW_PATH_AP: Defines the path to the WiFi hotspot firmware file.

There are too many variables in the Build system… Let’s explain

ABIIs what?

Most are from Baidu Baike

Application Programming Interfaces (apis), also known as Application Programming interfaces (apis), are conventions for connecting different parts of a software system. Because of the increasing scale of software, it is often necessary to divide complex systems into small components, the design of programming interfaces is very important. In the practice of program design, the design of programming interface should first make the responsibility of software system get reasonable division. Good interface design can reduce the interdependence of all parts of the system, improve the cohesion of components, reduce the coupling degree between components, and improve the maintenance and expansibility of the system.

The ABI stands for Application Binary Interface and is called Application Binary Interface. Unlike an API, which defines the interface between source code and libraries, the same code can be compiled on any system that supports the API, whereas the ABI allows compiled object code to run without changes on systems that use the ABI. At the same time, the ABI covers up the details. For example, the calling convention controls how the parameters of a function are passed and how the return value is received. The coding of system calls and how an application makes system calls to the operating system; And, in a full operating system ABI, the binary format of object files, libraries, and so on.

It describes the underlying interface between the application and the OS. The ABI covers all aspects of the program, such as object file format, data types, data alignment, function calling conventions and how functions pass parameters, return values, system call numbers, and how system calls are implemented.

A complete set of ABI, such as The Intel Binary Compatibility Standard (iBCS), allows programs to run on all systems that support the ABI without modification.

A couple of other important ones.mk

There are also several build-related.Mks under the Device/Formovie/Goblin path

goblin_fact.mk    goblin.mk    device.mk
Copy the code

Goblin_fact. mk and goblin.mk are the two entry files we defined in AndroidProduct.mk. The Device. mk does the following:

  • Copy the kernel image to the target system
  • Copy Linux initialization files and partition tables to the target system
  • Defines the resolution supported by the system
  • Specifies the overlay directory for the system
  • Add some modules
  • Set system properties
  • Include Some other configuration files

Let’s take a look at some of it:

PRODUCT_DIR := goblin
PRODUCT_NAME := goblin_fact # Product Name
PRODUCT_DEVICE := goblin The device name is criticalPRODUCT_BRAND := product brand PRODUCT_MODEL := Product model PRODUCT_MANUFACTURER :=Add the compiler module Settings and Launcher
PRODUCT_PACKAGES += \
    Settings \
    Launcher

# copy a c++ library to vendor/lib/
PRODUCT_COPY_FILES += \
    device/formovie/goblin/files/libstdc++.so:vendor/lib/libstdc++.so

# include a device.mk script
$(call inherit-product, device/formovie/$(PRODUCT_DIR)/device.mk)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# device.mk #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

Overlay directory for the system
DEVICE_PACKAGE_OVERLAYS := \
    device/formovie/$(PRODUCT_DIR)/overlay

Set system property values
PRODUCT_PROPERTY_OVERRIDES += \
    persist.sys.usb.config=mtp

# Define the resolution supported by the system
PRODUCT_AAPT_CONFIG := xlarge hdpi xhdpi tvdpi
PRODUCT_AAPT_PREF_CONFIG := hdpi
Copy the code

Some of the important compile variables above are explained as follows:

  • PRODUCT_COPY_FILES: Copies a file in the compiled directory to the target file system. If the folder does not exist, it is automatically created.
  • PRODUCT_PACKAGES: A list of modules used to define the product. All modules defined in the module list are compiled into it.
  • PRODUCT_AAPT_CONFIG: Specifies the screen density type (DIP) supported by the system. By support, we mean that at compile time, the corresponding resource files are added toframework_res.apkFile.
  • PRODUCT_AAPT_PREF_CONFIG: Specifies the actual screen density type of the system.
  • DEVICE_PACKAGE_OVERLAYS: a very important variable, specified for the systemoverlayDirectory. Used when the system is compiledoverlayThe resource files stored in the directory replace the original resource files of the system or the last class. This allows you to personalize the product without changing the native resource files. andoverlayYou can have multiple directories that replace resource files in the order in which they appear in a variable, using this feature to define commonoverlayCatalog, as well as each product exclusiveoverlayDirectories for maximum reuse of resource files.
  • PRODUCT_PROPERTY_OVERRIDES: Defines system property values. If the property starts withro.Start, then this property is read-only. Once set, properties cannot be changed. If the property starts withpersisit.Initially, when this property is set, its value is written to/data/propertyIn the.

Compile typeeng,useranduserdebug

engtype

The default compilation type. Executing make is equivalent to executing make eng.

The following modules are compiled into the system at compile time:

  • inAndroid.mkusingLOCAL_MODULE_TAGSDefines the tag:eng,debug,shell_$(TARGET_SHELL),useranddevelopmentThe module
  • Modules that are not APK modules and do not have any labels
  • APK modules specified in all product profiles

Compiled systems have the following properties:

  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1

Adb is turned on by default on compiled systems

usertype

The following modules are compiled into the system at compile time:

  • inAndroid.mkusingLOCAL_MODULE_TAGSDefines the tag:shell_$(TARGET_SHELL)anduserThe module
  • Modules that are not APK modules and do not have any labels
  • All APK modules specified in product profiles, while ignoring their label attributes

Compiled system properties:

  • ro.secure=1
  • ro.debuggable=0

Adb is not available by default on compiled systems and needs to be turned on manually in Settings

userdebugtype

The following modules are compiled into the system at compile time:

  • inAndroid.mkusingLOCAL_MODULE_TAGSDefines the tag:debug,shell_$(TARGET_SHELL)anduserThe module
  • Modules that are not APK modules and do not have any labels
  • All APK modules specified in product profiles, while ignoring their label attributes

Compiled system properties:

  • ro.secure=1
  • ro.debuggable=1

Adb is not available by default on compiled systems and needs to be turned on manually in Settings

Of the productimagefile

Android generates an image file after compiling, including:

  • boot.img: Contains passmkbootimgA combined kernel image and RAM disk
  • system,img: Mainly includes the Android framework
  • recovery.img: Used to store recovery images that are started during OTA.
  • = =cache.img== : This partition is used to store temporary data. If the device uses A/B update, this partition can be discarded.
  • = =misc.img== : the storage space for the recovery image cannot be smaller than 4KB.
  • userdata.img: contains applications and data installed by users, including user-defined data.
  • = =metadata.img== : if the device is encrypted, use a metadata partition. The storage space of the metadata partition cannot be smaller than 16MB.
  • = =vendor.img== : contains all binaries that cannot be distributed to the Android Open Source Project (AOSP). If there is no proprietary information, you can omit this partition. (Should be related data of third party manufacturers)
  • = =radio.img== : contains the wireless device image. This partition is required only for devices that contain wireless devices and include wireless device-specific software in the dedicated partition.
  • = =tos.img== : Used to store the binary image of the Trusty operating system, only if the device contains Trusty.

The yellow marks are not mentioned in the book, and are simply noted.

boot.img

Boot. img is an Android custom file format. The format consists of a 2*1024 file header followed by a gzip-compressed kernel image, followed by a ramdisk image, and finally (optionally) a loader program.

The boot.img structure is as follows:

- kernel.img
- ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Copy the code

Boot. img stores data in the unit of page. BOARD_KERNEL_PAGESIZE is specified at compile time. The usual value is 2048.

Ramdisk.img is a small file system that contains all the core files needed to initialize a Linux system.

recovery.img

Recovery.img is equivalent to a small text-interface Linux system with its own kernel and file system.

Recovery. img is used to recover or upgrade the system. Therefore, there is a recovery program in the sbin directory; Adbd and the system configuration file init.rc are also included. But these files are not the same as those in boot.img.

system.img

System. img is the image of the system directory on the device, which contains the main directories and files of the Android system. The contents include:

- system.img
  -/
    - app           Store general APK files
    - bin           # Store some Linux tools, mostly links to Toolbox
    - etc           Save the system configuration file
    - fonts         Save system font file
    - framework     All jar packages and resource files of the system platform are stored
    - lib           # Store the system's shared library
    - media         # Store system multimedia resources, mainly ringtones.
    - priv-app      Store the apK file of the system core
    - tts           # Store system voice synthesis files
    - usr           Store various keyboard layout, time area files
    - vendor        # Store configuration files from third-party vendors (existing versions are separated as a separate partition)
    - xbin          System management tool, equivalent to sbin in standard Linux file system
    - build.prop    # System properties definition file
Copy the code

userdata.img

Userdata. img is a mirror of the /data directory on the device and generally does not contain any files at the beginning. A few subdirectories and files are created in the /data directory during Android system initialization.

Improved compilation speed

memory

As much memory as possible

SSD

SSD improves file read and write speed

CCCache

Compiler optimization, increase cache.

export USE_CACHE = 1
export CCACHE_DIR=/<path_of_your_choice>/.ccache
prebuilts/misc/linux-x86/ccache/ccache -M 50G
Copy the code

Note that CCCache does not improve the speed of the first compile. The principle is to cache the compilation results of some system libraries. If the next compilation detects no changes in the library, it directly uses the cached file (impression is more pit).

Compiling the Android Emulator

The operation is as follows:

. build/envsetup.sh
lunch sdk-eng
make
Copy the code

After compiling

emulator
Copy the code

For x86 PCS, you can run Intelhaxm under extras/ Intel /Hardware_Accelerated_Execution_Manager in the SDK to speed things up before starting the emulator.

Build Android modules

Build /make/core/build-system.html When confused, read the official explanation.

Various modules in Android, whether apK applications, executables, or JAR packages, can be compiled through the Build system. In the source directory of each module, there is an Android.mk file, which contains the location of the module code, the name of the module, the dynamic library to link to, and a series of definitions.

Take Settings as an example:

# set LOCAL_PATH to the current directory
LOCAL_PATH:= $(call my-dir)
# Clear all LOCAL_ variables except LOCAL_PATH
include $(CLEAR_VARS)
###### Copy each module directly from the above part ######

# specify the module name
LOCAL_PACKAGE_NAME := Settings
When # is true, the SDK's hide API is used to compile
LOCAL_PRIVATE_PLATFORM_APIS := true
# specify module signature using platform signature
LOCAL_CERTIFICATE := platform
# true indicates that apK will be installed under Priv-app
LOCAL_PRIVILEGED_MODULE := true
# define the module as optional
LOCAL_MODULE_TAGS := optional
# Use AAPT2 optimized version
LOCAL_USE_AAPT2 := true

# specify a shared Java class library to rely on
LOCAL_JAVA_LIBRARIES := \
    bouncycastle \
    telephony-common \
    ims-common

# specify a static Java class library to rely on
LOCAL_STATIC_JAVA_LIBRARIES := \
    android-arch-lifecycle-runtime \
    android-arch-lifecycle-extensions \
    guava \
    jsr305 \
    settings-logtags \

Declare the package that calls Android
LOCAL_STATIC_ANDROID_LIBRARIES := \
    android-slices-builders \
    android-slices-core \
    android-slices-view \
    android-support-compat \
    android-support-v4 \
    android-support-v13 \
    android-support-v7-appcompat \
    android-support-v7-cardview \
    android-support-v7-preference \
    android-support-v7-recyclerview \
    android-support-v14-preference \

Define a list of source files
LOCAL_SRC_FILES := \
        $(call all-logtags-files-under, src)

# specify an obfuscated flag
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
# specify the compile module type to be APK
include $(BUILD_PACKAGE)
Include the rest of the android. mk file in the source directory
include $(call all-makefiles-under,$(LOCAL_PATH))
Copy the code

Module compilation variable

The android. mk file can compile different modules by including a module to compile the file. For example, when compiling APK:

include $(BUILD_PACKAGE)
Copy the code

After a series of grep, found these modules compiled variables are in the build/make/core/config. Mk defined in the file. Let’s take a look at some of the variable declarations. Look it up when you need it) :

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Build system internal files
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# Clear Local_ variable
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
Generate a local static library used by the compilation platform
BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk
Generate a local shared library used by the build platform
BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
Generate a local static library used by the target platform
BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
BUILD_HEADER_LIBRARY:= $(BUILD_SYSTEM)/header_library.mk
BUILD_AUX_STATIC_LIBRARY:= $(BUILD_SYSTEM)/aux_static_library.mk
BUILD_AUX_EXECUTABLE:= $(BUILD_SYSTEM)/aux_executable.mk
Generate a shared library used by the build platform
BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
Generate a Linux executable used by the target system
BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
# Produce executable programs that can be used by the compiler platform
BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
# Generate apK file
BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
BUILD_PHONY_PACKAGE:= $(BUILD_SYSTEM)/phony_package.mk
BUILD_RRO_PACKAGE:= $(BUILD_SYSTEM)/build_rro_package.mk
BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk
# Define the precompiled module target. The purpose is to introduce precompiled modules into the system
BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
# Define multiple precompiled module targets
BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk
Generate Java shared libraries
BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
Generate Java static libraries
BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk
Generate Java shared libraries for compiling platforms
BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
BUILD_APIDIFF:= $(BUILD_SYSTEM)/apidiff.mk
Copy the file defined by the LOCAL_COPY_HEADERS variable to the path defined by LOCAL_COPY_HEADERS_TO
BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
BUILD_NATIVE_TEST := $(BUILD_SYSTEM)/native_test.mk
BUILD_NATIVE_BENCHMARK := $(BUILD_SYSTEM)/native_benchmark.mk
BUILD_HOST_NATIVE_TEST := $(BUILD_SYSTEM)/host_native_test.mk
BUILD_FUZZ_TEST := $(BUILD_SYSTEM)/fuzz_test.mk
BUILD_HOST_FUZZ_TEST := $(BUILD_SYSTEM)/host_fuzz_test.mk
Copy the code

So include $(BUILD_PACKAGE) is just

include build/make/core/package.mk
Copy the code

Google dad is very sweet.

Those of you who are interested can delve into these.MK files.

Common module definition instances

Compile an APK file

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# specify a shared Java library to rely on
LOCAL_JAVA_LIBRARIES := 
# specify a static Java library to rely on
LOCAL_STATIC_JAVA_LIBRARIES := 

# Specify the module's label
LOCAL_MODULE_TAGS := optional/user/userdebug/eng
# specify the module name
LOCAL_PACKAGE_NAME := apkName
# specify how the module is signed
LOCAL_CERTIFICATE := platform

# Don't use code obfuscation tools for code obfuscation
LOCAL_PROGUARD_ENABLED:= disabled
Compile using the hide API
LOCAL_PRIVATE_PLATFORM_APIS := true
Install in the priv-app directory
LOCAL_PRIVILEGED_MODULE := true

Androidmanifest.xml file path
LOCAL_MANIFEST_FILE := app/src/main/AndroidManifest.xml
# specify the resource path
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/src/main/res
# specify source path
LOCAL_SRC_FILES := \
        $(call all-java-files-under, src)

include $(BUILD_PACKAGE)
Copy the code

Compile a Java shared library

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

# compile module tag
LOCAL_MODULE_TAGS := optional/user/userdebug/eng
The name of the compiled module
LOCAL_MODULE := java_lib_name
# source code compile path
LOCAL_SRC_FILES := $(call all-java-files-under,java)

include $(BUILD_JAVA_LIBRARY)
Copy the code

Compile a Java static library

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

The name of the compiled module
LOCAL_MODULE := java_static_lib_name
# source code compile path
LOCAL_SRC_FILES := $(call all-java-files-under,java)

include $(BUILD_STATIC_JAVA_LIBRARY)
Copy the code

Compile a Java resource pack file

The resources department is also an APK file, but there is no code.

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

# Use AAPT2 to package resources
LOCAL_USE_AAPT2 := true
If the value of # is true, the dependent jar package was written manually. Either system or user's own
LOCAL_NO_STANDARD_LIBRARIES := true
# Specify the signature type
LOCAL_CERTIFICATE := platform
# specify AAPT tool parameters (now using AAPT2 optimized version)
LOCAL_AAPT_FLAGS := -x
Define the module name
LOCAL_PACKAGE_NAME := java_res_name_lib
# define the module tag as user
LOCAL_MODULE_PATH := user
Define the output path of the module after compilation
LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
When # is true, other APKs can reference this module's resources
LOCAL_EXPORT_PACKAGE_RESOURCES := true
include $(BUILD_PACKAGE)
Copy the code

Compile an executable file

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# define the source path
LOCAL_SRC_FIFLES := Executor.cpp
Specify the dynamic library that the module needs to link to
LOCAL_SHARE_LIBRARIES := libutils libbinder
# define compile flags
ifeq ($(TARGET_OS),linux)
    LOCAL_CFLAGS += -DXP_UNIX
endif
# specify the module name
LOCAL_MODULE := executor_name
include $(BUILD_EXECUTABLE)
Copy the code

Build a native shared library

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional/user/userdebug/eng
LOCAL_MODULE := lib_native_share_name
# specify the source file to compile
LOCAL_SRC_FIFLES := Native.cpp
# specify the static library that the module needs to link to
LOCAL_SHARE_LIBRARIES := \
    libutils \
    libbinder
# specify the static library that the module depends on
LOCAL_STATIC_LIBRARIES := lib_native_static_name
# specify the header file lookup path
LOCAL_C_INCLUDES += \
    $(JNI_H_INCLUDE) \
    $(LOCAL_PATH)/.. /include
# define compile flags
LOCAL_CFLAGS += -O
include $(BUILD_SHARED_LIBRARY)
Copy the code

Build a static native library

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional/user/userdebug/eng
LOCAL_MODULE := lib_native_static_name
# specify the source file for the module
LOCAL_SRC_FIFLES := \
    NativeStatic.cpp
# specify the header file lookup path
LOCAL_C_INCLUDES:=  \
# define compile flags
LOCAL_CFLAGS :=-D_ANDROID_
include $(BUILD_STATIC_LIBRARY)
Copy the code

Definition of a precompiled module

In real development, many APKs, files, JAR packages, and so on are pre-compiled. These binaries need to be copied into the generated image file when compiling the system.

The usual method is to copy the file to the generated image file using the PRODUCT_COPY_FILES variable, like this:

PRODUCT_COPY_FILES += \
	$(LOCAL_PATH)/media/autovideo_265.mkv:/system/factory/autovideo_265.mkv 
Copy the code

However, for APK, or JAR packages, you need to use the system’s signature to run properly; Other dynamic library files may be dependent on modules in the source code. So that’s not going to work.

Android provides a way to precompile modules to address this problem. The general process is as follows:

  • throughLOCAL_SRC_FILESSpecifies the path to the binary file (APK or JAR package)
  • throughLOCAL_MODULE_CLASSSpecifies the type of the compiled module
  • throughinclude $(BUILD_PREBUILT)Perform precompilation

LOCAL_MODULE_CLASSWhat types can you specify?

First, Google dad said:

LOCAL_MODULE_CLASS
Which kind of module this is. This variable is used to construct other variable names used to locate the modules. See base_rules.mk and envsetup.mk.
Copy the code

So let’s take a look at these two files

base_rules.mk:

EXECUTABLES
SHARED_LIBRARIES
STATIC_LIBRARIES
NATIVE_BENCHMARK
HEADER_LIBRARIES
NATIVE_TESTS
JAVA_LIBRARIES
APPS
Copy the code

Envsetup.mk, however, is not explicitly stated.

Take a precompiled APK file as an example

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := Factory
LOCAL_SRC_FILES := release/factory_test-release.apk
LOCAL_PRIVILEGED_MODULE := true
LOCAL_MODULE_CLASS := APPS
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional

include $(BUILD_PREBUILT)
Copy the code

The commonly usedLOCAL_variable

Build /make/core/build-system.html

LOCAL_ = LOCAL_ (); LOCAL_ = LOCAL_ ();

The variable name instructions
LOCAL_ASSET_FILES Used to specify a list of resources when compiling APK files, usually written asLOCAL_ASSET_FILES += $(call find-subdir-assets)
LOCAL_CC Custom C compiler to replace the default compiler
LOCAL_CXX Custom C++ compiler to replace the default compiler
LOCAL_CFLAGS Define additional C/C++ compiler parameters
LOCAL_CPPFLAGS Define additional C++ compiler parameters that are not in the C compiler
LOCAL_CPP_EXTENSION Custom C++ source file suffixes. Such as:LOCAL_CPP_EXTENSION := .cc. Once defined, all source files in a module must use modified suffixes, and mixing is not currently supported.
LOCAL_C_INCLUDES Specifies the search path for the header file.
LOCAL_FORCE_STATIC_EXECUTABLE There are both shared and static libraries that need to be linked at compile time. Static libraries are linked preferentially when this variable is true. Usually this is only done during compilationroot/sbinApplications in directories are used because they are executed early and the rest of the file system has not been loaded
LOCAL_GENERATED_SOURCES Files that you add to LOCAL_GENERATED_SOURCESWill be automatically generated and then linked in when your module is built.
LOCAL_MODULE_TAGS Define module labels that the Build system uses to determine which modules need to be compiled.
LOCAL_REQUIRED_MODULES Specifies the dependent module. Once the current module is installed, the module specified by this variable will also be installed
LOCAL_JAVACFLAGS Defines additional javAC compiler parameters
LOCAL_JAVA_LIBRARIES Specifies the Java shared library that the module depends on
LOCAL_LDFLAGS Define the parameters of the connector LD
LOCAL_LDLIBS Specifies the library on which the module is connected. If the library files do not exist, their compilation is not triggered. (LOCAL_LDLIBS allows you to specify additional libraries that are not part of the build for your executable or library. Specify the libraries you want in -lxxx format; they’re passed directly to the link line. However, keep in mind that there will be no dependency generated for these libraries. It’s most useful in simulator builds where you want to use a library preinstalled on the host. The linker (ld) is a particularly fussy beast, so it’s sometimes necessary to pass other flags here if you’re doing something sneaky. Some examples:LOCAL_LDLIBS += -lcurses -lpthread.LOCAL_LDLIBS += -Wl,-z,origin
LOCAL_NO_MANIFEST If this parameter is true, the software package does not contain Androidmanifest.xml. (Commonly used in resource packs)
LOCAL_PACKAGE_NAME Specify the APP name
LOCAL_PATH The specifiedAndroid.mkFile Directory
LOCAL_POST_PROCESS_COMMAND When compiling the host related module, you can use this variable to define a command to execute after link completes
LOCAL_PREBUILT_LIBS Specifies a list of pre-compiled C/C++ dynamic and static libraries for pre-compiled modules
LOCAL_PREBUILT_JAVA_LIBRARIES Specifies a list of precompiled Java libraries that are used to precompile modules
LOCAL_SHARED_LIBRARIES Specifies the list of C/C++ shared libraries that the module depends on
LOCAL_SRC_FILES Specify a list of source files
LOCAL_STATIC_LIBRARIES Specifies the list of C/C++ static libraries that the module depends on
LOCAL_MODULE Except for apK module useLOCAL_PACKAGE_NAMEAll modules except the specified module name are usedLOCAL_MODULESpecifying the module name
LOCAL_MODULE_PATH Specifies the installation path of the module on the target system. Executables and dynamic library modules are usually pairedLOCAL_UNSTRIPPED_PATHuse
LOCAL_UNSTRIPPED_PATH Specifies the path where the unstrpped version of the module is saved in the out directory
LOCAL_ADDITIONAL_DEPENDENCIES Modules that need to depend on any other modules that aren’t actually built in can add these make targets toLOCAL_ADDITIONAL_DEPENDENCIES. Typically, this is a workaround for other dependencies that are not automatically created.
LOCAL_MODULE_CLASS Define the classification of modules. The generated modules will be installed in the corresponding directory according to the classification. For example: APPS, installed to /system/app;SHARED_LIBRARIES/system/lib; EXECUTABLE installed under /system/bin; /system/ ETC; But if you use bothLOCAL_MODULE_PATHIf a path is defined, install to that path.
LOCAL_MODULE_NAME Specifying the module name
LOCAL_MODULE_SUFFIX Specifies the suffix for the current module. Once specified, object files are created with the module name + suffix when the system generates them
LOCAL_STRIP_MODULE Specifies whether a module needs strips. This variable is typically used when compiling executables and dynamic libraries

Signatures in Android

In Android, all apKs installed on the system require a signature, which is a digital certificate attached to an application. While digital certificates have many uses, in Android, their only role is to identify the creator.

Android application signature method

Create a certificate file for signing

Android uses the Java tool keytool to generate a digital certificate.

keytool -genkey -v -keystore lee.keystore -alias lee.keystore -keyalg RSA -validity 30000
Copy the code

Parameter Description:

  • -keystore lee.keystoreIndicates the certificate file name.
  • -alias lee.keystoreIndicates the alias of the certificate
  • -keyalg RSAIndicates the encryption algorithm used
  • -validity 30000Indicates the validity period of the certificate

After the command is executed, the terminal prompts you to set the following information:

  • First, you need to set up onekeystoreEnter the password and repeat to confirm.
  • And then enter all kinds of personal information. EnteryesConfirm the information.
  • After confirming your personal information, you need to set onekeyEnter the password and repeat to confirm.

Why are there two passwords?

  • The first password set is the container in which the digital certificate is stored (keystore).
  • The second password is the password of the newly created digital certificate for signing.

Take a look at the certificate container you just created with the command:

keytool -list -keystore lee.keystore
Copy the code

At this point, you need to enter the first password, enter the following print:

lijie@leeMBP:~$keytool -list -keystore lee. Keystore enter the keystore password: keystore type: JKS keystore provider: SUN Your keystore contains 1 entry lee.keystore, 2020-7-19, PrivateKeyEntry, Certificate Fingerprint (SHA1): BD:6A:85:18:22:34:91:25:F9:38:1F:CB:A2:BA:EC:91:78:3C:67:9FCopy the code

Application Signature Procedure

Signature command

jarsigner -verbose -keystore lee.keystore -signedjar android-release-signed.apk android-release-unsigned.apk lee.keystore
Copy the code
  • -verboseIndicates that the signing procedure is to be printed
  • -keystoreUsed to specify the keystore file
  • -signedjarSpecifies the apK name after the signature
  • android-release-unsigned.apkFile to be signed
  • The lastlee.keystoreIs the alias of the certificate

The execution encountered the following error:

lijie@leeMBP:~/Desktop$ jarsigner -verbose -keystore ~/lee.keystore -signedjar Feng-Factory-signed.apk Feng-Factory.apk Lee. Keystore enter keystore password phrases: input lee. Keystore key password: jarsigner: can't jar for signature: Java. Util. Zip. ZipException: invalid entry compressed size (expected 26171 but got 26705 bytes)Copy the code

Since feng-factory. apk is signed, you need to delete the meta-INF folder (remove the old signature file) and sign again. OK. The output is as follows:

. >>> Signer X.509, CN= Lee, OU= Hualee, O= Hualee. Top, L=PK, ST=PK_HD, C=CN [Trusted certificate] JAR Signed. Warning: Signer certificates are self-signed certificatesCopy the code

After signing, let’s check the signature information:

jarsigner -verify -verbose -certs Feng-Factory-signed.apk 
Copy the code

You get the following return:

. - by"CN=lee, OU=hualee, O=hualee.top, L=PK, ST=PK_HD, C=CN"Signature summary algorithm: SHA-256 Signature algorithm: SHA256withRSA, 2048 bits key JAR has been verified.Copy the code

After the signature is modified, APK alignment is required before the application is published. Run the following command:

zipalign -f -v infile.apk outfile.apk
Copy the code

APK alignment first contact… According to the book, it is to improve the efficiency of resource access.

The aligned file can be checked using the following command:

zipalign -c -v 4 test.apk 
Copy the code

Android Signature

The method of Android system signature is different from application signature. In the build/make/target/product/security directory to store the suffix is called 4 groups. X509. Pem and. Pk8 file, as follows:

- security
    - Android.mk
    - README
    - media.pk8
    - media.x509.pem
    - platform.pk8
    - platform.x509.pem
    - shared.pk8
    - shared.x509.pem
    - testkey.pk8
    - testkey.x509.pem
    - verity.pk8
    - verity.x509.pem
    - verity_key
Copy the code
  • *.pk8The file is a private key
  • *.x509.pemThe file is a public key
  • Testkey is used for ordinary APK
  • Platform APK for the system core
  • Shared is used for important APKs such as Launcher and Contacts
  • Media Is the multimedia and download class APK of the system

Generates a signature file for the system

You need to use the development/tools/make_key command in the source code.

Generate the following system signature instructions from make_key:

make_key testkey '/C=CN/ST=PK/L=OK_HD/O=hualee/OU=hualee.top/CN=lee/[email protected]'
Copy the code
  • The first argument is the name of the key, includingmedia,platform,shared,testkey
  • The second parameter is the information about the key, C= country, ST= province, L= Region, O= organization, OU= organization unit, CN= name

Through make_key generated signature file, if all products are to use the same kind of signature, can use the files directly cover the build/make/target/product/security files in the directory. If different products also require different signatures, you can create a directory and specify it by compiling the PRODUCT_DEFAULT_DEV_CERTIFICATE variable. Such as:

PRODUCT_DEFAULT_DEV_CERTIFICATE := # your security files path
Copy the code

When the Build system compiles, the signing is done automatically. The signature in Build is done by signapk.jar with the following instructions:

java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk
Copy the code

Generate a keystore file for the system signature

When we develop system applications, we may need to add system signature files to AS to facilitate debugging.

Here is how to generate a system-signed keystore file:

  • Take source directory of the build/make/target/product/security platform. Pk8 platform. X509. Pem in a directory

  • Pem command: openssl pkcs8 -in platform. pk8-inform DER -outform pem out shared.priv.pem -nocrypt

  • Openssl pkCS12 -export -in platform.x509. Pem -inkey shared.priv.pem -out shared. pk12-name AndroidDebugkey

    • Enter your password, Android
    • Confirm password, Android
  • Generate debug.keystore with the command: keytool -importkeystore -deststorepass android -destkeypass android -destkeystore debug.keystore -srckeystore shared.pk12 -srcstoretype PKCS12 -srcstorepass android -alias androiddebugkey

conclusion

The Android Build system has finally seen the light of day. Although Google has been using Soong to Build the system for a long time, Android’s history is littered with problems. Step by step, the principles should be the same.

After writing this article, I understand the huge Android operating system, and I also understand some of the previously unknown include.

One more thing, Ao ao, want to know how to download the source code? Under the picture yo:

  • Ustc -AOSP(Android) image use help
  • Tsinghua University -Android image use help

No thanks ( ̄_, ̄)