repo: 创建local manifest以及如何添加app到CM/Android build系统中
The local manifest
Creating a local manifest allows you to customize the list of repositories on your copy of the source code by overriding the official manifest. In this way you can add, remove, or replace source code in the official manifest with your own. By pointing to new git repositories, (which need not even reside on the github site,) you can continue to synchronize with the repo sync command just as you would before. Only now, not only are official updates pulled from the regular manifest, but the remote git repositories specified in your manifest will also be checked, and new updates pulled to your source code.
Overriding the manifest
To override the contents of manifest.xml, you will need to write (or borrow) a plaintext XML file that defines the repos you want to pull from. There are two ways you can do this. The old deprecated way is to create a local_manifest.xml in the .repo directory. The new way (available in repo versions >= 1.19) is to create a folder called local_manifests and put that inside the .repo directory, then put your XML inside that directory. You can place as many override files in .repo/local_manifests as you like and repo will pick them up during the next sync. You can call the files anything you like as long as they end in .xml.
An example
Take a look at the following local_manifest.xml file. Then we'll discuss how it works.
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="omap" fetch="git://git.omapzoom.org/" />
<remove-project name="CyanogenMod/android_hardware_ti_omap3" />
<project path="hardware/ti/omap3" name="repo/android/hardware/ti/omap3" remote="omap" revision="jellybean"/>
</manifest>
The first two lines containing <?xml version="1.0" encoding="UTF-8"?> and <manifest> are standard, as is the last line, which contains </manifest>.
Next, a remote for git is declared and given the name "omap". (If you're not familiar with the concept of a remote in git, it essentially refers to a place (and method) for accessing a git repository. See here for more info.) In this case, omapzoom.org is a site that contains special up-to-date repositories for Texas Instrument's OMAP platform.
这个name有两个用途:第一是在manifest.xml中让每个project可以指定remote是谁;第二是这个name会作为属于该remote的每个git project中的remote的名字,所以这个remote的名字就可以在git fetch的时候来使用。
此外注意这个remote中的fetch属性,有的时候会看到定义成“..”。这表示是repo init的时候,指定的URL的上一层。比如repo init -u git://a.com/b,那么此时fetch为..的话就表示fetch的值是git://a.com。这个fetch其实是最终去git fetch每一个git project的时候的一个前缀。最终和git project中的name属性的值拼在一起,成为最终git fetch的target。
找一个manifest.xml来看一遍会体会更深。包括还有如default element,指定default value,也很常用。
完整的manifest.xml的语法在这里:http://git-repo.googlecode.com/git-history/v1.8.1/docs/manifest-format.txt
The next line removes a project (the one at http://www.github.com/cyanogenmod/android_hardware_ti_omap3) declared in the original manifest.xml. It will now no longer be synced with repo sync.
The next line defines a new project. It replaces the one that was removed (from github.com/cyanogenmod) with one from Texas Instruments, using the "omap" remote that was defined above.
When adding a new project that replaces an existing project, you should always remove that project before defining the replacement. However, not every new project need replace an existing cyanogenmod project. You can also simply add a brand-new project to the source code, such as when you want to add your own app to the build.
Note that when adding new projects, there are at least three parts defined:
remote -- the name of the remote. this can be one that was defined in either the regular manifest or local_manifest.xml.
name -- the name of the git project-- for github it has the format account_name/project_name.
path -- where the git repository should go in your local copy of the source code.
revision -- (OPTIONAL) which branch or tag to use in the repository.
After adding .repo/local_manifests/your_file.xml, you should be able to repo sync and the source code should be updated accordingly.
Local Sources
To add local git repositories use something like fetch="file:///path/to/source"
-------------------
Intro: Adding a new app to the build
So after completing a build, people have been asking how to add their own app(s) to the CyanogenMod .zip file.
The "easy" way-- Add it to the zip manually
One way to do this is to simply add the .apk into the .zip and then edit the recovery installation script (written in a simple scripting language called "edify") to copy the file from the .zip to the device.
The "right" way: Make a part of the build repository so it auto-builds
Add app source to /packages/apps
You can do this manually, or you can do it via the .repo/local_manifests/*.xml(参考上面的讲解). If you do it this way, a repo sync will update the source to your app from whatever git repository you name in the local manifest. It's pretty easy to use, and allows you to override/replace/add/remove any official CM repository with one or more of your own.
Determine the name of the project from Android.mk
Regardless of how you put the source in packages/apps/, assuming that the source for the app has an Android.mk Makefile, you can get it to automatically build and install the resulting file in your $OUT directory (and thus your .zip) by simply determining the name of the project, which is typically defined in Android.mk with this:
LOCAL_PACKAGE_NAME := PackageName
以上的做完了,你的APK就会出现在out目录中。如果要进入到最终编译出来的zip(用于recovery刷机)或是img(用于fastboot刷机),还需要做:
Add the project to device.mk (or whatever .mk) in the device folder
Then just add that project to be built in the /device/[MANUFACTURER]/[CODENAME]/device.mk file.
Example:
Let's look at the grouper device aka the Nexus 7. You want to find where the list of packages to build is for this device, in device/asus/grouper/device-common.mk.
Note:
For the nexus 7, the device-common.mk file is shared with the tilapia device (the Nexus 7 GSM version), so if you're building for another device that doesn't have device-common.mk, you'd probably make the edit to device.mk instead.
Now you have a choice. If PRODUCT_PACKAGES was previously defined, you can add a value like this:
PRODUCT_PACKAGES += MyPackageName
The += part means to append it to the list.
Or, if it's simpler, you can just add it to the end an existing PRODUCT_PACKAGES list of projects by appending a "\" to the last item and then adding MyPackageName at the end. Notice that you can't put any commented lines (ie, lines starting with #) or even blank lines in the list of items to be built.
So if the list looks like this...
PRODUCT_PACKAGES := \
lights.grouper \
audio.primary.grouper
...you'd add it to the end:
PRODUCT_PACKAGES := \
lights.grouper \
audio.primary.grouper \
MyPackage
If the source for your app does not have the Android.mk makefile stuff, you'll need to add it. You can use any of the existing packages in packages/apps as a model for what needs to be done to build your particular app.
See http://www.kandroid.org/ndk/docs/ANDROID-MK.html for official documentation on Android .mk files.