Home | History | Annotate | Download | only in ant
      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 
     38     public void setPreviousBuildType(String previousBuildType) {
     39         mPreviousBuildType = previousBuildType;
     40     }
     41 
     42     public void setBuildType(String buildType) {
     43         mBuildType = buildType;
     44     }
     45 
     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      */
     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      */
     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      */
     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 
    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 
    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