├── 00routine.sh ├── 01build-goldfish-kernel.sh ├── 01build-goldfish-module.sh ├── 02build-doc-javadoc.sh ├── 02build-tags.sh ├── 50list-branches.sh ├── 50list-group.sh ├── README.md ├── aosp-screenshot.png ├── common-util ├── install-links.sh ├── lib-common-util └── lib-goldfish-build /00routine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | 3 | pwd=$(pwd) 4 | 5 | # AOSP specific setting 6 | export JAVA_HOME=/opt/java6 7 | export USE_CCACHE=1 8 | mkdir -p ${pwd}/.ccache 9 | export CCACHE_DIR=${pwd}/.ccache 10 | #export ANDROID_PRODUCT_OUT=$(pwd)/out/target/product/generic/ 11 | 12 | source venv/bin/activate 13 | source build/envsetup.sh 14 | 15 | top=$(gettop) 16 | 17 | 18 | # create directories 19 | mkdir -p ${top}/99stuff/{kernel,sdcard}/ 20 | mkdir -p ${top}/99kernel/modules/ 21 | 22 | # building goldfish (emulator) kernel 23 | # env setup for https://github.com/pw4ever/linux-kernel-hacking-helper 24 | export ARENA=${top}/99arena/kernel/ 25 | mkdir -p ${ARENA} 26 | 27 | ## print out the whole procedure 28 | cat - <<'END' 29 | 30 | # the whole procedure; select the ones you need 31 | 32 | # suppose we are at top-level AOSP directory now 33 | bash 34 | source 00routine.sh 35 | lunch aosp_arm-eng 36 | 37 | # obtain Android emulator kernel (goldfish) 38 | cd $(gettop)/99kernel/ 39 | git clone https://android.googlesource.com/kernel/goldfish.git goldfish 40 | cd $(gettop)/99kernel/goldfish/ 41 | git checkout -t -b goldfish-3.4 origin/android-goldfish-3.4 42 | git checkout goldfish-3.4 43 | 44 | # initialize "linux kernel hacking helper" directories ($ARENA has been set up by "source 00routine.sh") 45 | hack_init.sh 10 46 | 47 | # choose the arch you want to build 48 | 49 | # build onto "linux kernel hacking helper" instance 1, on ARM arch, with 8 parallel jobs, and merging kernel configs for KGDB (kernel debugger) and LKM (loadable kernel module) 50 | $(gettop)/01build-goldfish-kernel.sh 1 arm 8 ${HOME}/hacking/linux-kernel/helper/config/kgdb ${HOME}/hacking/linux-kernel/helper/config/lkm 51 | $(gettop)/01build-goldfish-kernel.sh 2 x86_64 8 ${HOME}/hacking/linux-kernel/helper/config/kgdb ${HOME}/hacking/linux-kernel/helper/config/lkm 52 | $(gettop)/01build-goldfish-kernel.sh 3 i686 8 ${HOME}/hacking/linux-kernel/helper/config/kgdb ${HOME}/hacking/linux-kernel/helper/config/lkm 53 | 54 | # build kernel module 55 | cd $(gettop)/99kernel/modules 56 | 57 | # cd into the directory of the module, e.g., "hello" 58 | 59 | # build onto "linux kernel hacking helper" instance 1, on ARM arch, with 8 parallel jobs 60 | $(gettop)/01build-goldfish-module.sh 1 arm 8 61 | END 62 | -------------------------------------------------------------------------------- /01build-goldfish-kernel.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # print the directory that have the scripts (beyond symlinks) 4 | # usage: mydir=$(find_my_dir_beyond_symlink) 5 | #http://stackoverflow.com/a/246128/1527494 6 | function find_my_dir_beyond_symlink 7 | { 8 | local SOURCE="${BASH_SOURCE[0]}" 9 | local DIR 10 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 11 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 12 | SOURCE="$(readlink "$SOURCE")" 13 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located 14 | done 15 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 16 | echo $DIR 17 | } 18 | 19 | mydir=$(find_my_dir_beyond_symlink) 20 | 21 | source ${mydir}/lib-common-util 22 | 23 | usage="$0 []" 24 | 25 | function my_goldfish_build_procedure 26 | { 27 | hack_kernel_config-init.sh ${target_inst} mrproper 28 | hack_kernel_config-init.sh ${target_inst} ${config_name} 29 | # config_to_merge: e.g., ${HOME}/hacking/linux-kernel/helper/config/kgdb and ${HOME}/hacking/linux-kernel/helper/config/lkm 30 | hack_kernel_config-merge.sh ${target_inst} ${config_to_merge} 31 | hack_kernel_build.sh ${target_inst} ${make_jobs} 32 | } 33 | export -f my_goldfish_build_procedure 34 | 35 | source ${mydir}/lib-goldfish-build 36 | -------------------------------------------------------------------------------- /01build-goldfish-module.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # print the directory that have the scripts (beyond symlinks) 4 | # usage: mydir=$(find_my_dir_beyond_symlink) 5 | #http://stackoverflow.com/a/246128/1527494 6 | function find_my_dir_beyond_symlink 7 | { 8 | local SOURCE="${BASH_SOURCE[0]}" 9 | local DIR 10 | while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 11 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 12 | SOURCE="$(readlink "$SOURCE")" 13 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located 14 | done 15 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 16 | echo $DIR 17 | } 18 | 19 | mydir=$(find_my_dir_beyond_symlink) 20 | 21 | source ${mydir}/lib-common-util 22 | 23 | usage="$0 " 24 | 25 | function my_goldfish_build_procedure 26 | { 27 | hack_mod_build.sh ${target_inst} ${make_jobs} 28 | } 29 | export -f my_goldfish_build_procedure 30 | 31 | source ${mydir}/lib-goldfish-build 32 | -------------------------------------------------------------------------------- /02build-doc-javadoc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | 3 | OUTDIR=${OUTDIR:-90doc/javadoc/} 4 | TMPDIR=${TMPDIR:-/tmp/aosp-javadoc/} 5 | 6 | declare -a base_dirs 7 | base_dirs=( frameworks/base libcore out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src ) 8 | 9 | [[ -d ${OUTDIR} ]] && rm -rf ${OUTDIR} 10 | mkdir -p ${OUTDIR} 11 | [[ -d ${TMPDIR} ]] && rm -rf ${TMPDIR} 12 | mkdir -p ${TMPDIR} 13 | 14 | for dir in "${base_dirs[@]}"; do 15 | for d in $(find ${dir} -type d -name java -a ! -regex '.*test.*' -a ! -regex '.*java/java.*'); do 16 | cp -r ${d}/* ${TMPDIR} 17 | done 18 | done 19 | 20 | api_subpackages=$(find ${TMPDIR} -maxdepth 1 -mindepth 1 -type d | perl -wnl -e 'our @a; push @a, $1 if $_=~qr|/([^/]+)$|; END { our @a; print join ":", @a; } ') 21 | 22 | javadoc -d ${OUTDIR} -protected -sourcepath ${TMPDIR} -subpackages ${api_subpackages} 23 | 24 | echo 25 | echo '----------------------------------------' 26 | echo \${BROWSER} ${OUTDIR%/}/index.html 27 | echo '----------------------------------------' 28 | -------------------------------------------------------------------------------- /02build-tags.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | 3 | TAGFILE=${TAGFILE:-cscope.files} 4 | DIRS=${DIRS:-frameworks/base/ frameworks/native/ system/core/ bionic/ libcore/ dalvik/ art/ abi/ libnativehelper/} 5 | 6 | 7 | rm -rf ${TAGFILE} 8 | rm -rf build-tags-*.touch 9 | 10 | touch ${TAGFILE} 11 | 12 | for dir in ${DIRS}; do 13 | find ${dir} -type f -name '*.[ch]' -o -name '*.cpp' -o -name '*.java' >> ${TAGFILE} 14 | done 15 | 16 | ( cscope -k -b -f cscope.out -i ${TAGFILE} && touch build-tags-cscope.touch ) & 17 | ( ctags ${TAGFILE} && touch build-tags-ctags.touch ) & 18 | ( etags ${TAGFILE} && touch build-tags-etags.touch ) & 19 | -------------------------------------------------------------------------------- /50list-branches.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | ( cd .repo/manifests; git pull; git tag -l ) 3 | -------------------------------------------------------------------------------- /50list-group.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | perl -wnl -e 'our @a; push @a, split /,/, $1 if /groups="([^"]+)"/; END {print join "\n", @a}' .repo/manifest.xml | sort | uniq 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* 4 | 5 | - [Android Open Source Project (AOSP) building/testing helper scripts](#android-open-source-project-aosp-buildingtesting-helper-scripts) 6 | - [Cheatsheet](#cheatsheet) 7 | - [One-time setup](#one-time-setup) 8 | - [AOSP building routine](#aosp-building-routine) 9 | - [Build goldfish kernel](#build-goldfish-kernel) 10 | - [Build, install, and test a loadble kernel module](#build-install-and-test-a-loadble-kernel-module) 11 | - [Build Android framework API JavaDoc documentation](#build-android-framework-api-javadoc-documentation) 12 | - [Bonus](#bonus) 13 | 14 | 15 | 16 | # Android Open Source Project (AOSP) building/testing helper scripts 17 | 18 | These scripts help set up AOSP building environment and, with the help of [Linux kernel hacking helper][linux-helper], build and test Android emulator (goldfish) kernel and loadable kernel modules (LKMs). 19 | 20 | ## Cheatsheet 21 | 22 | ### One-time setup 23 | 24 | ```bash 25 | mkdir -p $HOME/hacking/aosp 26 | cd $HOME/hacking/aosp 27 | git clone https://github.com/pw4ever/aosp-hacking-helper.git helper 28 | # cd into AOSP source top directory, say, $HOME/project/aosp 29 | $HOME/hacking/aosp/helper/install-links.sh 30 | ``` 31 | 32 | If you want to use the scripts to build [Android emulator](https://developer.android.com/tools/help/emulator.html) kernel (goldfish), go and set up [Linux kernel hacking helper][linux-helper] at `$HOME/hacking/linux-kernel/helper` (follow [here](https://github.com/pw4ever/linux-kernel-hacking-helper#one-time-setup) for setup instructions). 33 | 34 | ### AOSP building routine 35 | 36 | Every time, before you start [building AOSP](https://source.android.com/source/building-running.html), follow the following routine at the top-level directory of your [downloaded AOSP source](https://source.android.com/source/downloading.html). 37 | 38 | ```bash 39 | # suppose we are at top-level AOSP directory now 40 | bash 41 | source 00routine.sh 42 | lunch aosp_arm-eng # or other lunch combo (tip: use `print_lunch_menu` to see the menu; ${TARGET_PRODUCT}-${TARGET_BUILD_VARIANT}) of your choice 43 | ``` 44 | 45 | For your convenience, `source 00routine.sh` will print out this instruction (and the instructions for building goldfish kernel and LKMs). 46 | 47 | ### Build goldfish kernel 48 | 49 | To build goldfish kernel, you must download it first (as of May 2014, Android kernel source requires *separate* download from the main AOSP source repo). 50 | 51 | ```bash 52 | cd $(gettop)/99kernel/ 53 | git clone https://android.googlesource.com/kernel/goldfish.git goldfish 54 | cd $(gettop)/99kernel/goldfish/ 55 | git checkout -t -b goldfish-3.4 origin/android-goldfish-3.4 # or other version of your choice 56 | 57 | # initialize "linux kernel hacking helper" directories ($ARENA has been set up by "source 00routine.sh") 58 | hack_init.sh 10 59 | ``` 60 | 61 | Choose the target Kernel arch (ARM, x86_64, or i686) and kernel config you want to merge. 62 | 63 | ```bash 64 | # build onto "linux kernel hacking helper" instance 1, on ARM arch, with 8 parallel jobs, and merging kernel configs for KGDB (kernel debugger) and LKM (loadable kernel module) support 65 | $(gettop)/01build-goldfish-kernel.sh 1 arm 8 ${HOME}/hacking/linux-kernel/helper/config/kgdb ${HOME}/hacking/linux-kernel/helper/config/lkm 66 | 67 | # build onto "linux kernel hacking helper" instance 2, on X86_64 arch, with 8 parallel jobs, and merging kernel configs for KGDB (kernel debugger) and LKM (loadable kernel module) support 68 | $(gettop)/01build-goldfish-kernel.sh 2 x86_64 8 ${HOME}/hacking/linux-kernel/helper/config/kgdb ${HOME}/hacking/linux-kernel/helper/config/lkm 69 | 70 | # build onto "linux kernel hacking helper" instance 3, on i686 arch, with 8 parallel jobs, and merging kernel configs for KGDB (kernel debugger) and LKM (loadable kernel module) support 71 | $(gettop)/01build-goldfish-kernel.sh 3 i686 8 ${HOME}/hacking/linux-kernel/helper/config/kgdb ${HOME}/hacking/linux-kernel/helper/config/lkm 72 | ``` 73 | 74 | After building the kernel, the kernel image that can be loaded with `emulator -kernel ` will be found at (take ARM for example, say the "linux kernel hacking helper" instance number is 1 in `01build-goldfish-kernel.sh`) `${ARENA}/build/1/arch/arm/boot/zImage`. 75 | 76 | If you want to test the kernel with a virtual sdcard image, create the sdcard image first: 77 | ```bash 78 | # create a 200M virtual sdcard image with label "label-test01" as the file "$(gettop)/99stuff/sdcard/test01.img" (the directory has been created by "source 00routine.sh" 79 | mksdcar -l label-test01 200M $(gettop)/99stuff/sdcard/test01.img 80 | ``` 81 | 82 | Then, we can test the kernel: 83 | ```bash 84 | emulator -kernel ${ARENA}/build/1/arch/arm/boot/zImage -sdcard $(gettop)/99stuff/sdcard/test01.img & 85 | ``` 86 | 87 | ### Build, install, and test a loadble kernel module 88 | 89 | To build a LKM, `cd` into the directory (perhaps create a directory for your module under `$(gettop)/99kernel/modules/`, e.g., `$(gettop)/99kernel/modules/hello/`), which has your LKM source. The Makefile/Kbuild should have the usual `obj-m += ` variable definitions; read the good old [LDD3](http://www.makelinux.net/ldd3/) or [kernel documentation](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/modules.txt) on this. 90 | 91 | ```bash 92 | # build onto "linux kernel hacking helper" instance 1, on ARM arch, with 8 parallel jobs 93 | $(gettop)/01build-goldfish-module.sh 1 arm 8 94 | ``` 95 | 96 | After this, you should have (suppose your kernel module has `obj-m := hello.o` in Makefile/Kbuild) `hello.ko` in your directory. Now you can push the kernel module onto your emulator instance: 97 | 98 | ```bash 99 | adb -e push hello.ko /data/hello.ko 100 | ``` 101 | 102 | Then, you can test it with: 103 | ```bash 104 | # load the module 105 | adb shell insmod /data/hello.ko 106 | 107 | # unload the module 108 | adb shell rmmod hello 109 | ``` 110 | 111 | ### Build Android framework API JavaDoc documentation 112 | 113 | ```bash 114 | cd $(gettop) 115 | ./02build-doc-javadoc.sh 2> /dev/null 116 | ``` 117 | 118 | Afterwards, the doc will be rooted under `$(gettop)/90doc/javadoc/`. 119 | 120 | ## Bonus 121 | 122 | This is what the build environment (with a running emulator) looks like. 123 | 124 | ![](aosp-screenshot.png) 125 | 126 | The "Kernel version" and "Build number" show that it is running on my own builds. Also, the `adb shell dmesg | tail -3` show that we have successfully loaded and unloaded a test module (loaded by the adb shell session on the right with `insmod /data/hello.ko; rmmod hello`). 127 | 128 | Consider using [my awesome config](https://github.com/pw4ever/awesome-wm-config) if you like the X Window manager. 129 | 130 | [linux-helper]: https://github.com/pw4ever/linux-kernel-hacking-helper "Linux kernel hacking helper" 131 | -------------------------------------------------------------------------------- /aosp-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pw4ever/aosp-hacking-helper/c73cc68b8cf130db1867452bba02a9f275923f13/aosp-screenshot.png -------------------------------------------------------------------------------- /common-util: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # print the directory that have the scripts (beyond symlinks) 4 | # usage: mydir=$(find_my_dir_beyond_symlink) 5 | #http://stackoverflow.com/a/246128/1527494 6 | 7 | 8 | 9 | function error 10 | { 11 | echo $1 12 | exit 1 13 | } 14 | 15 | function usage 16 | { 17 | error "$0 $usage" 18 | } 19 | -------------------------------------------------------------------------------- /install-links.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | source="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | target=$(pwd) 5 | 6 | for f in ${source}/*; do 7 | f=$(basename "$f") 8 | if echo "$f" | perl -wnle 'exit 1 unless /^\d\d/'; then 9 | ln -sf ${source}/$f ${target} 10 | fi 11 | done 12 | -------------------------------------------------------------------------------- /lib-common-util: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | function error 4 | { 5 | echo $1 6 | exit 1 7 | } 8 | 9 | function usage 10 | { 11 | error "$0 $usage" 12 | } 13 | -------------------------------------------------------------------------------- /lib-goldfish-build: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # common part of building goldfish kernel/modules 4 | 5 | # pre-requisite: 6 | # * variable "usage" is defined with the usage text 7 | # * function "my_goldfish_build_procedure" is exported; it has access to these variables: "target_inst" "make_jobs" "config_name" "config_to_merge" 8 | 9 | 10 | target_inst=$1 11 | shift 12 | if [[ -z ${target_inst} ]]; then 13 | usage 14 | fi 15 | 16 | # kernel target arch 17 | arch=$1 18 | shift 19 | arch=${arch:-arm} 20 | 21 | # make jobs 22 | make_jobs=$1 23 | shift 24 | make_jobs=${make_jobs:-8} 25 | 26 | # config to merge 27 | config_to_merge="$@" 28 | 29 | # run in a subshell so do not impact the value of current shell 30 | ( 31 | TOPDIR=$(dirname $0) 32 | 33 | case $arch in 34 | arm) 35 | export ARCH=arm 36 | export SUBARCH=${ARCH} 37 | ;; 38 | x86_64) 39 | export ARCH=x86 40 | export SUBARCH=x86_64 41 | ;; 42 | i686) 43 | export ARCH=x86 44 | export SUBARCH=x86 45 | ;; 46 | *) 47 | usage 48 | ;; 49 | esac 50 | 51 | # adapt from ${TOPDIR}/external/qemu/distrib/build-kernel.sh 52 | export CROSS_COMPILE=$TOPDIR/external/qemu/distrib/kernel-toolchain/android-kernel-toolchain- 53 | 54 | # http://stackoverflow.com/a/20893543/1527494 55 | # prevent "unknown CPU architecture" error 56 | case $arch in 57 | arm) 58 | export REAL_CROSS_COMPILE=${TOPDIR}/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/arm-linux-androideabi- 59 | ;; 60 | x86_64) 61 | export REAL_CROSS_COMPILE=${TOPDIR}/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.7/bin/x86_64-linux-android- 62 | ;; 63 | i686) 64 | export REAL_CROSS_COMPILE=${TOPDIR}/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7/bin/i686-linux-android- 65 | ;; 66 | esac 67 | 68 | config_name= 69 | case $arch in 70 | arm) 71 | # http://stackoverflow.com/a/21274955/1527494 72 | config_name=goldfish_armv7_defconfig 73 | ;; 74 | x86_64|i686) 75 | config_name=goldfish_defconfig 76 | ;; 77 | esac 78 | 79 | my_goldfish_build_procedure 80 | 81 | ) 82 | 83 | # prevent leak afterwards 84 | unset my_goldfish_build_procedure 85 | --------------------------------------------------------------------------------