Home | History | Annotate | Download | only in scripts
      1 #!/bin/bash
      2 #
      3 # This script builds the AOSP Android jars, and installs them in your local
      4 # Maven repository. See: http://source.android.com/source/building.html for
      5 # more information on building AOSP.
      6 #
      7 # Usage:
      8 #   build-android.sh <android repo path> <android version> <robolectric version>
      9 #
     10 # For a tutorial check scripts/README.md
     11 
     12 set -ex
     13 
     14 function usage() {
     15     echo "Usage: ${0} <android repo path> <android-version> <robolectric-sub-version> <output directory>"
     16 }
     17 
     18 if [[ $# -ne 4 ]]; then
     19     usage
     20     exit 1
     21 fi
     22 
     23 buildRoot=$1
     24 
     25 if [[ ! -d $buildRoot ]]; then
     26     echo $buildRoot is not a directory
     27     usage
     28     exit 1
     29 fi
     30 
     31 if [[ -z "${SIGNING_PASSWORD}" ]]; then
     32     echo "Please set the GPG passphrase as SIGNING_PASSWORD"
     33     exit 1
     34 fi
     35 
     36 buildRoot=$(cd $buildRoot; pwd)
     37 
     38 ANDROID_VERSION=$2
     39 ROBOLECTRIC_SUB_VERSION=$3
     40 
     41 SCRIPT_DIR=$(cd $(dirname "$0"); pwd)
     42 
     43 ANDROID_SOURCES_BASE=${buildRoot}
     44 FRAMEWORKS_BASE_DIR=${ANDROID_SOURCES_BASE}/frameworks/base
     45 FRAMEWORKS_RAW_RES_DIR=${FRAMEWORKS_BASE_DIR}/core/res/
     46 ROBOLECTRIC_VERSION=${ANDROID_VERSION}-robolectric-${ROBOLECTRIC_SUB_VERSION}
     47 
     48 # Intermediate artifacts
     49 ANDROID_RES=android-res-${ANDROID_VERSION}.jar
     50 ANDROID_EXT=android-ext-${ANDROID_VERSION}.jar
     51 ANDROID_CLASSES=android-classes-${ANDROID_VERSION}.jar
     52 
     53 # API specific paths
     54 LIB_PHONE_NUMBERS_PKG="com/android/i18n/phonenumbers"
     55 LIB_PHONE_NUMBERS_PATH="external/libphonenumber/java/src"
     56 
     57 # Final artifact names
     58 ANDROID_ALL=android-all-${ROBOLECTRIC_VERSION}.jar
     59 ANDROID_ALL_POM=android-all-${ROBOLECTRIC_VERSION}.pom
     60 ANDROID_ALL_SRC=android-all-${ROBOLECTRIC_VERSION}-sources.jar
     61 ANDROID_ALL_DOC=android-all-${ROBOLECTRIC_VERSION}-javadoc.jar
     62 ANDROID_BUNDLE=android-all-${ROBOLECTRIC_VERSION}-bundle.jar
     63 
     64 TZDATA_ARCH="generic_x86"
     65 
     66 build_platform() {
     67     NATIVE_ARTIFACTS=()
     68 
     69     if [[ "${ANDROID_VERSION}" == "4.1.2_r1" ]]; then
     70         ARTIFACTS=("core" "services" "framework" "android.policy" "ext")
     71         SOURCES=(core/java graphics/java media/java location/java opengl/java policy/src sax/java services/java telephony/java wifi/java)
     72     elif [[ "${ANDROID_VERSION}" == "4.2.2_r1.2" ]]; then
     73         ARTIFACTS=("core" "services" "telephony-common" "framework" "android.policy" "ext")
     74         SOURCES=(core/java graphics/java media/java location/java opengl/java policy/src sax/java services/java telephony/java wifi/java)
     75     elif [[ "${ANDROID_VERSION}" == "4.3_r2" ]]; then
     76         ARTIFACTS=("core" "services" "telephony-common" "framework" "android.policy" "ext")
     77         SOURCES=(core/java graphics/java media/java location/java opengl/java policy/src sax/java services/java telephony/java wifi/java)
     78     elif [[ "${ANDROID_VERSION}" == "4.4_r1" ]]; then
     79         ARTIFACTS=("core" "services" "telephony-common" "framework" "framework2" "framework-base" "android.policy" "ext" "webviewchromium" "okhttp" "conscrypt")
     80         SOURCES=(core/java graphics/java media/java location/java opengl/java policy/src sax/java services/java telephony/java wifi/java)
     81     elif [[ "${ANDROID_VERSION}" == "5.0.2_r3" ]]; then
     82         ARTIFACTS=("core-libart" "services" "telephony-common" "framework" "android.policy" "ext" "okhttp" "conscrypt")
     83         SOURCES=(core/java graphics/java media/java location/java opengl/java policy/src sax/java services/java telephony/java wifi/java)
     84         TZDATA_ARCH="generic"
     85     elif [[ "${ANDROID_VERSION}" == "5.1.1_r9" ]]; then
     86         ARTIFACTS=("core-libart" "services" "telephony-common" "framework" "android.policy" "ext" "okhttp" "conscrypt")
     87         SOURCES=(core/java graphics/java media/java location/java opengl/java policy/src sax/java services/java telephony/java wifi/java)
     88         TZDATA_ARCH="generic"
     89     elif [[ "${ANDROID_VERSION}" == "6.0.1_r3" ]]; then
     90         ARTIFACTS=("core-libart" "services" "services.accessibility" "telephony-common" "framework" "ext" "icu4j-icudata-jarjar" "okhttp" "conscrypt")
     91         SOURCES=(core/java graphics/java media/java location/java opengl/java sax/java services/java telephony/java wifi/java)
     92         LIB_PHONE_NUMBERS_PKG="com/google/i18n/phonenumbers"
     93         LIB_PHONE_NUMBERS_PATH="external/libphonenumber/libphonenumber/src"
     94         TZDATA_ARCH="generic"
     95     elif [[ "${ANDROID_VERSION}" == "7.0.0_r1" ]]; then
     96         ARTIFACTS=("core-libart" "services" "services.accessibility" "telephony-common" "framework" "ext" "okhttp" "conscrypt")
     97         NATIVE_ARTIFACTS=("icu4j-icudata-host-jarjar" "icu4j-icutzdata-host-jarjar")
     98         SOURCES=(core/java graphics/java media/java location/java opengl/java sax/java services/java telephony/java wifi/java)
     99         LIB_PHONE_NUMBERS_PKG="com/google/i18n/phonenumbers"
    100         LIB_PHONE_NUMBERS_PATH="external/libphonenumber/libphonenumber/src"
    101     elif [[ "${ANDROID_VERSION}" == "7.1.0_r7" ]]; then
    102         ARTIFACTS=("core-libart" "services" "services.accessibility" "telephony-common" "framework" "ext" "okhttp" "conscrypt")
    103         NATIVE_ARTIFACTS=("icu4j-icudata-host-jarjar" "icu4j-icutzdata-host-jarjar")
    104         SOURCES=(core/java graphics/java media/java location/java opengl/java sax/java services/java telephony/java wifi/java)
    105         LIB_PHONE_NUMBERS_PKG="com/google/i18n/phonenumbers"
    106         LIB_PHONE_NUMBERS_PATH="external/libphonenumber/libphonenumber/src"
    107     elif [[ "${ANDROID_VERSION}" == "8.0.0_r4" ]]; then
    108         ARTIFACTS=("robolectric_android-all")
    109         NATIVE_ARTIFACTS=()
    110         SOURCES=(core/java graphics/java media/java location/java opengl/java sax/java services/java telephony/java wifi/java)
    111     else
    112         echo "Robolectric: No match for version: ${ANDROID_VERSION}"
    113         exit 1
    114     fi
    115 
    116     cd ${ANDROID_SOURCES_BASE}
    117     if [ ! -d out/target/common/obj/JAVA_LIBRARIES ]; then
    118       echo "Robolectric: You need to run 'sync-android.sh' first"
    119       exit 1
    120     fi
    121 }
    122 
    123 build_android_res() {
    124     echo "Robolectric: Building android-res..."
    125     cd ${FRAMEWORKS_BASE_DIR}/core/res; jar cf ${OUT}/${ANDROID_RES} .
    126     src=${ANDROID_SOURCES_BASE}/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk
    127     cp $src ${OUT}/${ANDROID_RES}
    128 }
    129 
    130 build_android_ext() {
    131     echo "Robolectric: Building android-ext..."
    132     mkdir -p ${OUT}/ext-classes-modified/${LIB_PHONE_NUMBERS_PKG}
    133     cd ${OUT}/ext-classes-modified; jar xf ${ANDROID_SOURCES_BASE}/out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar
    134     cp -R ${ANDROID_SOURCES_BASE}/${LIB_PHONE_NUMBERS_PATH}/${LIB_PHONE_NUMBERS_PKG}/data ${OUT}/ext-classes-modified/${LIB_PHONE_NUMBERS_PKG}
    135     cd ${OUT}/ext-classes-modified; jar cf ${OUT}/${ANDROID_EXT} .
    136     rm -rf ${OUT}/ext-classes-modified
    137 }
    138 
    139 build_android_classes() {
    140     echo "Robolectric: Building android-classes..."
    141     mkdir ${OUT}/android-all-classes
    142     for artifact in "${ARTIFACTS[@]}"; do
    143         src=${ANDROID_SOURCES_BASE}/out/target/common/obj/JAVA_LIBRARIES/${artifact}_intermediates
    144         cd ${OUT}/android-all-classes
    145         if [[ -f ${src}/classes.jar ]]; then
    146             jar xf ${src}/classes.jar
    147         else
    148             echo "Couldn't find ${artifact} at ${src}/classes.jar"
    149             exit 1
    150         fi
    151     done
    152 
    153     for artifact in "${NATIVE_ARTIFACTS[@]}"; do
    154         jarPath=${ANDROID_SOURCES_BASE}/out/host/linux-x86/framework/${artifact}.jar
    155         cd ${OUT}/android-all-classes
    156         if [[ -f $jarPath ]]; then
    157             jar xf $jarPath
    158         else
    159             echo "Couldn't find ${artifact} at $jarPath"
    160             exit 1
    161         fi
    162     done
    163     build_tzdata
    164     build_prop
    165     cd ${OUT}/android-all-classes; jar cf ${OUT}/${ANDROID_CLASSES} .
    166     rm -rf ${OUT}/android-all-classes
    167 }
    168 
    169 build_tzdata() {
    170   echo "Robolectric: Building tzdata..."
    171   mkdir -p ${OUT}/android-all-classes/usr/share/zoneinfo
    172   cp ${ANDROID_SOURCES_BASE}/out/target/product/${TZDATA_ARCH}/system/usr/share/zoneinfo/tzdata ${OUT}/android-all-classes/usr/share/zoneinfo
    173 }
    174 
    175 build_prop() {
    176   cp ${ANDROID_SOURCES_BASE}/out/target/product/generic_x86/system/build.prop ${OUT}/android-all-classes
    177 }
    178 
    179 build_android_all_jar() {
    180     echo "Robolectric: Building android-all..."
    181     mkdir ${OUT}/android-all
    182     cd ${OUT}/android-all; unzip ${OUT}/${ANDROID_RES}
    183     # temporarily add raw resources too
    184     cd ${OUT}/android-all; rsync -a ${FRAMEWORKS_RAW_RES_DIR} raw-res
    185     cd ${OUT}/android-all; jar xf ${OUT}/${ANDROID_EXT}
    186     cd ${OUT}/android-all; jar xf ${OUT}/${ANDROID_CLASSES}
    187 
    188     # Remove unused files
    189     rm -rf ${OUT}/android-all/Android.mk
    190     rm -rf ${OUT}/android-all/raw-res/Android.mk
    191     rm -rf ${OUT}/android-all/AndroidManifest.xml
    192     rm -rf ${OUT}/android-all/raw-resAndroidManifest.xml
    193     rm -rf ${OUT}/android-all/META-INF
    194     rm -rf ${OUT}/android-all/MODULE_LICENSE_APACHE2
    195     rm -rf ${OUT}/android-all/raw-res/MODULE_LICENSE_APACHE2
    196     rm -rf ${OUT}/android-all/MakeJavaSymbols.sed
    197     rm -rf ${OUT}/android-all/raw-res/MakeJavaSymbols.sed
    198     rm -rf ${OUT}/android-all/NOTICE
    199     rm -rf ${OUT}/android-all/raw-res/NOTICE
    200     rm -rf ${OUT}/android-all/lint.xml
    201     rm -rf ${OUT}/android-all/raw-res/lint.xml
    202     rm -rf ${OUT}/android-all/java/lang
    203 
    204     # Build the new JAR file
    205     cd ${OUT}/android-all; jar cf ${OUT}/${ANDROID_ALL} .
    206     rm ${OUT}/${ANDROID_RES} ${OUT}/${ANDROID_EXT} ${OUT}/${ANDROID_CLASSES}
    207 }
    208 
    209 cp_android_all_jar() {
    210   # function to use for android versions that support building the android all
    211   # jar directly
    212   # This will just copy the android all jar to the final name
    213   src=${ANDROID_SOURCES_BASE}/out/target/common/obj/JAVA_LIBRARIES/robolectric_android-all-stub_intermediates/classes-with-res.jar
    214   cp $src ${OUT}/${ANDROID_ALL}
    215 }
    216 
    217 build_android_src_jar() {
    218     echo "Robolectric: Building android-all-source..."
    219     local src=${ANDROID_SOURCES_BASE}/frameworks/base
    220     local tmp=${OUT}/sources
    221     mkdir ${tmp}
    222 
    223     for sourceSubDir in "${SOURCES[@]}"; do
    224         rsync -a ${src}/${sourceSubDir}/ ${tmp}/
    225     done
    226     rsync -a ${ANDROID_SOURCES_BASE}/libcore/luni/src/main/java/ ${tmp}/ # this is new
    227     cd ${tmp}; jar cf ${OUT}/${ANDROID_ALL_SRC} .
    228     rm -rf ${tmp}
    229 }
    230 
    231 build_android_doc_jar() {
    232     # TODO: Actually build the docs
    233     echo "Robolectric: Building android-all-javadoc..."
    234     mkdir ${OUT}/javadoc
    235     cd ${OUT}/javadoc; jar cf ${OUT}/${ANDROID_ALL_DOC} .
    236     rm -rf ${OUT}/javadoc
    237 }
    238 
    239 build_signed_packages() {
    240     echo "Robolectric: Building android-all.pom..."
    241     sed s/VERSION/${ROBOLECTRIC_VERSION}/ ${SCRIPT_DIR}/pom_template.xml | sed s/ARTIFACT_ID/android-all/ > ${OUT}/${ANDROID_ALL_POM}
    242 
    243     echo "Robolectric: Signing files with gpg..."
    244     for ext in ".jar" "-javadoc.jar" "-sources.jar" ".pom"; do
    245         ( cd ${OUT} && gpg -ab --passphrase ${SIGNING_PASSWORD} android-all-${ROBOLECTRIC_VERSION}$ext )
    246     done
    247 
    248     echo "Robolectric: Creating bundle for Sonatype upload..."
    249     cd ${OUT}; jar cf ${ANDROID_BUNDLE} *.jar *.pom *.asc
    250 }
    251 
    252 mavenize() {
    253     local FILE_NAME_BASE=android-all-${ROBOLECTRIC_VERSION}
    254     mvn install:install-file \
    255       -Dfile=${OUT}/${FILE_NAME_BASE}.jar \
    256       -DgroupId=org.robolectric \
    257       -DartifactId=android-all \
    258       -Dversion=${ROBOLECTRIC_VERSION} \
    259       -Dpackaging=jar
    260 
    261     mvn install:install-file \
    262       -Dfile=${OUT}/${FILE_NAME_BASE}-sources.jar \
    263       -DgroupId=org.robolectric \
    264       -DartifactId=android-all \
    265       -Dversion=${ROBOLECTRIC_VERSION} \
    266       -Dpackaging=jar \
    267       -Dclassifier=sources
    268 
    269     mvn install:install-file \
    270       -Dfile=${OUT}/${FILE_NAME_BASE}-javadoc.jar \
    271       -DgroupId=org.robolectric \
    272       -DartifactId=android-all \
    273       -Dversion=${ROBOLECTRIC_VERSION} \
    274       -Dpackaging=jar \
    275       -Dclassifier=javadoc
    276 }
    277 
    278 if [[ ! -d "${4}" ]]; then
    279   echo "$4 is not a directory"
    280   exit 1
    281 fi
    282 
    283 OUT=${4}/${ANDROID_VERSION}
    284 mkdir -p ${OUT}
    285 
    286 build_platform
    287 if [[ "${ANDROID_VERSION}" == "8.0.0_r4" ]]; then
    288   cp_android_all_jar
    289 else
    290   build_android_res
    291   build_android_ext
    292   build_android_classes
    293   build_android_all_jar
    294 fi
    295 
    296 build_android_src_jar
    297 build_android_doc_jar
    298 build_signed_packages
    299 mavenize
    300 
    301 echo "DONE!!"
    302 echo "Your artifacts are located here: ${OUT}"
    303