diff options
author | mikaelpeltier <mikaelpeltier@google.com> | 2014-09-23 10:22:27 +0200 |
---|---|---|
committer | mikaelpeltier <mikaelpeltier@google.com> | 2014-09-23 11:44:01 +0200 |
commit | 6681c763ef2e33b19d8d44cc897f4c4c4a77abbe (patch) | |
tree | afd9c59dcdf77f5b3168685b0be1a51ac9f40d9c /jack | |
parent | 151db94fa5e8f6fcb00785254d26e59db27d1e42 (diff) | |
download | toolchain_jack-6681c763ef2e33b19d8d44cc897f4c4c4a77abbe.zip toolchain_jack-6681c763ef2e33b19d8d44cc897f4c4c4a77abbe.tar.gz toolchain_jack-6681c763ef2e33b19d8d44cc897f4c4c4a77abbe.tar.bz2 |
Trigger a full rebuild when classpath is modified
- A full rebuild is needed when a file contained inside a folder
in the classpath or an archive in the classpath is more recent
than the generated dex file.
Change-Id: Iec0c3e0d2d0150f2ba02ca51fbec0913607df07a
Diffstat (limited to 'jack')
4 files changed, 149 insertions, 5 deletions
diff --git a/jack/src/com/android/jack/experimental/incremental/JackIncremental.java b/jack/src/com/android/jack/experimental/incremental/JackIncremental.java index 344f4e1..93ad0fc 100644 --- a/jack/src/com/android/jack/experimental/incremental/JackIncremental.java +++ b/jack/src/com/android/jack/experimental/incremental/JackIncremental.java @@ -184,7 +184,7 @@ public class JackIncremental extends CommandLine { compilerState = new CompilerState(incrementalFolder); - if (isIncrementalCompilation(options)) { + if (isIncrementalCompilation(options) && !needFullRebuild(options)) { logger.log(Level.INFO, "Incremental compilation"); List<String> javaFilesNames = getJavaFilesSpecifiedOnCommandLine(options); @@ -262,6 +262,54 @@ public class JackIncremental extends CommandLine { return compilerState; } + /* + * A full rebuild is needed when a file contained inside a folder in the classpath + * or an archive in the classpath is more recent than the generated dex file. + */ + private static boolean needFullRebuild(@Nonnull Options options) { + File outputDexFile = new File(options.getOutputDir(), DexFileWriter.DEX_FILENAME); + if (outputDexFile.exists()) { + for (File lib : options.getBootclasspath()) { + if (isModifiedLibrary(lib, outputDexFile.lastModified())) { + return true; + } + } + for (File lib : options.getClasspath()) { + if (isModifiedLibrary(lib, outputDexFile.lastModified())) { + return true; + } + } + } + return false; + } + + private static boolean isModifiedLibrary(@Nonnull File lib, long time) { + if (lib.isFile() && (lib.lastModified() > time)) { + return true; + } else if (lib.isDirectory() && hasModifiedFile(lib, time)) { + return true; + } + + return false; + } + + private static boolean hasModifiedFile(@Nonnull File file, long time) { + assert file.isDirectory(); + + for (File f : file.listFiles()) { + if (f.isDirectory()) { + if (hasModifiedFile(f, time)) { + return true; + } + } else if (f.lastModified() > time) { + return true; + } + } + + return false; + } + + @Nonnull private static String dependenciesToString(@Nonnull Map<String, Set<String>> fileDependencies) { StringBuilder builder = new StringBuilder(); builder.append(TextUtils.LINE_SEPARATOR); @@ -485,8 +533,7 @@ public class JackIncremental extends CommandLine { } private static boolean isIncrementalCompilation(@Nonnull Options options) { - if (!options.getEcjArguments().isEmpty() - && getCompilerState().exists()) { + if (!options.getEcjArguments().isEmpty() && getCompilerState().exists()) { return true; } diff --git a/jack/tests/com/android/jack/experimental/incremental/DependenciesTest015.java b/jack/tests/com/android/jack/experimental/incremental/DependenciesTest015.java new file mode 100644 index 0000000..c4291d2 --- /dev/null +++ b/jack/tests/com/android/jack/experimental/incremental/DependenciesTest015.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 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.jack.experimental.incremental; + +import com.android.jack.Main; +import com.android.jack.TestTools; +import com.android.jack.frontend.FrontendCompilationException; + +import junit.framework.Assert; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.util.List; + +/** + * JUnit test checking incremental support. + */ +public class DependenciesTest015 { + + @BeforeClass + public static void setUpClass() { + Main.class.getClassLoader().setDefaultAssertionStatus(true); + } + + /** + * Check that incremental compilation works when library on classpath is modified. + */ + @Test + public void testDependency001() throws Exception { + IncrementalTestingEnvironment iteLib = + new IncrementalTestingEnvironment(TestTools.createTempDir("DependenciesTest_", "_001_lib")); + + iteLib.addJavaFile("jack.incremental", "A.java", "package jack.incremental; \n" + + "public abstract class A { \n" + "public abstract void m(); }"); + + iteLib.incrementalBuildFromFolder(); + iteLib.snapshotJackFilesModificationDate(); + List<File> jackFilesLib = iteLib.getJackFiles(); + Assert.assertEquals(1, jackFilesLib.size()); + + + IncrementalTestingEnvironment iteProg = + new IncrementalTestingEnvironment(TestTools.createTempDir("DependenciesTest_", "_001_prog")); + + iteProg.addJavaFile("jack.incremental", "B.java", "package jack.incremental; \n" + + "public class B extends A { \n" + " @Override public void m(){} }"); + + iteProg.incrementalBuildFromFolder(new File[]{iteLib.getJackFolder()}); + iteProg.snapshotJackFilesModificationDate(); + Assert.assertEquals(1, iteProg.getJackFiles().size()); + + iteLib.deleteJavaFile("jack.incremental", "A.java"); + iteLib.addJavaFile("jack.incremental", "A.java", "package jack.incremental; \n" + + "public abstract class A { \n" + "public abstract int m(); }"); + iteLib.incrementalBuildFromFolder(); + iteLib.snapshotJackFilesModificationDate(); + jackFilesLib = iteLib.getJackFiles(); + Assert.assertEquals(1, jackFilesLib.size()); + + try { + iteProg.incrementalBuildFromFolder(new File[] {iteLib.getJackFolder()}); + Assert.fail(); + } catch (FrontendCompilationException e) { + Assert.assertTrue(iteProg.getStringRepresentingErr().contains( + "The return type is incompatible with A.m()")); + } + } +} + diff --git a/jack/tests/com/android/jack/experimental/incremental/DependencyAllTests.java b/jack/tests/com/android/jack/experimental/incremental/DependencyAllTests.java index 458b6b5..e8b42a8 100644 --- a/jack/tests/com/android/jack/experimental/incremental/DependencyAllTests.java +++ b/jack/tests/com/android/jack/experimental/incremental/DependencyAllTests.java @@ -9,6 +9,7 @@ import org.junit.runners.Suite.SuiteClasses; DependenciesTest003.class, DependenciesTest004.class, DependenciesTest005.class, DependenciesTest006.class, DependenciesTest007.class, DependenciesTest008.class, DependenciesTest009.class, DependenciesTest010.class, DependenciesTest011.class, - DependenciesTest012.class, DependenciesTest013.class, DependenciesTest014.class}) + DependenciesTest012.class, DependenciesTest013.class, DependenciesTest014.class, + DependenciesTest015.class}) public class DependencyAllTests { }
\ No newline at end of file diff --git a/jack/tests/com/android/jack/experimental/incremental/IncrementalTestingEnvironment.java b/jack/tests/com/android/jack/experimental/incremental/IncrementalTestingEnvironment.java index a7b3d8e..099425d 100644 --- a/jack/tests/com/android/jack/experimental/incremental/IncrementalTestingEnvironment.java +++ b/jack/tests/com/android/jack/experimental/incremental/IncrementalTestingEnvironment.java @@ -129,6 +129,10 @@ public class IncrementalTestingEnvironment extends TestTools { } public void incrementalBuildFromFolder() throws Exception { + incrementalBuildFromFolder(null); + } + + public void incrementalBuildFromFolder(@CheckForNull File[] classpath) throws Exception { startOutRedirection(); startErrRedirection(); @@ -136,7 +140,9 @@ public class IncrementalTestingEnvironment extends TestTools { options.setIncrementalFolder(getCompilerStateFolder()); compileSourceToDex(options, sourceFolder, - TestTools.getClasspathAsString(TestTools.getDefaultBootclasspath()), testingFolder); + classpath == null ? TestTools.getClasspathAsString(TestTools.getDefaultBootclasspath()) + : TestTools.getClasspathsAsString(TestTools.getDefaultBootclasspath(), classpath), + testingFolder); Thread.sleep(1000); @@ -215,6 +221,11 @@ public class IncrementalTestingEnvironment extends TestTools { } @Nonnull + public File getJackFolder() { + return jackFolder; + } + + @Nonnull public List<File> getJackFiles() { List<File> jackFiles = new ArrayList<File>(); fillJackFiles(jackFolder, jackFiles); |