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 DX_FLAGS="" 64 SKIP_DX_MERGER="false" 65 EXPERIMENTAL="" 66 67 # Setup experimental flag mappings in a bash associative array. 68 declare -A JACK_EXPERIMENTAL_ARGS 69 JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" 70 JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" 71 72 declare -A SMALI_EXPERIMENTAL_ARGS 73 SMALI_EXPERIMENTAL_ARGS["default-methods"]="--api-level 24" 74 75 while true; do 76 if [ "x$1" = "x--dx-option" ]; then 77 shift 78 on="$1" 79 DX_FLAGS="${DX_FLAGS} $option" 80 shift 81 elif [ "x$1" = "x--jvm" ]; then 82 shift 83 elif [ "x$1" = "x--no-src" ]; then 84 HAS_SRC=false 85 shift 86 elif [ "x$1" = "x--no-src2" ]; then 87 HAS_SRC2=false 88 shift 89 elif [ "x$1" = "x--no-src-multidex" ]; then 90 HAS_SRC_MULTIDEX=false 91 shift 92 elif [ "x$1" = "x--no-smali-multidex" ]; then 93 HAS_SMALI_MULTIDEX=false 94 shift 95 elif [ "x$1" = "x--no-src-ex" ]; then 96 HAS_SRC_EX=false 97 shift 98 elif [ "x$1" = "x--no-smali" ]; then 99 HAS_SMALI=false 100 shift 101 elif [ "x$1" = "x--experimental" ]; then 102 shift 103 EXPERIMENTAL="${EXPERIMENTAL} $1" 104 shift 105 elif expr "x$1" : "x--" >/dev/null 2>&1; then 106 echo "unknown $0 option: $1" 1>&2 107 exit 1 108 else 109 break 110 fi 111 done 112 113 # Add args from the experimental mappings. 114 for experiment in ${EXPERIMENTAL}; do 115 JACK_ARGS="${JACK_ARGS} ${JACK_EXPERIMENTAL_ARGS[${experiment}]}" 116 SMALI_ARGS="${SMALI_ARGS} ${SMALI_EXPERIMENTAL_ARGS[${experiment}]}" 117 done 118 119 if [ -e classes.dex ]; then 120 zip $TEST_NAME.jar classes.dex 121 exit 0 122 fi 123 124 if ! [ "${HAS_SRC}" = "true" ] && ! [ "${HAS_SRC2}" = "true" ]; then 125 # No src directory? Then forget about trying to run dx. 126 SKIP_DX_MERGER="true" 127 fi 128 129 if [ ${HAS_SRC_DEX2OAT_UNRESOLVED} = "true" ]; then 130 mkdir classes 131 mkdir classes-ex 132 ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src-dex2oat-unresolved -d classes `find src -name '*.java'` 133 ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src -d classes-ex `find src-dex2oat-unresolved -name '*.java'` 134 if [ ${USE_JACK} = "true" ]; then 135 jar cf classes.jill.jar -C classes . 136 jar cf classes-ex.jill.jar -C classes-ex . 137 138 ${JACK} --import classes-ex.jill.jar --output-dex . 139 zip ${TEST_NAME}-ex.jar classes.dex 140 ${JACK} --import classes.jill.jar --output-dex . 141 else 142 if [ ${NEED_DEX} = "true" ]; then 143 ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 classes-ex 144 zip ${TEST_NAME}-ex.jar classes.dex 145 ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes 146 fi 147 fi 148 else 149 if [ ${USE_JACK} = "true" ]; then 150 # Jack toolchain 151 if [ "${HAS_SRC}" = "true" ]; then 152 if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then 153 # Compile src and src-multidex in the same .jack file. We will apply multidex partitioning 154 # when creating the output .dex file. 155 ${JACK} ${JACK_ARGS} --output-jack src.jack src src src-multidex 156 jack_extra_args="${jack_extra_args} -D jack.dex.output.policy=minimal-multidex" 157 jack_extra_args="${jack_extra_args} -D jack.preprocessor=true" 158 jack_extra_args="${jack_extra_args} -D jack.preprocessor.file=multidex.jpp" 159 else 160 ${JACK} ${JACK_ARGS} --output-jack src.jack src 161 fi 162 jack_extra_args="${jack_extra_args} --import src.jack" 163 fi 164 165 if [ "${HAS_SRC2}" = "true" ]; then 166 ${JACK} ${JACK_ARGS} --output-jack src2.jack src2 167 # In case of duplicate classes, we want to take into account the classes from src2. Therefore 168 # we apply the 'keep-first' policy and import src2.jack file *before* the src.jack file. 169 jack_extra_args="${jack_extra_args} -D jack.import.type.policy=keep-first" 170 jack_extra_args="--import src2.jack ${jack_extra_args}" 171 fi 172 173 # Compile jack files into a DEX file. 174 if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then 175 ${JACK} ${JACK_ARGS} ${jack_extra_args} --output-dex . 176 fi 177 else 178 # Legacy toolchain with javac+dx 179 if [ "${HAS_SRC}" = "true" ]; then 180 mkdir classes 181 ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src -name '*.java'` 182 fi 183 184 if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then 185 mkdir classes2 186 ${JAVAC} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'` 187 if [ ${NEED_DEX} = "true" ]; then 188 ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex \ 189 --dump-width=1000 ${DX_FLAGS} classes2 190 fi 191 fi 192 193 if [ "${HAS_SRC2}" = "true" ]; then 194 mkdir -p classes 195 ${JAVAC} ${JAVAC_ARGS} -d classes `find src2 -name '*.java'` 196 fi 197 198 if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then 199 if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then 200 ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \ 201 --dump-width=1000 ${DX_FLAGS} classes 202 fi 203 fi 204 fi 205 fi 206 207 if [ "${HAS_SMALI}" = "true" ]; then 208 # Compile Smali classes 209 ${SMALI} -JXmx512m ${SMALI_ARGS} --output smali_classes.dex `find smali -name '*.smali'` 210 211 # Don't bother with dexmerger if we provide our own main function in a smali file. 212 if [ ${SKIP_DX_MERGER} = "false" ]; then 213 ${DXMERGER} classes.dex classes.dex smali_classes.dex 214 else 215 mv smali_classes.dex classes.dex 216 fi 217 fi 218 219 if [ "${HAS_SMALI_MULTIDEX}" = "true" ]; then 220 # Compile Smali classes 221 ${SMALI} -JXmx512m ${SMALI_ARGS} --output smali_classes2.dex `find smali-multidex -name '*.smali'` 222 223 # Don't bother with dexmerger if we provide our own main function in a smali file. 224 if [ ${HAS_SRC_MULTIDEX} = "true" ]; then 225 ${DXMERGER} classes2.dex classes2.dex smali_classes2.dex 226 else 227 mv smali_classes2.dex classes2.dex 228 fi 229 fi 230 231 232 if [ ${HAS_SRC_EX} = "true" ]; then 233 if [ ${USE_JACK} = "true" ]; then 234 # Rename previous "classes.dex" so it is not overwritten. 235 mv classes.dex classes-1.dex 236 #TODO find another way to append src.jack to the jack classpath 237 ${JACK}:src.jack ${JACK_ARGS} --output-dex . src-ex 238 zip $TEST_NAME-ex.jar classes.dex 239 # Restore previous "classes.dex" so it can be zipped. 240 mv classes-1.dex classes.dex 241 else 242 mkdir classes-ex 243 ${JAVAC} ${JAVAC_ARGS} -d classes-ex -cp classes `find src-ex -name '*.java'` 244 if [ ${NEED_DEX} = "true" ]; then 245 ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes-ex.dex \ 246 --dump-width=1000 ${DX_FLAGS} classes-ex 247 248 # quick shuffle so that the stored name is "classes.dex" 249 mv classes.dex classes-1.dex 250 mv classes-ex.dex classes.dex 251 zip $TEST_NAME-ex.jar classes.dex 252 mv classes.dex classes-ex.dex 253 mv classes-1.dex classes.dex 254 fi 255 fi 256 fi 257 258 # Create a single jar with two dex files for multidex. 259 if [ ${HAS_SRC_MULTIDEX} = "true" ] || [ ${HAS_SMALI_MULTIDEX} = "true" ]; then 260 zip $TEST_NAME.jar classes.dex classes2.dex 261 elif [ ${NEED_DEX} = "true" ]; then 262 zip $TEST_NAME.jar classes.dex 263 fi 264