From f265ce821c48ed54ad8d00060664b55a8f8e1bb7 Mon Sep 17 00:00:00 2001 From: Jean-Marie Henaff Date: Mon, 19 May 2014 17:34:13 +0200 Subject: WIP Use JUnit for jack-tests. (cherry picked from commit 452cbd7d69db557ecdbbd20875a669752cf2d9d7) Change-Id: I96a34b90c9525fa4403f6f940d6fcdf4656722ab --- .../jack/test/toolchain/LegacyToolchain.java | 293 +++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java (limited to 'jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java') diff --git a/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java new file mode 100644 index 0000000..3a5a231 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java @@ -0,0 +1,293 @@ +/* + * 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.test.toolchain; + +import com.android.dx.command.dexer.Main.Arguments; +import com.android.jack.test.util.ExecFileException; +import com.android.jack.test.util.ExecuteFile; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; + +/** + * The legacy android toolchain. + */ +public class LegacyToolchain extends AndroidToolchain { + + @Nonnull + private final File legacyCompilerPrebuilt; + @Nonnull + private final File jarjarPrebuilt; + @Nonnull + private final File proguardPrebuilt; + + private boolean useDxOptimization = true; + + LegacyToolchain(@Nonnull File legacyCompilerPrebuilt, @Nonnull File jarjarPrebuilt, + @Nonnull File proguardPrebuilt) { + this.legacyCompilerPrebuilt = legacyCompilerPrebuilt; + this.jarjarPrebuilt = jarjarPrebuilt; + this.proguardPrebuilt = proguardPrebuilt; + } + + @Override + @Nonnull + public void srcToExe(@Nonnull String classpath, @Nonnull File out, + @Nonnull File... sources) throws Exception { + + try { + + File jarFile = AbstractTestTools.createTempFile("legacyLib", ".jar"); + File jarFileJarjar = AbstractTestTools.createTempFile("legacyLibJarjar", ".jar"); + File jarFileProguard = AbstractTestTools.createTempFile("legacyLibProguard", ".jar"); + + srcToLib(classpath, jarFile, true /* zipFiles = */, sources); + + if (jarjarRules != null) { + processWithJarJar(jarjarRules, jarFile, jarFileJarjar); + } else { + jarFileJarjar = jarFile; + } + + if (proguardFlags.size() > 0) { + processWithProguard(classpath, proguardFlags, jarFileJarjar, + jarFileProguard); + } else { + jarFileProguard = jarFileJarjar; + } + + libToDex(jarFileProguard, out); + + } catch (IOException e) { + throw new RuntimeException("Legacy toolchain exited with an error", e); + } + } + + @Override + @Nonnull + public void srcToLib(@Nonnull String classpath, @Nonnull File out, + boolean zipFiles, @Nonnull File... sources) throws Exception { + + try { + File classesDir; + if (zipFiles) { + classesDir = AbstractTestTools.createTempDir(); + } else { + classesDir = out; + } + if (withDebugInfos) { + compileWithEcj(sources, classpath, classesDir); + } else { + compileWithExternalRefCompiler(sources, classpath, classesDir); + } + if (staticLibs.size() > 0) { + for (File staticLib : staticLibs) { + AbstractTestTools.unzip(staticLib, classesDir); + } + } + if (zipFiles) { + AbstractTestTools.createjar(out, classesDir); + } + } catch (IOException e) { + throw new RuntimeException("Legacy toolchain exited with an error", e); + } + } + + @Override + @Nonnull + public void libToDex(@Nonnull File in, @Nonnull File out) throws Exception { + + try { + compileWithDx(in, out); + } catch (IOException e) { + throw new RuntimeException("Legacy toolchain exited with an error", e); + } + } + + @Override + @Nonnull + public void libToLib(@Nonnull File in, @Nonnull File out) throws Exception { + throw new AssertionError("Not Yet Implemented"); + } + + @Override + @Nonnull + public File[] getDefaultBootClasspath() { + return new File[] { + new File(AbstractTestTools.getJackRootDir(), + "toolchain/jack/jack-tests/libs/core-stubs-mini.jar"), + new File(AbstractTestTools.getJackRootDir(), + "toolchain/jack/jack-tests/libs/junit4.jar") + }; + } + + private void processWithJarJar(@Nonnull File jarjarRules, + @Nonnull File inJar, @Nonnull File outJar) { + String[] args = new String[]{"java", "-jar", jarjarPrebuilt.getAbsolutePath(), + "process", jarjarRules.getAbsolutePath(), + inJar.getAbsolutePath(), outJar.getAbsolutePath()}; + + ExecuteFile execFile = new ExecuteFile(args); + execFile.setOut(outRedirectStream); + execFile.setErr(errRedirectStream); + execFile.setVerbose(true); + + try { + if (execFile.run() != 0) { + throw new RuntimeException("JarJar exited with an error"); + } + } catch (ExecFileException e) { + throw new RuntimeException("An error occured while running Jarjar", e); + } + } + + private void processWithProguard(@Nonnull String bootclasspathStr, + @Nonnull List proguardFlags, @Nonnull File inJar, @Nonnull File outJar) { + + List args = new ArrayList(); + args.add("java"); + args.add("-jar"); + args.add(proguardPrebuilt.getAbsolutePath()); + args.add("-injar"); + args.add(inJar.getAbsolutePath()); + args.add("-outjars"); + args.add(outJar.getAbsolutePath()); + args.add("-libraryjars"); + args.add(bootclasspathStr); + args.add("-verbose"); + args.add("-forceprocessing"); + args.add("-dontoptimize"); + for (File flags : proguardFlags) { + args.add("-include"); + args.add(flags.getAbsolutePath()); + } + + ExecuteFile execFile = new ExecuteFile(args.toArray(new String[args.size()])); + execFile.setOut(outRedirectStream); + execFile.setErr(errRedirectStream); + execFile.setVerbose(true); + + try { + if (execFile.run() != 0) { + throw new RuntimeException("Proguard exited with an error"); + } + } catch (ExecFileException e) { + throw new RuntimeException("An error occured while running Proguard", e); + } + } + + private void compileWithEcj(@Nonnull File[] sources, @Nonnull String classpath, + @Nonnull File out) { + + throw new AssertionError("Not yet implemented"); + } + + @Override + @Nonnull + public LegacyToolchain disableDxOptimizations() { + useDxOptimization = false; + return this; + } + + @Override + @Nonnull + public LegacyToolchain enableDxOptimizations() { + useDxOptimization = true; + return this; + } + + private static void addSourceLevel(@Nonnull SourceLevel level, @Nonnull List args) { + args.add("-source"); + switch (level) { + case JAVA_6: + args.add("1.6"); + break; + case JAVA_7: + args.add("1.7"); + break; + default: + throw new AssertionError("Unkown level: '" + level.toString() + "'"); + } + } + + private void compileWithExternalRefCompiler(@Nonnull File[] sources, + @Nonnull String classpath, @Nonnull File out) { + + List arguments = new ArrayList(); + + arguments.add(legacyCompilerPrebuilt.getAbsolutePath()); + + addSourceLevel(sourceLevel, arguments); + + if (annotationProcessorClass != null) { + arguments.add("-processor"); + arguments.add(annotationProcessorClass.getName()); + } + + if (classpath != null) { + arguments.add("-classpath"); + arguments.add(classpath); + } + + AbstractTestTools.addFile(arguments, false, sources); + + arguments.add("-d"); + arguments.add(out.getAbsolutePath()); + + ExecuteFile execFile = new ExecuteFile(arguments.toArray(new String[arguments.size()])); + execFile.setErr(outRedirectStream); + execFile.setOut(errRedirectStream); + execFile.setVerbose(true); + try { + if (execFile.run() != 0) { + throw new RuntimeException("Reference compiler exited with an error"); + } + } catch (ExecFileException e) { + throw new RuntimeException("An error occured while running reference compiler", e); + } + } + + private void compileWithDx(File in, File out) + throws IOException { + + try { + System.setOut(outRedirectStream); + System.setErr(errRedirectStream); + + Arguments arguments = new Arguments(); + + arguments.jarOutput = false; + arguments.outName = new File(out, getBinaryFileName()).getAbsolutePath(); + arguments.optimize = !withDebugInfos && useDxOptimization; + // this only means we deactivate the check that no core classes are included + arguments.coreLibrary = true; + arguments.parse(new String[] {in.getAbsolutePath()}); + + int retValue = com.android.dx.command.dexer.Main.run(arguments); + if (retValue != 0) { + throw new RuntimeException("Dx failed and returned " + retValue); + } + } finally { + System.setOut(stdOut); + System.setErr(stdErr); + } + } +} -- cgit v1.1