Merge "Tools: Switch from JAR-per-tool to a single swiss army knife"
diff --git a/build.gradle b/build.gradle
index 86ba02f..0f782b2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -514,7 +514,7 @@
classifier = null
version = null
manifest {
- attributes 'Main-Class': 'com.android.tools.r8.R8'
+ attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife'
}
// In order to build without dependencies, pass the exclude_deps property using:
// gradle -Pexclude_deps R8
@@ -527,164 +527,27 @@
}
task D8(type: ShadowJar) {
- from consolidatedLicense.outputs.files
- exclude { path ->
- path.getRelativePath().getPathString().startsWith("META-INF")
- }
+ from R8.outputs.files
baseName 'd8'
- classifier = null
- version = null
manifest {
attributes 'Main-Class': 'com.android.tools.r8.D8'
}
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps D8
- if (!project.hasProperty('exclude_deps')) {
- from repackageSources.outputs.files
- from repackageDeps.outputs.files
- } else {
- from sourceSets.main.output
- }
}
-task CompatDx(type: Jar) {
- from sourceSets.main.output
+task CompatDx(type: ShadowJar) {
+ from R8.outputs.files
baseName 'compatdx'
manifest {
attributes 'Main-Class': 'com.android.tools.r8.compatdx.CompatDx'
}
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps CompatDx
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
}
-task DexFileMerger(type: Jar) {
- from sourceSets.main.output
- baseName 'dexfilemerger'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.dexfilemerger.DexFileMerger'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps CompatDx
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task DexSplitter(type: Jar) {
- from sourceSets.main.output
- baseName 'dexsplitter'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.dexsplitter.DexSplitter'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps CompatDx
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task CompatProguard(type: Jar) {
- from sourceSets.main.output
+task CompatProguard(type: ShadowJar) {
+ from R8.outputs.files
baseName 'compatproguard'
manifest {
attributes 'Main-Class': 'com.android.tools.r8.compatproguard.CompatProguard'
}
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps CompatProguard
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task D8Logger(type: Jar) {
- from sourceSets.main.output
- baseName 'd8logger'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.D8Logger'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps D8Logger
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task disasm(type: Jar) {
- from sourceSets.main.output
- baseName 'disasm'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.Disassemble'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps D8
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task bisect(type: Jar) {
- from sourceSets.main.output
- baseName 'bisect'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.bisect.Bisect'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps R8
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task DexSegments(type: Jar) {
- from sourceSets.main.output
- baseName 'dexsegments'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.DexSegments'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps DexSegments
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task maindex(type: Jar) {
- from sourceSets.main.output
- baseName 'maindex'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.GenerateMainDexList'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps maindex
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
-task ExtractMarker(type: Jar) {
- from sourceSets.main.output
- baseName 'extractmarker'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.ExtractMarker'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps ExtractMarker
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
}
task bspatch(type: Jar) {
@@ -694,7 +557,7 @@
attributes 'Main-Class': 'com.android.tools.r8.dex.BSPatch'
}
// In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps maindex
+ // gradle -Pexclude_deps bspatch
if (!project.hasProperty('exclude_deps')) {
// Also include dependencies
from {
@@ -703,20 +566,6 @@
}
}
-task jardiff(type: Jar) {
- from sourceSets.main.output
- baseName 'jardiff'
- manifest {
- attributes 'Main-Class': 'com.android.tools.r8.JarDiff'
- }
- // In order to build without dependencies, pass the exclude_deps property using:
- // gradle -Pexclude_deps jardiff
- if (!project.hasProperty('exclude_deps')) {
- // Also include dependencies
- from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
- }
-}
-
task sourceJar(type: Jar, dependsOn: classes) {
classifier = 'src'
from sourceSets.main.allSource
diff --git a/src/main/java/com/android/tools/r8/SwissArmyKnife.java b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
new file mode 100644
index 0000000..0e35847
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
@@ -0,0 +1,83 @@
+// Copyright (c) 2018, 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 com.android.tools.r8;
+
+import com.android.tools.r8.bisect.Bisect;
+import com.android.tools.r8.compatdx.CompatDx;
+import com.android.tools.r8.compatproguard.CompatProguard;
+import com.android.tools.r8.dexfilemerger.DexFileMerger;
+import com.android.tools.r8.dexsplitter.DexSplitter;
+import java.util.Arrays;
+
+/**
+ * Common entry point to everything in the R8 project.
+ *
+ * <p>This class is used as the main class in {@code r8.jar}. It checks the first command-line
+ * argument to find the tool to run, or runs {@link R8} if the first argument is not a recognized
+ * tool name.
+ *
+ * <p>The set of tools recognized by this class is defined by a switch statement in {@link
+ * SwissArmyKnife#main(String[])}.
+ */
+public class SwissArmyKnife {
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ runDefault(args);
+ return;
+ }
+ switch (args[0]) {
+ case "r8":
+ R8.main(shift(args));
+ break;
+ case "d8":
+ D8.main(shift(args));
+ break;
+ case "compatdx":
+ CompatDx.main(shift(args));
+ break;
+ case "dexfilemerger":
+ DexFileMerger.main(shift(args));
+ break;
+ case "dexsplitter":
+ DexSplitter.main(shift(args));
+ break;
+ case "compatproguard":
+ CompatProguard.main(shift(args));
+ break;
+ case "d8logger":
+ D8Logger.main(shift(args));
+ break;
+ case "disasm":
+ Disassemble.main(shift(args));
+ break;
+ case "bisect":
+ Bisect.main(shift(args));
+ break;
+ case "dexsegments":
+ DexSegments.main(shift(args));
+ break;
+ case "maindex":
+ GenerateMainDexList.main(shift(args));
+ break;
+ case "extractmarker":
+ ExtractMarker.main(shift(args));
+ break;
+ case "jardiff":
+ JarDiff.main(shift(args));
+ break;
+ default:
+ runDefault(args);
+ break;
+ }
+ }
+
+ private static void runDefault(String[] args) {
+ R8.main(args);
+ }
+
+ private static String[] shift(String[] args) {
+ return Arrays.copyOfRange(args, 1, args.length);
+ }
+}
diff --git a/tools/archive.py b/tools/archive.py
index 76df65e..07f138a 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -3,22 +3,25 @@
# 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.
-import gradle
import create_maven_release
-import d8
+import gradle
import os
-import r8
+import shutil
import subprocess
import sys
+import toolhelper
import utils
-import shutil
import zipfile
ARCHIVE_BUCKET = 'r8-releases'
+def GetToolVersion(jar_path):
+ output = subprocess.check_output(['java', '-jar', jar_path, '--version'])
+ return output.splitlines()[0].strip()
+
def GetVersion():
- r8_version = r8.run(['--version'], build = False).splitlines()[0].strip()
- d8_version = d8.run(['--version'], build = False).splitlines()[0].strip()
+ r8_version = GetToolVersion(utils.R8_JAR)
+ d8_version = GetToolVersion(utils.D8_JAR)
# The version printed is "D8 vVERSION_NUMBER" and "R8 vVERSION_NUMBER"
# Sanity check that versions match.
if d8_version.split()[1] != r8_version.split()[1]:
diff --git a/tools/bisect.py b/tools/bisect.py
index c8d1501..74c880e 100755
--- a/tools/bisect.py
+++ b/tools/bisect.py
@@ -3,33 +3,8 @@
# 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.
-import gradle
-import os
-import subprocess
import sys
-import utils
-
-JAR = os.path.join(utils.REPO_ROOT, 'build', 'libs', 'bisect.jar')
-
-def run(args, build, debug):
- if build:
- gradle.RunGradle(['bisect'])
- cmd = ['java']
- if debug:
- cmd.append('-ea')
- cmd.extend(['-jar', JAR])
- cmd.extend(args)
- subprocess.check_call(cmd)
-
-def main():
- build = True
- args = []
- for arg in sys.argv[1:]:
- if arg in ("--build", "--no-build"):
- build = arg == "--build"
- else:
- args.append(arg)
- run(args, build, True)
+import toolhelper
if __name__ == '__main__':
- sys.exit(main())
+ sys.exit(toolhelper.run('bisect', sys.argv[1:]))
diff --git a/tools/compatdx.py b/tools/compatdx.py
index 25a59db..c4cb320 100755
--- a/tools/compatdx.py
+++ b/tools/compatdx.py
@@ -3,42 +3,8 @@
# 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.
-import gradle
-import os
-import subprocess
import sys
-import utils
-
-def run(args, build = True, debug = True, profile = False, track_memory_file=None):
- if build:
- gradle.RunGradle(['CompatDX'])
- cmd = []
- if track_memory_file:
- cmd.extend(['tools/track_memory.sh', track_memory_file])
- cmd.append('java')
- if debug:
- cmd.append('-ea')
- if profile:
- cmd.append('-agentlib:hprof=cpu=samples,interval=1,depth=8')
- cmd.extend(['-jar', utils.COMPATDX_JAR])
- cmd.extend(args)
- subprocess.check_call(cmd)
-
-def main():
- build = True
- args = []
- for arg in sys.argv[1:]:
- if arg in ("--build", "--no-build"):
- build = arg == "--build"
- else:
- args.append(arg)
- try:
- run(args, build)
- except subprocess.CalledProcessError as e:
- # In case anything relevant was printed to stdout, normally this is already
- # on stderr.
- print(e.output)
- return e.returncode
+import toolhelper
if __name__ == '__main__':
- sys.exit(main())
+ sys.exit(toolhelper.run('compatdx', sys.argv[1:]))
diff --git a/tools/compatproguard.py b/tools/compatproguard.py
new file mode 100755
index 0000000..10542e3
--- /dev/null
+++ b/tools/compatproguard.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('compatproguard', sys.argv[1:]))
diff --git a/tools/d8.py b/tools/d8.py
index bf97845..18a4a67 100755
--- a/tools/d8.py
+++ b/tools/d8.py
@@ -3,46 +3,8 @@
# 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.
-import gradle
-import os
-import subprocess
import sys
-import utils
-
-def run(args, build=True, debug=True, profile=False,
- track_memory_file=None):
- if build:
- gradle.RunGradle(['D8'])
- cmd = []
- if track_memory_file:
- cmd.extend(['tools/track_memory.sh', track_memory_file])
- cmd.append('java')
- if debug:
- cmd.append('-ea')
- if profile:
- cmd.append('-agentlib:hprof=cpu=samples,interval=1,depth=8')
- cmd.extend(['-jar', utils.D8_JAR])
- cmd.extend(args)
- utils.PrintCmd(cmd)
- result = subprocess.check_output(cmd)
- print(result)
- return result
-
-def main():
- build = True
- args = []
- for arg in sys.argv[1:]:
- if arg in ("--build", "--no-build"):
- build = arg == "--build"
- else:
- args.append(arg)
- try:
- run(args, build)
- except subprocess.CalledProcessError as e:
- # In case anything relevant was printed to stdout, normally this is already
- # on stderr.
- print(e.output)
- return e.returncode
+import toolhelper
if __name__ == '__main__':
- sys.exit(main())
+ sys.exit(toolhelper.run('d8', sys.argv[1:]))
diff --git a/tools/d8logger.py b/tools/d8logger.py
new file mode 100755
index 0000000..9fb3508
--- /dev/null
+++ b/tools/d8logger.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('d8logger', sys.argv[1:]))
diff --git a/tools/dexfilemerger.py b/tools/dexfilemerger.py
new file mode 100755
index 0000000..7bdfc22
--- /dev/null
+++ b/tools/dexfilemerger.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('dexfilemerger', sys.argv[1:]))
diff --git a/tools/dexsegments.py b/tools/dexsegments.py
new file mode 100755
index 0000000..f984063
--- /dev/null
+++ b/tools/dexsegments.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('dexsegments', sys.argv[1:]))
diff --git a/tools/dexsplitter.py b/tools/dexsplitter.py
new file mode 100755
index 0000000..415b149
--- /dev/null
+++ b/tools/dexsplitter.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('dexsplitter', sys.argv[1:]))
diff --git a/tools/disasm.py b/tools/disasm.py
new file mode 100755
index 0000000..0d2599a
--- /dev/null
+++ b/tools/disasm.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('disasm', sys.argv[1:]))
diff --git a/tools/extractmarker.py b/tools/extractmarker.py
new file mode 100755
index 0000000..36a9c88
--- /dev/null
+++ b/tools/extractmarker.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('extractmarker', sys.argv[1:]))
diff --git a/tools/jardiff.py b/tools/jardiff.py
new file mode 100755
index 0000000..894131c
--- /dev/null
+++ b/tools/jardiff.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('jardiff', sys.argv[1:]))
diff --git a/tools/maindex.py b/tools/maindex.py
new file mode 100755
index 0000000..ff5329a
--- /dev/null
+++ b/tools/maindex.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run('maindex', sys.argv[1:]))
diff --git a/tools/r8.py b/tools/r8.py
index 3ae4da7..60c60a0 100755
--- a/tools/r8.py
+++ b/tools/r8.py
@@ -3,46 +3,8 @@
# 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.
-import gradle
-import os
-import subprocess
import sys
-import utils
-
-def run(args, build=True, debug=True, profile=False,
- track_memory_file=None):
- if build:
- gradle.RunGradle(['r8'])
- cmd = []
- if track_memory_file:
- cmd.extend(['tools/track_memory.sh', track_memory_file])
- cmd.append('java')
- if debug:
- cmd.append('-ea')
- if profile:
- cmd.append('-agentlib:hprof=cpu=samples,interval=1,depth=8')
- cmd.extend(['-jar', utils.R8_JAR])
- cmd.extend(args)
- utils.PrintCmd(cmd)
- result = subprocess.check_output(cmd)
- print(result)
- return result
-
-def main():
- build = True
- args = []
- for arg in sys.argv[1:]:
- if arg in ("--build", "--no-build"):
- build = arg == "--build"
- else:
- args.append(arg)
- try:
- run(args, build)
- except subprocess.CalledProcessError as e:
- # In case anything relevant was printed to stdout, normally this is already
- # on stderr.
- print(e.output)
- return e.returncode
+import toolhelper
if __name__ == '__main__':
- sys.exit(main())
+ sys.exit(toolhelper.run('r8', sys.argv[1:]))
diff --git a/tools/run-d8-on-gmscore.py b/tools/run-d8-on-gmscore.py
index 63865d0..b1bdc6e 100755
--- a/tools/run-d8-on-gmscore.py
+++ b/tools/run-d8-on-gmscore.py
@@ -3,11 +3,11 @@
# 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.
-import d8
import gmscore_data
import optparse
import os
import sys
+import toolhelper
def ParseOptions():
result = optparse.OptionParser()
@@ -70,8 +70,13 @@
with open(options.dump_args_file, 'w') as args_file:
args_file.writelines([arg + os.linesep for arg in args])
else:
- d8.run(args, not options.no_build, not options.no_debug, options.profile,
- options.track_memory_to_file)
+ toolhelper.run(
+ 'd8',
+ args,
+ build=not options.no_build,
+ debug=not options.no_debug,
+ profile=options.profile,
+ track_memory_to_file=options.track_memory_to_file)
if __name__ == '__main__':
sys.exit(main())
diff --git a/tools/run_on_app.py b/tools/run_on_app.py
index b9bcc60..571d96d 100755
--- a/tools/run_on_app.py
+++ b/tools/run_on_app.py
@@ -10,10 +10,9 @@
import sys
import time
-import d8
import gmail_data
import gmscore_data
-import r8
+import toolhelper
import utils
import youtube_data
@@ -191,22 +190,20 @@
if options.print_memoryuse and not options.track_memory_to_file:
options.track_memory_to_file = os.path.join(temp,
utils.MEMORY_USE_TMP_FILE)
- if options.compiler == 'd8':
- d8.run(args, not options.no_build, not options.no_debug,
- options.profile, options.track_memory_to_file)
- else:
- if app_provided_pg_conf:
- # Ensure that output of -printmapping and -printseeds go to the output
- # location and not where the app Proguard configuration places them.
- if outdir.endswith('.zip') or outdir.endswith('.jar'):
- pg_outdir = os.path.dirname(outdir)
- else:
- pg_outdir = outdir
- additional_pg_conf = GenerateAdditionalProguardConfiguration(
- temp, os.path.abspath(pg_outdir))
- args.extend(['--pg-conf', additional_pg_conf])
- r8.run(args, not options.no_build, not options.no_debug,
- options.profile, options.track_memory_to_file)
+ if options.compiler == 'r8' and app_provided_pg_conf:
+ # Ensure that output of -printmapping and -printseeds go to the output
+ # location and not where the app Proguard configuration places them.
+ if outdir.endswith('.zip') or outdir.endswith('.jar'):
+ pg_outdir = os.path.dirname(outdir)
+ else:
+ pg_outdir = outdir
+ additional_pg_conf = GenerateAdditionalProguardConfiguration(
+ temp, os.path.abspath(pg_outdir))
+ args.extend(['--pg-conf', additional_pg_conf])
+ toolhelper.run(options.compiler, args, build=not options.no_build,
+ debug=not options.no_debug,
+ profile=options.profile,
+ track_memory_to_file=options.track_memory_to_file)
if options.print_memoryuse:
print('{}(MemoryUse): {}'
.format(options.print_memoryuse,
diff --git a/tools/toolhelper.py b/tools/toolhelper.py
new file mode 100644
index 0000000..a7f509c
--- /dev/null
+++ b/tools/toolhelper.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2018, 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.
+
+import gradle
+import os
+import subprocess
+import sys
+import utils
+
+def run(tool, args, build=None, debug=True,
+ profile=False, track_memory_file=None):
+ if build is None:
+ build, args = extract_build_from_args(args)
+ if build:
+ gradle.RunGradle(['r8'])
+ cmd = []
+ if track_memory_file:
+ cmd.extend(['tools/track_memory.sh', track_memory_file])
+ cmd.append('java')
+ if debug:
+ cmd.append('-ea')
+ if profile:
+ cmd.append('-agentlib:hprof=cpu=samples,interval=1,depth=8')
+ cmd.extend(['-jar', utils.R8_JAR, tool])
+ cmd.extend(args)
+ utils.PrintCmd(cmd)
+ return subprocess.call(cmd)
+
+def extract_build_from_args(input_args):
+ build = True
+ args = []
+ for arg in input_args:
+ if arg in ("--build", "--no-build"):
+ build = arg == "--build"
+ else:
+ args.append(arg)
+ return build, args