blob: ee61030b8d998ce322f32f3650c55793439f3ecd [file] [log] [blame]
/*
* Copyright (C) 2013 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.sdklib.build;
import static com.android.SdkConstants.EXT_FS;
import static com.android.SdkConstants.EXT_RS;
import static com.android.SdkConstants.EXT_RSH;
import com.android.annotations.NonNull;
import com.google.common.collect.Lists;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* Checks whether Renderscript compilation is needed. This is entirely based
* on using dependency files and manually looking up the list of current inputs, and old
* outputs timestamp.
*
* TODO: add checks on input/output checksum to detect true changes.
* TODO: (better) delete Ant and use Gradle.
*
* This should be only needed in Ant.
*/
public class ManualRenderScriptChecker extends RenderScriptChecker {
@NonNull
private final List<File> mInputFiles = Lists.newArrayList();
public ManualRenderScriptChecker(
@NonNull List<File> sourceFolders,
@NonNull File binFolder) {
super(sourceFolders, binFolder);
}
public boolean mustCompile() throws IOException {
mInputFiles.clear();
loadDependencies();
if (mDependencyFiles.isEmpty()) {
mInputFiles.addAll(findInputFiles());
return !mInputFiles.isEmpty();
}
// get the current files to compile, while checking then against the old inputs
// to detect new inputs
SourceSearcher searcher = new SourceSearcher(mSourceFolders, EXT_RS, EXT_FS, EXT_RSH);
InputProcessor inputProcessor = new InputProcessor(mOldInputs);
searcher.search(inputProcessor);
// at this point we have gathered the input files, so we can record them in case we have to
// compile later.
mInputFiles.addAll(inputProcessor.sourceFiles);
if (inputProcessor.mustCompile) {
return true;
}
// no new files? check if we have less input files.
if (mOldInputs.size() !=
inputProcessor.sourceFiles.size() + inputProcessor.headerFiles.size()) {
return true;
}
// since there's no change in the input, look for change in the output.
for (File file : mOldOutputs) {
if (!file.isFile()) {
// deleted output file?
return true;
}
}
// finally look at file changes.
for (DependencyFile depFile : mDependencyFiles) {
if (depFile.needCompilation()) {
return true;
}
}
return false;
}
@NonNull
public List<File> getInputFiles() {
return mInputFiles;
}
private static class InputProcessor implements SourceSearcher.SourceFileProcessor {
@NonNull
private final Set<File> mOldInputs;
List<File> sourceFiles = Lists.newArrayList();
List<File> headerFiles = Lists.newArrayList();
boolean mustCompile = false;
InputProcessor(@NonNull Set<File> oldInputs) {
mOldInputs = oldInputs;
}
@Override
public void processFile(@NonNull File sourceFile, @NonNull String extension)
throws IOException {
if (EXT_RSH.equals(extension)) {
headerFiles.add(sourceFile);
} else {
sourceFiles.add(sourceFile);
}
// detect new inputs.
if (!mOldInputs.contains(sourceFile)) {
mustCompile = true;
}
}
}
}