Home | History | Annotate | Download | only in etc
      1 #!/bin/bash
      2 #
      3 # Copyright (C) 2008 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #     http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 # Stop if something fails.
     18 set -e
     19 
     20 # Set default values for directories.
     21 if [ -d smali ]; then
     22   HAS_SMALI=true
     23 else
     24   HAS_SMALI=false
     25 fi
     26 
     27 if [ -d src ]; then
     28   HAS_SRC=true
     29 else
     30   HAS_SRC=false
     31 fi
     32 
     33 if [ -d src2 ]; then
     34   HAS_SRC2=true
     35 else
     36   HAS_SRC2=false
     37 fi
     38 
     39 if [ -d src-multidex ]; then
     40   HAS_SRC_MULTIDEX=true
     41 else
     42   HAS_SRC_MULTIDEX=false
     43 fi
     44 
     45 if [ -d smali-multidex ]; then
     46   HAS_SMALI_MULTIDEX=true
     47 else
     48   HAS_SMALI_MULTIDEX=false
     49 fi
     50 
     51 if [ -d src-ex ]; then
     52   HAS_SRC_EX=true
     53 else
     54   HAS_SRC_EX=false
     55 fi
     56 
     57 if [ -d src-dex2oat-unresolved ]; then
     58   HAS_SRC_DEX2OAT_UNRESOLVED=true
     59 else
     60   HAS_SRC_DEX2OAT_UNRESOLVED=false
     61 fi
     62 
     63 # Allow overriding ZIP_COMPRESSION_METHOD with e.g. 'store'
     64 ZIP_COMPRESSION_METHOD="deflate"
     65 # Align every ZIP file made by calling $ZIPALIGN command?
     66 WITH_ZIP_ALIGN=false
     67 ZIP_ALIGN_BYTES="-1"
     68 
     69 DX_FLAGS=""
     70 SKIP_DX_MERGER="false"
     71 EXPERIMENTAL=""
     72 
     73 # The key for default arguments if no experimental things are enabled.
     74 DEFAULT_EXPERIMENT="no-experiment"
     75 
     76 # Setup experimental flag mappings in a bash associative array.
     77 declare -A JACK_EXPERIMENTAL_ARGS
     78 JACK_EXPERIMENTAL_ARGS["agents"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
     79 JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
     80 JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
     81 JACK_EXPERIMENTAL_ARGS["method-handles"]="-D jack.java.source.version=1.7 -D jack.android.min-api-level=o-b1"
     82 JACK_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
     83 
     84 declare -A SMALI_EXPERIMENTAL_ARGS
     85 SMALI_EXPERIMENTAL_ARGS["default-methods"]="--api-level 24"
     86 SMALI_EXPERIMENTAL_ARGS["method-handles"]="--api-level 26"
     87 SMALI_EXPERIMENTAL_ARGS["agents"]="--api-level 26"
     88 
     89 declare -A JAVAC_EXPERIMENTAL_ARGS
     90 JAVAC_EXPERIMENTAL_ARGS["default-methods"]="-source 1.8 -target 1.8"
     91 JAVAC_EXPERIMENTAL_ARGS["lambdas"]="-source 1.8 -target 1.8"
     92 JAVAC_EXPERIMENTAL_ARGS["method-handles"]="-source 1.8 -target 1.8"
     93 # We need to leave javac at default 1.7 so that dx will continue to work
     94 JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.8 -target 1.8"
     95 JAVAC_EXPERIMENTAL_ARGS["agents"]="-source 1.8 -target 1.8"
     96 
     97 while true; do
     98   if [ "x$1" = "x--dx-option" ]; then
     99     shift
    100     option="$1"
    101     DX_FLAGS="${DX_FLAGS} $option"
    102     shift
    103   elif [ "x$1" = "x--jvm" ]; then
    104     shift
    105   elif [ "x$1" = "x--no-src" ]; then
    106     HAS_SRC=false
    107     shift
    108   elif [ "x$1" = "x--no-src2" ]; then
    109     HAS_SRC2=false
    110     shift
    111   elif [ "x$1" = "x--no-src-multidex" ]; then
    112     HAS_SRC_MULTIDEX=false
    113     shift
    114   elif [ "x$1" = "x--no-smali-multidex" ]; then
    115     HAS_SMALI_MULTIDEX=false
    116     shift
    117   elif [ "x$1" = "x--no-src-ex" ]; then
    118     HAS_SRC_EX=false
    119     shift
    120   elif [ "x$1" = "x--no-smali" ]; then
    121     HAS_SMALI=false
    122     shift
    123   elif [ "x$1" = "x--experimental" ]; then
    124     shift
    125     # We have a specific experimental configuration so don't use the default.
    126     DEFAULT_EXPERIMENT=""
    127     EXPERIMENTAL="${EXPERIMENTAL} $1"
    128     shift
    129   elif [ "x$1" = "x--zip-compression-method" ]; then
    130     # Allow using different zip compression method, e.g. 'store'
    131     shift
    132     ZIP_COMPRESSION_METHOD="$1"
    133     shift
    134   elif [ "x$1" = "x--zip-align" ]; then
    135     # Align ZIP entries to some # of bytes.
    136     shift
    137     WITH_ZIP_ALIGN=true
    138     ZIP_ALIGN_BYTES="$1"
    139     shift
    140   elif expr "x$1" : "x--" >/dev/null 2>&1; then
    141     echo "unknown $0 option: $1" 1>&2
    142     exit 1
    143   else
    144     break
    145   fi
    146 done
    147 
    148 # Be sure to get any default arguments if not doing any experiments.
    149 EXPERIMENTAL="${EXPERIMENTAL} ${DEFAULT_EXPERIMENT}"
    150 
    151 if [ "${JACK_SERVER}" = "false" ]; then
    152   # Run in single-threaded mode for the continuous buildbot.
    153   JACK_ARGS="${JACK_ARGS} -D sched.runner=single-threaded"
    154 else
    155   # Run with 4 threads to reduce memory footprint and thread contention.
    156   JACK_ARGS="${JACK_ARGS} -D sched.runner=multi-threaded"
    157   JACK_ARGS="${JACK_ARGS} -D sched.runner.thread.kind=fixed"
    158   JACK_ARGS="${JACK_ARGS} -D sched.runner.thread.fixed.count=4"
    159 fi
    160 
    161 # Add args from the experimental mappings.
    162 for experiment in ${EXPERIMENTAL}; do
    163   JACK_ARGS="${JACK_ARGS} ${JACK_EXPERIMENTAL_ARGS[${experiment}]}"
    164   SMALI_ARGS="${SMALI_ARGS} ${SMALI_EXPERIMENTAL_ARGS[${experiment}]}"
    165   JAVAC_ARGS="${JAVAC_ARGS} ${JAVAC_EXPERIMENTAL_ARGS[${experiment}]}"
    166 done
    167 
    168 #########################################
    169 
    170 # Catch all commands to 'ZIP' and prepend extra flags.
    171 # Optionally, zipalign results to some alignment.
    172 function zip() {
    173   local zip_target="$1"
    174   local entry_src="$2"
    175   shift 2
    176 
    177   command zip --compression-method "$ZIP_COMPRESSION_METHOD" "$zip_target" "$entry_src" "$@"
    178 
    179   if "$WITH_ZIP_ALIGN"; then
    180     # zipalign does not operate in-place, so write results to a temp file.
    181     local tmp_file="$(mktemp)"
    182     "$ZIPALIGN" -f "$ZIP_ALIGN_BYTES" "$zip_target" "$tmp_file"
    183     # replace original zip target with our temp file.
    184     mv "$tmp_file" "$zip_target"
    185   fi
    186 }
    187 
    188 if [ -e classes.dex ]; then
    189   zip $TEST_NAME.jar classes.dex
    190   exit 0
    191 fi
    192 
    193 if ! [ "${HAS_SRC}" = "true" ] && ! [ "${HAS_SRC2}" = "true" ]; then
    194   # No src directory? Then forget about trying to run dx.
    195   SKIP_DX_MERGER="true"
    196 fi
    197 
    198 if [ ${HAS_SRC_DEX2OAT_UNRESOLVED} = "true" ]; then
    199   mkdir classes
    200   mkdir classes-ex
    201   ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src-dex2oat-unresolved -d classes `find src -name '*.java'`
    202   ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src -d classes-ex `find src-dex2oat-unresolved -name '*.java'`
    203   if [ ${USE_JACK} = "true" ]; then
    204     jar cf classes.jill.jar -C classes .
    205     jar cf classes-ex.jill.jar -C classes-ex .
    206 
    207     ${JACK} --import classes-ex.jill.jar --output-dex .
    208     zip ${TEST_NAME}-ex.jar classes.dex
    209     ${JACK} --import classes.jill.jar --output-dex .
    210   else
    211     if [ ${NEED_DEX} = "true" ]; then
    212       ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 ${DX_FLAGS} classes-ex
    213       zip ${TEST_NAME}-ex.jar classes.dex
    214       ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 ${DX_FLAGS} classes
    215     fi
    216   fi
    217 else
    218   if [ ${USE_JACK} = "true" ]; then
    219     # Jack toolchain
    220     if [ "${HAS_SRC}" = "true" ]; then
    221       if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
    222         # Compile src and src-multidex in the same .jack file. We will apply multidex partitioning
    223         # when creating the output .dex file.
    224         ${JACK} ${JACK_ARGS} --output-jack src.jack src src src-multidex
    225         jack_extra_args="${jack_extra_args} -D jack.dex.output.policy=minimal-multidex"
    226         jack_extra_args="${jack_extra_args} -D jack.preprocessor=true"
    227         jack_extra_args="${jack_extra_args} -D jack.preprocessor.file=multidex.jpp"
    228       else
    229         ${JACK} ${JACK_ARGS} --output-jack src.jack src
    230       fi
    231       jack_extra_args="${jack_extra_args} --import src.jack"
    232     fi
    233 
    234     if [ "${HAS_SRC2}" = "true" ]; then
    235       ${JACK} ${JACK_ARGS} --output-jack src2.jack src2
    236       # In case of duplicate classes, we want to take into account the classes from src2. Therefore
    237       # we apply the 'keep-first' policy and import src2.jack file *before* the src.jack file.
    238       jack_extra_args="${jack_extra_args} -D jack.import.type.policy=keep-first"
    239       jack_extra_args="--import src2.jack ${jack_extra_args}"
    240     fi
    241 
    242     # Compile jack files into a DEX file.
    243     if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then
    244       ${JACK} ${JACK_ARGS} ${jack_extra_args} --output-dex .
    245     fi
    246   else
    247     # Legacy toolchain with javac+dx
    248     if [ "${HAS_SRC}" = "true" ]; then
    249       mkdir classes
    250       ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src -name '*.java'`
    251     fi
    252 
    253     if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
    254       mkdir classes2
    255       ${JAVAC} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'`
    256       if [ ${NEED_DEX} = "true" ]; then
    257         ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex \
    258           --dump-width=1000 ${DX_FLAGS} classes2
    259       fi
    260     fi
    261 
    262     if [ "${HAS_SRC2}" = "true" ]; then
    263       mkdir -p classes
    264       ${JAVAC} ${JAVAC_ARGS} -d classes `find src2 -name '*.java'`
    265     fi
    266 
    267     if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then
    268       if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then
    269         ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \
    270           --dump-width=1000 ${DX_FLAGS} classes
    271       fi
    272     fi
    273   fi
    274 fi
    275 
    276 if [ "${HAS_SMALI}" = "true" -a ${NEED_DEX} = "true" ]; then
    277   # Compile Smali classes
    278   ${SMALI} -JXmx512m ${SMALI_ARGS} --output smali_classes.dex `find smali -name '*.smali'`
    279 
    280   # Don't bother with dexmerger if we provide our own main function in a smali file.
    281   if [ ${SKIP_DX_MERGER} = "false" ]; then
    282     ${DXMERGER} classes.dex classes.dex smali_classes.dex
    283   else
    284     mv smali_classes.dex classes.dex
    285   fi
    286 fi
    287 
    288 if [ "${HAS_SMALI_MULTIDEX}" = "true" -a ${NEED_DEX} = "true" ]; then
    289   # Compile Smali classes
    290   ${SMALI} -JXmx512m ${SMALI_ARGS} --output smali_classes2.dex `find smali-multidex -name '*.smali'`
    291 
    292   # Don't bother with dexmerger if we provide our own main function in a smali file.
    293   if [ ${HAS_SRC_MULTIDEX} = "true" ]; then
    294     ${DXMERGER} classes2.dex classes2.dex smali_classes2.dex
    295   else
    296     mv smali_classes2.dex classes2.dex
    297   fi
    298 fi
    299 
    300 
    301 if [ ${HAS_SRC_EX} = "true" ]; then
    302   if [ ${USE_JACK} = "true" ]; then
    303       # Rename previous "classes.dex" so it is not overwritten.
    304       mv classes.dex classes-1.dex
    305       #TODO find another way to append src.jack to the jack classpath
    306       ${JACK}:src.jack ${JACK_ARGS} --output-dex . src-ex
    307       zip $TEST_NAME-ex.jar classes.dex
    308       # Restore previous "classes.dex" so it can be zipped.
    309       mv classes-1.dex classes.dex
    310   else
    311     mkdir classes-ex
    312     ${JAVAC} ${JAVAC_ARGS} -d classes-ex -cp classes `find src-ex -name '*.java'`
    313     if [ ${NEED_DEX} = "true" ]; then
    314       ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes-ex.dex \
    315         --dump-width=1000 ${DX_FLAGS} classes-ex
    316 
    317       # quick shuffle so that the stored name is "classes.dex"
    318       mv classes.dex classes-1.dex
    319       mv classes-ex.dex classes.dex
    320       zip $TEST_NAME-ex.jar classes.dex
    321       mv classes.dex classes-ex.dex
    322       mv classes-1.dex classes.dex
    323     fi
    324   fi
    325 fi
    326 
    327 # Create a single jar with two dex files for multidex.
    328 if [ ${NEED_DEX} = "true" ]; then
    329   if [ ${HAS_SRC_MULTIDEX} = "true" ] || [ ${HAS_SMALI_MULTIDEX} = "true" ]; then
    330     zip $TEST_NAME.jar classes.dex classes2.dex
    331   else
    332     zip $TEST_NAME.jar classes.dex
    333   fi
    334 fi
    335