blob: 08f86bf7802d08b38fb7b8dbb5ef5c57f8bc8bac [file] [log] [blame]
/*
* 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(" \\");
}
}
}
}
}