Initial push.
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
new file mode 100644
index 0000000..0f172d6
--- /dev/null
+++ b/buildSrc/build.gradle
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+apply plugin: 'java'
+apply plugin: 'idea'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile group: 'com.google.guava', name: 'guava', version: '19.0'
+ compile group: 'org.smali', name: 'smali', version: '2.2b4'
+}
diff --git a/buildSrc/src/main/java/dx/DexMerger.java b/buildSrc/src/main/java/dx/DexMerger.java
new file mode 100644
index 0000000..39a4bfb
--- /dev/null
+++ b/buildSrc/src/main/java/dx/DexMerger.java
@@ -0,0 +1,67 @@
+// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package dx;
+
+import java.io.File;
+import java.io.IOException;
+import org.gradle.api.Action;
+import org.gradle.api.DefaultTask;
+import org.gradle.api.UncheckedIOException;
+import org.gradle.api.file.FileTree;
+import org.gradle.api.tasks.TaskAction;
+import org.gradle.process.ExecSpec;
+import utils.Utils;
+
+public class DexMerger extends DefaultTask {
+
+ private FileTree source;
+ private File destination;
+ private File dexMergerExecutable;
+ private boolean debug;
+
+ public FileTree getSource() {
+ return source;
+ }
+
+ public void setSource(FileTree source) {
+ this.source = source;
+ getInputs().file(source);
+ }
+
+ public File getDestination() {
+ return destination;
+ }
+
+ public void setDestination(File destination) {
+ this.destination = destination;
+ getOutputs().file(destination);
+ }
+
+ public File getDexMergerExecutable() {
+ return dexMergerExecutable;
+ }
+
+ public void setDexMergerExecutable(File dexMergerExecutable) {
+ this.dexMergerExecutable = dexMergerExecutable;
+ }
+
+ @TaskAction
+ void exec() {
+ getProject().exec(new Action<ExecSpec>() {
+ @Override
+ public void execute(ExecSpec execSpec) {
+ try {
+ if (dexMergerExecutable == null) {
+ dexMergerExecutable = new File("tools/" + Utils.toolsDir() + "/dx/bin/dexmerger");
+ }
+ execSpec.setExecutable(dexMergerExecutable);
+ execSpec.args(destination.getCanonicalPath());
+ execSpec.args(source.getFiles());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/dx/Dx.java b/buildSrc/src/main/java/dx/Dx.java
new file mode 100644
index 0000000..e4b89c4
--- /dev/null
+++ b/buildSrc/src/main/java/dx/Dx.java
@@ -0,0 +1,83 @@
+// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package dx;
+
+import java.io.File;
+import java.io.IOException;
+import org.gradle.api.Action;
+import org.gradle.api.DefaultTask;
+import org.gradle.api.UncheckedIOException;
+import org.gradle.api.file.FileTree;
+import org.gradle.api.tasks.TaskAction;
+import org.gradle.process.ExecSpec;
+import utils.Utils;
+
+public class Dx extends DefaultTask {
+
+ private FileTree source;
+ private File destination;
+ private File dxExecutable;
+ private boolean debug;
+
+ public FileTree getSource() {
+ return source;
+ }
+
+ public void setSource(FileTree source) {
+ this.source = source;
+ getInputs().file(source);
+ }
+
+ public File getDestination() {
+ return destination;
+ }
+
+ public void setDestination(File destination) {
+ this.destination = destination;
+ File classesFile = destination.toPath().resolve("classes.dex").toFile();
+ // The output from running DX is classes.dex in the destination directory.
+ // TODO(sgjesse): Handle multidex?
+ getOutputs().file(classesFile);
+ }
+
+ public File getDxExecutable() {
+ return dxExecutable;
+ }
+
+ public void setDxExecutable(File dxExecutable) {
+ this.dxExecutable = dxExecutable;
+ }
+
+ public boolean isDebug() {
+ return debug;
+ }
+
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ @TaskAction
+ void exec() {
+ getProject().exec(new Action<ExecSpec>() {
+ @Override
+ public void execute(ExecSpec execSpec) {
+ try {
+ if (dxExecutable == null) {
+ dxExecutable = new File("tools/" + Utils.toolsDir() + "/dx/bin/dx");
+ }
+ execSpec.setExecutable(dxExecutable);
+ execSpec.args("--dex");
+ execSpec.args("--output");
+ execSpec.args(destination.getCanonicalPath());
+ if (isDebug()) {
+ execSpec.args("--debug");
+ }
+ execSpec.args(source.getFiles());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/smali/Smali.java b/buildSrc/src/main/java/smali/Smali.java
new file mode 100644
index 0000000..bd217d7
--- /dev/null
+++ b/buildSrc/src/main/java/smali/Smali.java
@@ -0,0 +1,59 @@
+// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package smali;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.gradle.api.DefaultTask;
+import org.gradle.api.UncheckedIOException;
+import org.gradle.api.file.FileTree;
+import org.gradle.api.tasks.TaskAction;
+
+public class Smali extends DefaultTask {
+
+ private FileTree source;
+ private File destination;
+ private File smaliScript;
+
+ public FileTree getSource() {
+ return source;
+ }
+
+ public void setSource(FileTree source) {
+ this.source = source;
+ getInputs().file(source);
+ }
+
+ public File getDestination() {
+ return destination;
+ }
+
+ public void setDestination(File destination) {
+ this.destination = destination;
+ getOutputs().file(destination);
+ }
+
+ public File getSmaliScript() {
+ return smaliScript;
+ }
+
+ public void setSmaliScript(File smaliScript) {
+ this.smaliScript = smaliScript;
+ }
+
+ @TaskAction
+ void exec() {
+ try {
+ List<String> fileNames = source.getFiles().stream().map(file -> file.toString())
+ .collect(Collectors.toList());
+ org.jf.smali.SmaliOptions options = new org.jf.smali.SmaliOptions();
+ options.outputDexFile = destination.getCanonicalPath().toString();
+ org.jf.smali.Smali.assemble(options, fileNames);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/utils/Utils.java b/buildSrc/src/main/java/utils/Utils.java
new file mode 100644
index 0000000..5e5e9d7
--- /dev/null
+++ b/buildSrc/src/main/java/utils/Utils.java
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package utils;
+
+public class Utils {
+ public static String toolsDir() {
+ return System.getProperty("os.name").equals("Mac OS X") ? "mac" : "linux";
+ }
+}