/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ant; import org.apache.tools.ant.BuildException; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * A base class for ant tasks that use a single dependency file to control (re)execution. */ public abstract class SingleDependencyTask extends BuildTypedTask { private DependencyGraph mDependencies; protected abstract String getExecTaskName(); protected interface InputPathFactory { InputPath createPath(File file, Set<String> extensionsToCheck); } private static final InputPathFactory sDefaultFactory = new InputPathFactory() { @Override public InputPath createPath(File file, Set<String> extensionsToCheck) { return new InputPath(file, extensionsToCheck); } }; /** * Creates a list of {@link InputPath} from a list of {@link File} and an optional list of * extensions. All the {@link InputPath} will share the same extension restrictions. * @param paths the list of path * @param extensionsToCheck A set of extensions. Only files with an extension in this set will * be considered for a modification check. All deleted/created files will still be * checked. If this is null, all files will be checked for modification date * @return a list of {@link InputPath} */ protected static List<InputPath> getInputPaths(List<File> paths, Set<String> extensionsToCheck, InputPathFactory factory) { List<InputPath> result = new ArrayList<InputPath>(paths.size()); if (factory == null ) { factory = sDefaultFactory; } for (File f : paths) { result.add(factory.createPath(f, extensionsToCheck)); } return result; } /** * Set up the dependency graph by passing it the location of the ".d" file, and the new input * paths. * @param dependencyFile path to the dependency file to use * @param inputPaths the new input paths for this new compilation. * @return true if the dependency graph was successfully initialized */ protected boolean initDependencies(String dependencyFile, List<InputPath> inputPaths) { if (hasBuildTypeChanged()) { // we don't care about deps, we need to execute the task no matter what. return true; } File depFile = new File(dependencyFile); if (depFile.exists()) { mDependencies = new DependencyGraph(dependencyFile, inputPaths); return true; } else { return false; } } /** * Wrapper check to see if we need to execute this task at all * @return true if the DependencyGraph reports that our prereqs or targets * have changed since the last run */ protected boolean dependenciesHaveChanged() { if (hasBuildTypeChanged()) { // if this is not a new build, display that build type change is forcing running // the task. if (isNewBuild() == false) { String execName = getExecTaskName(); if (execName == null) { System.out.println( "Current build type is different than previous build: forced task run."); } else { System.out.println( "Current build type is different than previous build: forced " + execName + " run."); } } return true; } assert mDependencies != null : "Dependencies have not been initialized"; return mDependencies.dependenciesHaveChanged(true /*printStatus*/); } protected void generateDependencyFile(String depFilePath, List<InputPath> inputs, String outputFile) { File depFile = new File(depFilePath); try { PrintStream ps = new PrintStream(depFile); // write the output file. ps.print(outputFile); ps.println(" : \\"); //write the input files int count = inputs.size(); for (int i = 0 ; i < count ; i++) { InputPath input = inputs.get(i); File file = input.getFile(); if (file.isDirectory()) { writeContent(ps, file, input); } else { ps.print(file.getAbsolutePath()); ps.println(" \\"); } } ps.close(); } catch (FileNotFoundException e) { throw new BuildException(e); } } private void writeContent(PrintStream ps, File file, InputPath input) { if (input.ignores(file)) { return; } File[] files = file.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { writeContent(ps, f, input); } else if (input.ignores(f) == false) { ps.print(f.getAbsolutePath()); ps.println(" \\"); } } } } }