1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ant; 18 19 import org.apache.tools.ant.BuildException; 20 import org.apache.tools.ant.taskdefs.ExecTask; 21 import org.apache.tools.ant.types.FileSet; 22 import org.apache.tools.ant.types.Path; 23 import org.apache.tools.ant.types.resources.FileResource; 24 25 import java.io.File; 26 import java.util.ArrayList; 27 import java.util.Iterator; 28 import java.util.List; 29 30 /** 31 * Custom task to execute dx while handling dependencies. 32 */ 33 public class DexExecTask extends BaseTask { 34 35 private String mExecutable; 36 private String mOutput; 37 private boolean mVerbose = false; 38 private boolean mNoLocals = false; 39 private List<Path> mPathInputs; 40 private List<FileSet> mFileSetInputs; 41 42 43 /** 44 * Sets the value of the "executable" attribute. 45 * @param executable the value. 46 */ setExecutable(Path executable)47 public void setExecutable(Path executable) { 48 mExecutable = TaskHelper.checkSinglePath("executable", executable); 49 } 50 51 /** 52 * Sets the value of the "verbose" attribute. 53 * @param verbose the value. 54 */ setVerbose(boolean verbose)55 public void setVerbose(boolean verbose) { 56 mVerbose = verbose; 57 } 58 59 /** 60 * Sets the value of the "output" attribute. 61 * @param output the value. 62 */ setOutput(Path output)63 public void setOutput(Path output) { 64 mOutput = TaskHelper.checkSinglePath("output", output); 65 } 66 67 /** 68 * Sets the value of the "nolocals" attribute. 69 * @param verbose the value. 70 */ setNoLocals(boolean nolocals)71 public void setNoLocals(boolean nolocals) { 72 mNoLocals = nolocals; 73 } 74 75 /** 76 * Returns an object representing a nested <var>path</var> element. 77 */ createPath()78 public Object createPath() { 79 if (mPathInputs == null) { 80 mPathInputs = new ArrayList<Path>(); 81 } 82 83 Path path = new Path(getProject()); 84 mPathInputs.add(path); 85 86 return path; 87 } 88 89 /** 90 * Returns an object representing a nested <var>path</var> element. 91 */ createFileSet()92 public Object createFileSet() { 93 if (mFileSetInputs == null) { 94 mFileSetInputs = new ArrayList<FileSet>(); 95 } 96 97 FileSet fs = new FileSet(); 98 fs.setProject(getProject()); 99 mFileSetInputs.add(fs); 100 101 return fs; 102 } 103 104 105 @Override execute()106 public void execute() throws BuildException { 107 108 // get all input paths 109 List<File> paths = new ArrayList<File>(); 110 if (mPathInputs != null) { 111 for (Path pathList : mPathInputs) { 112 for (String path : pathList.list()) { 113 paths.add(new File(path)); 114 } 115 } 116 } 117 118 if (mFileSetInputs != null) { 119 for (FileSet fs : mFileSetInputs) { 120 Iterator<?> iter = fs.iterator(); 121 while (iter.hasNext()) { 122 FileResource fr = (FileResource) iter.next(); 123 paths.add(fr.getFile()); 124 } 125 } 126 } 127 128 // figure out the path to the dependency file. 129 String depFile = mOutput + ".d"; 130 131 // get InputPath with no extension restrictions 132 List<InputPath> inputPaths = getInputPaths(paths, null /*extensionsToCheck*/); 133 134 if (initDependencies(depFile, inputPaths) && dependenciesHaveChanged() == false) { 135 System.out.println( 136 "No new compiled code. No need to convert bytecode to dalvik format."); 137 return; 138 } 139 140 System.out.println(String.format( 141 "Converting compiled files and external libraries into %1$s...", mOutput)); 142 143 ExecTask task = new ExecTask(); 144 task.setProject(getProject()); 145 task.setOwningTarget(getOwningTarget()); 146 task.setExecutable(mExecutable); 147 task.setTaskName(getExecTaskName()); 148 task.setFailonerror(true); 149 150 task.createArg().setValue("--dex"); 151 152 if (mNoLocals) { 153 task.createArg().setValue("--no-locals"); 154 } 155 156 if (mVerbose) { 157 task.createArg().setValue("--verbose"); 158 } 159 160 task.createArg().setValue("--output"); 161 task.createArg().setValue(mOutput); 162 163 164 for (File f : paths) { 165 task.createArg().setValue(f.getAbsolutePath()); 166 } 167 168 // execute it. 169 task.execute(); 170 171 // generate the dependency file. 172 generateDependencyFile(depFile, inputPaths, mOutput); 173 } 174 175 @Override getExecTaskName()176 protected String getExecTaskName() { 177 return "dx"; 178 } 179 } 180