Vernacular development--DIY Android source code

Source: Internet
Author: User

In the Android Studio code debugging article, there are a few tips on how to debug Android studio code. Now, let's talk about some of the things Android source compiles. (I think that as Android developer everyone should have a copy of their own Android source code, so that we can at any time on their own doubts about the place through the hands of debugging to enhance understanding).

This article uses the latest Ubuntu 16.04, before you start, make sure you've installed git. Students who are not installed can install it by using the following command:

sudo apt-get install git git config –global user.email “[email protected]” git config –global user.name “test”

where [email protected] is your own mailbox.

Before we get to the point, let's take a look at the four processes of Android source code compilation: 1. Download the source code, 2. Build the compilation environment; 3. Compile the source; 4 run. The following will also be described in this procedure.

SOURCE download

As a result of a wall, here we use the domestic image source for download. At present, the available image sources are usually hkust and Tsinghua, the specific use of similar, here I choose the Tsinghua University Mirror to explain. Reference: (hkust source, Tsinghua Source)

Repo Tool download and installation

Implement the following command to download and install the Repo tool

mkdir ~/binPATH=~/bin:$PATHcurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+x ~/bin/repo

Here, let me briefly introduce the next repo tool, we know that the AOSP project is composed of different sub-projects, in order to facilitate management, Google uses git to the AOSP project for multi-warehouse management. Before I talk about repo tools, I'll take you to the multi-warehouse project:

We have a very large project pre, and the project is R1,R2 by many sub-projects,... RN and other components, in order to facilitate management and collaborative development, we create their own warehouse for each sub-project, the structure of the entire project is as follows:

Having a project pre in the library has a problem: if we want to create a pre branch to do feature development, it means that we need to create the corresponding branch in each sub-project, which is a disaster if it is purely by hand. Well, of course we would like to write an automated handler (we assume that this tool is called repoutil) to help us solve this problem. This repoutil also has a need for versioning, so we also use git to manage it and create a corresponding repository for it. The entire project is structured as follows:

Here Repoutil knows each subproject under the pre-project (that is, a list of maintenance sub-projects), and also needs to provide management functions for these sub-projects, such as creating a branch uniformly. But from a "single duty" perspective, the functionality of the REPOUITL tool is too complex, We can completely extract the maintenance sub-project list as a new project Sub_projects, because the sub-project will also change, so to create a corresponding warehouse for it, and git management, so that the repoutil only need to pass the simple to Ub_ Projects is dependent, the entire project is structured as follows:

The AOSP project structure is very similar to what I described above. The Repo tool corresponds to the repoutil,mainfest corresponding to the sub_projects.
To summarize: Repo is a tool that consists of a series of Python scripts that manage the AOSP project by invoking a git command.

Create source folder

Everyone familiar with git should know that we need to create a corresponding warehouse locally for the project. Again, here we create a folder for the code to manage. Here I created the source folder under the current user directory, and all the downloaded source code and the compiled product are placed here. The command is as follows:

sourcecdsource
Initializing the Warehouse

We use the source folder above as the repository, and now we need to initialize the repository. By executing the Initialize Warehouse command, you can obtain the most recent code on the AOSP Project master and initialize the repository, with the following command:

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest

or use:

repo init -u git://aosp.tuna.tsinghua.edu.cn/aosp/platform/manifest

The effect of both is consistent, only the agreement is different.
If the prompt fails to connect to gerrit.googlesource.com during the execution of the command, then we just need to edit the ~/bin/repo file, find the Repo_url line, and modify its contents to:

‘https://gerrit-google.tuna.tsinghua.edu.cn/git-repo‘

Then re-execute the above command.

The manifest command without parameters is used to get the latest code on the master, sometimes we want to specify a version of the source, at this time can be specified by the-b parameter to get a specific version of Android, such as we want to get ANDROID-4.0.1_R1 branch, Then the command is as follows:

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-4.0.1_r1

(Here Aosp the current list of all branches of the project can be viewed on the official website: Branch list)

Synchronize source to Local

Once the repository is initialized, you can begin to formally synchronize the code locally, with the following command:

repo sync

In the future, if you need to synchronize remote code locally, you only have to execute the command. During the synchronization process, if the network is interrupted, use this command to continue the synchronization. No accident, you can synchronize all the source code to local in 5 hours. So, this process can be done at night during sleep.

(Hint: Make sure that the code is fully synchronized, or the following compilation process errors will make you miserable, uncertain children's shoes can be more repo Sync sync several times)

Building a compilation environment

After the source download is complete, you can build the environment. Before we begin, let's look at some of the compilation requirements:

1. Hardware Requirements:
64-bit operating system can only compile more than 2.3.x version, if you want to compile 2.3.x below, then requires 32-bit operating system.
The more disk space, the better, at least 100GB or more. That means you can buy a bigger hard drive.
If you want to run Linux on a virtual machine, then you need at least 16GB of Ram/swap.
(In fact, I highly recommend compiling more than 2.3.x of code in a virtual machine.)

2. Software Requirements:
1. Operating System Requirements
In AOSP Open source, the main branch is developed and tested using Ubuntu long-term versions, so it is also recommended that you compile with Ubuntu, below we list different versions of Ubuntu to compile those Android versions:

Android version compile the required Ubuntu minimum version
Android 6.0 to AOSP Master Ubuntu 14.04
Android 2.3.x to Android 5.x Ubuntu 12.04
Android 1.5 to Android 2.2.x Ubuntu 10.04

2. JDK Version Requirements
In addition to the operating system version of this issue, we also need to focus on the JDK version of the problem, for convenience, we also listed the different versions of the Android version of the source code needs to use the JDK version:

Android version compile the required JDK version
Aosp's Android Mainline OpenJDK 8
Android 5.x to Android 6.0 OpenJDK 7
Android 2.3.x to Android 4.4.x Oracle JDK 6
Android 1.5 to Android 2.2.x Oracle JDK 5

More specific can be see: Google source code compilation requirements

I am now compiling the AOSP mainline code under Ubuntu 16.04, so I need to install OPENJDK 8 and execute the following command:
sudo apt-get install openjdk-8-jdk
If you need to compile the AOSP mainline code under Ubuntu 14.04 and also need to install OPENJDK 8, you need to execute the following command:

sudo apt-get updatesudo apt-get install openjdk-8-jdk

If you are compiling a system version of Android 5.x to Android 6.0, you need to use OPENJDK7. However, only openjdk8 and OPENJDK9 installations are supported in the Ubuntu 15.04 and later versions of the online installation library. Therefore, If you want to install OPENJDK 7 you need to set the PPA first:

sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update

Then execute the installation command:

sudo apt-get install openjdk-7-jdk

Sometimes we need to compile different versions of the Android system, and we may use different JDK versions. For JDK version switching, you can use the following command:

sudo update-alternative --config javasudo update-alternative --config javac

3. Other requirements

The Google official build environment guide has already explained the dependencies that Ubuntu14.04,ubuntu 12.04,ubuntu 10.04 needs to add, and we're not going to introduce them here. I thought, The settings of Ubuntu16.04 and Ubuntu14.04 should be similar, but only too young too simple.
The following are the dependency settings in Ubuntu16.04:

sudo apt-getInstall libx11-dev: i386 Libreadline6-dev: i386 LIBGL1-mesa-devG++-Multilib sudo apt-getInstall- yGIT Flex Bison gperf Build-essentialLibncurses5-dev: i386 sudo apt-getInstall Tofrodos python-markdownLibxml2-utilsXsltproc zlib1g-dev: i386 sudo apt-getInstall dpkg-devLibsdl1. 2-devLibesd0-devsudo apt-getInstall Git-coreGNUPG Flex Bison Gperf Build-essentialsudo apt-getInstall Zip Curl zlib1g-devGcc-multilibG++-Multilib sudo apt-getInstall LIBC6-dev-i386sudo apt-getInstall LIB32NCURSES5-devX11proto-core-devLibx11-devsudo apt-getInstall LIBGL1-mesa-devLibxml2-utilsXsltproc Unzip M4sudo Apt-getInstall lib32z-devCCache

(Several of the arguments in the command are duplicates but do not hinder us)

Initializing the compilation environment

After making sure that the above process is complete, we need to initialize the compilation environment with the following command:

source build/envsetup.sh

The result of executing the command is as follows:

It is not difficult to find that the command simply introduces other execution scripts, and what these scripts do are not currently covered in this article.
After the command has been executed successfully, we get some useful commands, such as the lunch command that is used at the bottom.

Compiling source code

After initializing the compilation environment, we formally enter the source code compilation phase. This phase includes two phases: Select the build version and perform the compilation.

Select the compilation target

Set the specific version to be compiled with the lunch directive. For example, here we are compiling Aosp_arm64-eng, so execute the instructions:

lunch aosp_arm64-eng

If you don't know what version you want to compile, you only need to execute the lunch instruction without parameters. After that, the console lists all the device models and compilation types supported by the current source:

Then, depending on your needs, you can enter the appropriate number. Typically, we choose Aosp_arm-eng, but when you start a virtual machine after compiling in Ubuntu 16.04 (64-bit), you may experience a black screen or no response, and you might want to use AOSP_ Arm64-eng. Here, I choose 2, namely Aosp_arm64-eng

Our simple introduction, compiled version of the command rules, is in the form of Build-buildtype.
Build refers to the name of a specific set of code for a particular function, the environment in which the source can run, such as full to represent the emulator.

The build type refers to the compilation types, usually with three kinds:
-user: The first access, applies to the release version of the product.
-userdebug: Similar to user mode, but with root privileges and debugging capabilities for debugging.
-eng: Engineering mode with additional debugging tools.
It is not difficult to find that we need to compile in eng mode so that we can debug.

Start compiling

Code compilation through the make directive, which can specify -j parameters to set the number of threads participating in the compilation to improve compilation speed. For example, here we set 8 threads to compile at the same time:

-j8

It is important to note that the number of threads involved in compiling is not as good as possible, usually based on the core of your machine Cup: core*2, which is twice times the core of the current CPU. For example, my notebook is a dual core four thread, so according to the formula, the fastest compilation can be make-j8.
(by cat /proc/cpuinfo viewing the relevant CPU information)

If all goes well, after a few hours, it can be compiled. See ### make completed successfully (01:18:45(hh:mm:ss)) ### that you have compiled successfully.

Running the emulator

After the compilation is complete, you can run the Android virtual machine with the following command, as follows:

source build/envsetup.shlunch(选择刚才你设置的目标版本,比如这里了我选择的是2)emulator

If you are running the virtual machine immediately after compiling, since we have already executed the source and lunch commands, now you just need to execute the command to run the virtual machine:

emulator

No surprises, after waiting for a while, you will see the running interface:

Now that we've talked about the simulator run, here's a description of the four files required for the simulator to run:
1. Linux Kernel
2. system.img
3. userdate.img
4. ramdisk.img
(Here, for the time being no explanation)
If you select Aosp_arm-eng when you use the lunch command, the Linux kernel uses the Kernel-qemu file in the directory by default when executing the emualtor command without parameters /source/prebuilds/qemu-kernel/arm/kernel-qemu ; The Android image file is the default source/out/target/product/generic directory of System.img,userdata.img and Ramdisk.img, which is the image file we just compiled.

I chose Aosp_arm64-eng when I used the lunch command, so Linux defaults to /source/prebuilds/qemu-kernel/arm64/kernel-qemu Kernel-qemu, while the other files are source/out/target/product/generic64 system.img under the directory used. Userdata.img and Ramdisk.img.

Module compilation

Compiling the entire Android source code with the make command is a relatively small requirement. More often, we modify or add some modules, so how do we compile a separate module?

Google also provides the developer with the appropriate commands to support the compilation of individual modules. Above we mentioned that envsetup.sh gave us some commands, in addition to the lunch we used above, as well as these:

  - croot: Changes directory to the top of the tree.  - m: Makes from the top of the tree.  - mm: Builds all of the modules in the current directory.  - mmm: Builds all of the modules in the supplied directories.  - cgrep: Greps on all local C/C++ files.  - jgrep: Greps on all local Java files.  - resgrep: Greps on all local res/*.xml files.  - godir: Go to the directory containing a file.

What I use most here is MMM, which is used to compile the specified directory. In general, each directory contains only one module. For example, here we compile the Launcher2 module:

mmm packages/apps/Launcher2/

After a while, if the prompt means that the ### make completed success fully ### compilation is complete, out/target/product/gereric/system/app you can see the compiled launcher2.apk file now.

After compiling the specified module, if we want to integrate the module's apk into the system image, we need to use it make snod . So our newly generated system.img contains the Launcher2 module we just compiled. Takes effect after restarting the emulator.

We are constantly modifying some modules, we can not always re-system.img after each recompile, and then restart the phone. Is there any easy way?
At this point, after compiling, with the ADB install command to directly install the generated APK file on the device, compared to using make snod, a lot faster.

Let's simply introduce a directory out/target/product/generic/system of common directories:
The APK files from the Android system are all in the out/target/product/generic/system/apk directory;
Some executable files (such as the execution of C compilation), are placed in the out/target/product/generic/system/bin directory;
The dynamic link library is placed in the out/target/product/generic/system/lib directory;
The hardware abstraction layer files are placed in the out/targer/product/generic/system/lib/hw directory.

SDK compilation

If you need to compile the SDK yourself, it's simple, just execute the command make sdk .

Error collection

In the process of compiling, we will basically encounter a variety of errors, most of which we can search for a response in Google Solutions. Here are just a few of the mistakes I've encountered:
Error One: You were attemping to build with the incorrect version. The specific error is as follows:


This problem can be avoided if you take a serious look at the requirements of the build environment. Of course, it's easy to fix it: Install OpenJDK 8, and don't forget to switch the JDK version with the sudo update-alternative command.

Error two: Out of memory error. The specific error is as follows:


This error is more common, especially when compiling the AOSP mainline code, which is often caused by the JVM heap size being too small.
There are two ways to resolve this:
method One:
Before compiling the command, modify the Prebuilts/sdk/tools/jack-admin file to find this line in the file:
JACK_SERVER_COMMAND="java -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"
Then add-xmx4096m on the line, such as:
JACK_SERVER_COMMAND="java -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"
Then execute time make-8j

Method Two:
In the console, execute the following command:

export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m"out/host/linux-x86/bin/jack-admin kill-serverout/host/linux-x86/bin/jack-admin start-server

:

After executing the command, use the make command to continue compiling. In some cases, when you execute Jack-admin kill-server you may be prompted that the command does not exist, at which point you go to out/host/linux-x86/bin/ The Jack-admin file does not exist in the directory. If I were you, I would repo sync again and start over.

error Three: When using emulator, the virtual machine stops at the black screen and clicks no response. This may be the Kiner kernel issue, the workaround is as follows:
Execute the following command:

./out/host/linux-x86-partition-size1024-kernel./prebuilts/qemu-kernel/arm/kernel-qemu-armv7

Resolve the emulator to wait for a black screen problem by using the KERNEL-QEMU-ARMV7 kernel. while-partition-size 1024 resolves the warning: System partion Siez adjusted to match image file (163 MB >66 MB) issue.

If you start compiling the version is Aosp_arm-eng, using the above command still does not solve the problem of waiting for the black screen, you might want to compile Aosp_arm64-eng try.

So far, we have explained the entire Android compilation process, in addition to the simple Android source of multi-warehouse management mechanism. Below, you need to, automatically, to compile a copy of the source code. Back, I'll continue on this basis to add some explanation of the principle, and combined with Android studio for source debugging.

Vernacular development--DIY Android source code

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.