1 /* 2 * Copyright (C) 2009 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.Task; 21 22 import java.io.File; 23 import java.io.FileNotFoundException; 24 import java.io.PrintStream; 25 import java.util.ArrayList; 26 import java.util.List; 27 import java.util.Set; 28 29 /** 30 * A base class for the ant task that contains logic for handling dependency files 31 */ 32 public abstract class BaseTask extends Task { 33 34 private DependencyGraph mDependencies; 35 private String mPreviousBuildType; 36 private String mBuildType; 37 setPreviousBuildType(String previousBuildType)38 public void setPreviousBuildType(String previousBuildType) { 39 mPreviousBuildType = previousBuildType; 40 } 41 setBuildType(String buildType)42 public void setBuildType(String buildType) { 43 mBuildType = buildType; 44 } 45 getExecTaskName()46 protected abstract String getExecTaskName(); 47 48 /** 49 * Creates a list of {@link InputPath} from a list of {@link File} and an optional list of 50 * extensions. All the {@link InputPath} will share the same extension restrictions. 51 * @param paths the list of path 52 * @param extensionsToCheck A set of extensions. Only files with an extension in this set will 53 * be considered for a modification check. All deleted/created files will still be 54 * checked. If this is null, all files will be checked for modification date 55 * @return a list of {@link InputPath} 56 */ getInputPaths(List<File> paths, Set<String> extensionsToCheck)57 protected static List<InputPath> getInputPaths(List<File> paths, 58 Set<String> extensionsToCheck) { 59 List<InputPath> result = new ArrayList<InputPath>(paths.size()); 60 61 for (File f : paths) { 62 result.add(new InputPath(f, extensionsToCheck)); 63 } 64 65 return result; 66 } 67 68 /** 69 * Set up the dependency graph by passing it the location of the ".d" file, and the new input 70 * paths. 71 * @param dependencyFile path to the dependency file to use 72 * @param the new input paths for this new compilation. 73 * @return true if the dependency graph was successfully initialized 74 */ initDependencies(String dependencyFile, List<InputPath> inputPaths)75 protected boolean initDependencies(String dependencyFile, List<InputPath> inputPaths) { 76 if (mBuildType != null && mBuildType.equals(mPreviousBuildType) == false) { 77 // we don't care about deps, we need to execute the task no matter what. 78 return true; 79 } 80 81 File depFile = new File(dependencyFile); 82 if (depFile.exists()) { 83 mDependencies = new DependencyGraph(dependencyFile, inputPaths); 84 return true; 85 } else { 86 return false; 87 } 88 } 89 90 /** 91 * Wrapper check to see if we need to execute this task at all 92 * @return true if the DependencyGraph reports that our prereqs or targets 93 * have changed since the last run 94 */ dependenciesHaveChanged()95 protected boolean dependenciesHaveChanged() { 96 if (mBuildType != null && mBuildType.equals(mPreviousBuildType) == false) { 97 String execName = getExecTaskName(); 98 if (execName == null) { 99 System.out.println( 100 "Current build type is different than previous build: forced task run."); 101 } else { 102 System.out.println( 103 "Current build type is different than previous build: forced " + 104 execName + " run."); 105 } 106 return true; 107 } 108 109 assert mDependencies != null : "Dependencies have not been initialized"; 110 return mDependencies.dependenciesHaveChanged(true /*printStatus*/); 111 } 112 generateDependencyFile(String depFilePath, List<InputPath> inputs, String outputFile)113 protected void generateDependencyFile(String depFilePath, 114 List<InputPath> inputs, String outputFile) { 115 File depFile = new File(depFilePath); 116 117 try { 118 PrintStream ps = new PrintStream(depFile); 119 120 // write the output file. 121 ps.print(outputFile); 122 ps.println(" : \\"); 123 124 //write the input files 125 int count = inputs.size(); 126 for (int i = 0 ; i < count ; i++) { 127 InputPath input = inputs.get(i); 128 File file = input.getFile(); 129 if (file.isDirectory()) { 130 writeContent(ps, file, input); 131 } else { 132 ps.print(file.getAbsolutePath()); 133 ps.println(" \\"); 134 } 135 } 136 137 ps.close(); 138 } catch (FileNotFoundException e) { 139 new BuildException(e); 140 } 141 } 142 writeContent(PrintStream ps, File file, InputPath input)143 private void writeContent(PrintStream ps, File file, InputPath input) { 144 if (input.ignores(file)) { 145 return; 146 } 147 148 File[] files = file.listFiles(); 149 if (files != null) { 150 for (File f : files) { 151 if (f.isDirectory()) { 152 writeContent(ps, f, input); 153 } else if (input.ignores(f) == false) { 154 ps.print(f.getAbsolutePath()); 155 ps.println(" \\"); 156 } 157 } 158 } 159 } 160 } 161