An overview of the

The Android Build system is a set of frameworks used to Build the Android system, Android SDK, and related documentation. In the Android system, the Android source code contains many modules. Android customization is different for different devices from different manufacturers. How to manage these modules in a unified way, how to compile on different operating systems, how to compile for different hardware devices, different compilation types, and provide customized extensions for each manufacturer, how does Android solve these problems? This is the Android Build we have to talk about.

Android source directory structure:

Linux make command

Before we get to Android, we need to understand the make command for Linux. On Linux, you can compile code with the make command. By default, the Make command finds a Makefile in the current directory and compiles the code according to the instructions in the Makefile. Such as GCC, Linux system in the shell command cp, rm and so on.

What is the difference between a shell command and a make command? The make command actually does this through a shell command, but the magic of it is that it helps you handle dependencies between files. For example, there is a file T that depends on another file D and requires that file T be regenerated only when the contents of file D change.

How does the Make command know that there is a dependency between two files and what to do with the target file when the dependent file changes? The answer is in the Makefile mentioned earlier. A Makefile file is actually a script file, just like a normal shell script file, except it follows the Makefile syntax. The most basic function of makefiles is to describe the dependencies between files and how to handle those dependencies.

The Android Build profile

The Android Build system is a part of the Android system. It is used to compile the Android system, Android SDK, and related documents. The system is mainly composed of Make files, Shell scripts and Python scripts. Android build

  • Build /core, which is the core of the Android build framework.
  • The file in the device directory stores specific product configuration files.
  • The compilation file of each module: Android.mk, located in the original file directory of the module.

Android Build system core

The Build /core directory contains mk files, shell scripts, and PER scripts that form the basis and architecture of the Android Build system.

In buil/core, the system does three main things:

Common commands:

source build/envsetup.sh
lunch
make
Copy the code

envsetup.sh

There are three main things that build/envsetup.sh does:

To compile for Android, you must first execute the envsetup.sh script, which sets up the Android build environment. This is done by setting up the shell command and calling the add_lunch_combo command, which stores the parameters passed for calling the command into a global array variable called LUNCH_MENU_CHOICES.

Common shell commands defined in the envsetup.sh script:

The command instructions
contact-button Specifies the currently compiled product
croot Quickly switch to the source code root directory for easy compilation
m Compile the entire source without switching the current directory to the source root
mm Compile all modules in the current directory, but not their dependencies
mm Compile all modules in the current directory, but not their dependencies
cgrep Run the grep command for all C/C++ files in the system
sgrep Run the grep command for all source files in the system

Compiling Android

Currently, the Compilation environment for Android only supports Ubuntu and Mac OS. We need to obtain the complete Android source code before compiling the Android system. Open the console, go to the root directory of the Android source code, and execute the following name:

source build/envsetup.sh 
lunch full-eng 
make -j8
Copy the code

The meaning of these commands has been mentioned above. The first command “source build/envsetup.sh” introduces the build/envsetup.sh script, which initializes the compilation environment and introduces some auxiliary Shell functions.

The second step of the command “lunch full-eng” is to call the lunch function and specify the argument as “full-eng”. The arguments to the lunch function are used to specify the target device and build type for this build.

The third command, “make-j8,” actually starts compiling. The “-j” argument to make specifies the number of concurrent jobs to be compiled. This is an integer that is usually 1 or 2 times the number of concurrent threads supported by the compilation host CPU (for example: On a 4-core CPU with two threads per core, either make-j8 or make-j16 can be used. The complete compile time depends on the configuration of the compile host.

The Build results

All compilations will be in the /out directory, which contains:

  • /out/host/ : This directory contains the products of Android development tools for the host. That is, various tools in SDK, such as emulator, ADB, AAPT, etc.
  • /out/target/common/ : This directory contains common compilations for devices, mainly Java application code and Java libraries.
  • /out/target/product// : contains device-specific compilation results and platform-specific C/C++ libraries and binaries. In the command, is the name of the target device.
  • /out/dist/ : contains packages for multiple distributions. Copy files to this directory by “make disttarget”. The default compilation target does not produce this directory.

Build Generated image file

The most important Build artifacts are the three image files in the /out/target/product// directory:

  • System. img: Contains the Android OS system files, libraries, executables, and preset applications, which will be mounted as the root partition.
  • Ramdisk. img: Will be mounted by the Linux kernel as a read-only partition at startup, which contains the /init file and some configuration files. It is used to mount other system images and start the init process.
  • Userdata.img: will be mounted as /data, which contains application-related data and user-related data.

Make file

The entry file for the entire Build system is a file named “Makefile” in the root directory of the source code, which is read first by the make command when called in the root directory. The contents of the Makefile are just one line: “include build/core/main.mk”. The purpose of this line of code is obvious: include the build/core/main.mk file. The main.mk file will contain other files, and other files will contain more files, introducing the entire Build system.

The relationships between Make files are quite complex throughout the Build system. Look at the main diagram of the make file:

Make common files:

The file name instructions
main.mk The main Make file, which first checks the build environment and introduces the other Make files. In addition, this file defines several of the most important Make targets, such as droid, SDK, and so on (see “Make targets” below).
help.mk Contains the definition of a Make target named help that lists the main Make targets and their descriptions.
envsetup.mk Configure environment variables required by the Build system, such as TARGET_PRODUCT, TARGET_BUILD_VARIANT, HOST_OS, and HOST_ARCH. The current compiled host platform information (such as operating system, CPU type, etc.) is determined in this file. In addition, the file specifies the output path for the various compilation results.
pathmap.mk Define the paths of many header files as mapping tables in the form of name-value pairs and provide the include-path-for function to get them. For example, $(call include-path-for, frameworks-native) can be used to retrieve the header file path required by the framework’s native code.
combo/select.mk Select platform-specific Make files based on the platform of the current compiler.
dumpvar.mk Displays the configuration information for the Build before it starts.
config.mk Configuration file for the entire Build system, one of the most important Make files. This file contains the following contents: defines a number of constants responsible for the compilation of different types of modules. Define compiler parameters and common file suffixes such as.zip,.jar. Apk. Configure parameters related to the product according to the boardconfig. mk file. Set the path of some common tools, such as flex, e2fsck, dx.
definitions.mk One of the most important Make files, in which a large number of functions are defined. These functions are used by other files in the Build system. For example: my-dir, all-subdir-makefiles, find-subdir-files, sign-package, etc. Please refer to the code comments of each function for a description of these functions.
distdir.mk Definition of dist goals. The dist target is used to copy files to the specified path
dex_preopt.mk Pre-optimizations for boot JAR packages.
pdk_config.mk As the name implies, a configuration file for PDK (Platform development Kit).
post_clean.mk Check the configuration of the current Build based on the previous Build and clean up as necessary.
legacy_prebuilts.mk Only the GRANDFATHERED_ALL_PREBUILT variable is defined in this file.
Makefile Contained by main.mk, the contents of this file are some additional content to assist main.mk.
The name of the instructions
apps_only This target will compile applications in the current configuration that do not contain user, UserDEBUG, eng tags (for tags, see “Adding a new module” below).
droidcore The goal is simply a combination of several dependent goals and does no more processing on its own.
dist_files This target is used to copy files to the /out/dist directory.
files The goal is simply a combination of several dependent goals and does no more processing on its own
prebuilt The target depends on $(ALL_PREBUILT), which is used to process all the compiled files.
$(modules_to_install) The modules_to_install variable contains all modules that will be installed under the current configuration (whether a module will be installed depends on the product’s configuration file, module labels, etc.), so this goal will result in the compilation of all modules that will be installed.
$(modules_to_check) This goal is to ensure that the building blocks we define are not redundant.
$(INSTALLED_ANDROID_INFO_TXT_TARGET) The target will generate a equipment information about the current Build configuration file, the file path is generated: the out/target/product / / android – info. TXT
systemimage Generating system. Img.

Some other Make targets included in the Build system:

Make target instructions
make clean To clear data, run the rm -rf out/ command
make sdk Build the SDK for Android
Make target instructions
make clean-sdk Clean up SDK builds
make update-api Update the API. This command is used to update frameworks after changes to the Framework API. The exposed API is documented in the frameworks/base/ API directory.
make dist Execute Build and copy the output file of the MAKECMDGOALS variable definition to the /out/dist directory
make all Compile everything, whether or not it is included in the current product definition
make help Help information
make snod Quickly rebuild system images from compiled packages
make libandroid_runtime Compile all JNI Framework content
makeframework Compile all Java Framework content
makeservices Compile system services and related content
make Compiles a specified module with local_target as the module name
make clean- Clears the compilation result of a specified module
makedump-products Displays the build configuration information for all products, such as the product name, supported languages, and modules included in the product
makePRODUCT-xxx-yyy Builds a specified product
makebootimage Generate the boot img
The name of the instructions
eng The default type, which is compiled for the development phase. When this type is selected, the result of compilation will be: Install modules with ENG, DEBUG, User, development tags Install all non-APK modules without labels Install all APK modules specified in the product definition file
user This compilation type is suitable for the final release phase. When this type is selected, the result of compilation will be: Install all modules with the User label install all non-APK modules without labels Install all APK modules specified in the product definition file, and the label of the APK module will be ignored
userdebug This compilation type is suitable for the debug phase. This type is the same as user, except that modules containing the DEBUG tag are installed to compile systems with root access

Depending on how the various types of modules in the table above are compiled, to perform compilation, just import the corresponding Make files in Table 3. For example, to compile an APK file, simply add “include $(BUILD_PACKAGE)” to the Android.mk file. In addition, Build defines a number of handy functions for use in Android.mk, including:

  • $(call my-dir) : gets the current folder path.
  • $(call all-java-files-under,) : gets all Java files in the specified directory.
  • $(call all-c-files-under,) : gets all C files in the specified directory.
  • $(call all-iaidl-files-under,) : gets all AIDL files in the specified directory.
  • $(call all-makefiles-under,) : gets all Make files in the specified directory.
  • $(Call intermediates-dir-for,,,,) : Gets the path to the target folder for Build output.

For example, compile an APK file

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Obtain Java files in all subdirectories LOCAL_SRC_FILES := $(call all-subdir-java-files) Static Java libraries that the current module depends on, If there are multiple Spaces delimited LOCAL_STATIC_JAVA_LIBRARIES := static-library # Name of the current module LOCAL_PACKAGE_NAME := LocalPackage # Compile the APK file include $(BUILD_PACKAGE)Copy the code

To compile a Java static library:

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Obtain Java files in all subdirectories LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_JAVA_LIBRARIES := Android.test. runner # LOCAL_MODULE := sample # Compile the current module into a static Java library  include $(BUILD_STATIC_JAVA_LIBRARY)Copy the code

Attached: Android compilation system details