blob: e1b2deb496d8d9ea17fe1fb7a884cca00a84b6b8 [file] [log] [blame]
Rico Wind0ed24cc2018-03-23 07:16:35 +01001#!/usr/bin/env python
2# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
6# Script for building sample apks using the sdk tools directly.
7
8import apk_utils
9import fnmatch
10import glob
11import optparse
12import os
13import shutil
14import subprocess
15import sys
16import utils
17
18ANDROID_JAR = 'third_party/android_jar/lib-v{api}/android.jar'
19DEFAULT_AAPT = 'aapt' # Assume in path.
20DEFAULT_D8 = os.path.join(utils.REPO_ROOT, 'tools', 'd8.py')
21DEFAULT_JAVAC = 'javac'
22SRC_LOCATION = 'src/com/android/tools/r8/sample/{app}/*.java'
23DEFAULT_KEYSTORE = os.path.join(os.getenv('HOME'), '.android', 'debug.keystore')
24
25SAMPLE_APKS = [
26 'simple'
27]
28
29def parse_options():
30 result = optparse.OptionParser()
31 result.add_option('--aapt',
32 help='aapt executable to use',
33 default=DEFAULT_AAPT)
34 result.add_option('--api',
35 help='Android api level',
36 default=21,
37 choices=[14, 15, 19, 21, 22, 23, 24, 25, 26])
38 result.add_option('--keystore',
39 help='Keystore used for signing',
40 default=DEFAULT_KEYSTORE)
41 result.add_option('--app',
42 help='Which app to build',
43 default='simple',
44 choices=SAMPLE_APKS)
45 return result.parse_args()
46
47def run_aapt(aapt, args):
48 command = [aapt]
49 command.extend(args)
50 utils.PrintCmd(command)
51 subprocess.check_call(command)
52
53def get_build_dir(app):
54 return os.path.join(utils.BUILD, 'sampleApks', app)
55
56def get_gen_path(app):
57 gen_path = os.path.join(get_build_dir(app), 'gen')
58 utils.makedirs_if_needed(gen_path)
59 return gen_path
60
61def get_bin_path(app):
62 bin_path = os.path.join(get_build_dir(app), 'bin')
63 utils.makedirs_if_needed(bin_path)
64 return bin_path
65
66def get_android_jar(api):
67 return os.path.join(utils.REPO_ROOT, ANDROID_JAR.format(api=api))
68
69def get_sample_dir(app):
70 return os.path.join(utils.REPO_ROOT, 'src', 'test', 'sampleApks', app)
71
72def get_src_path(app):
73 return os.path.join(get_sample_dir(app), 'src')
74
75def run_aapt_pack(aapt, api, app):
76 with utils.ChangedWorkingDirectory(get_sample_dir(app)):
77 args = ['package',
78 '-v', '-f',
79 '-I', get_android_jar(api),
80 '-M', 'AndroidManifest.xml',
81 '-A', 'assets',
82 '-S', 'res',
83 '-m',
84 '-J', get_gen_path(app),
Søren Gjesse12c52092018-04-05 14:22:29 +020085 '-F', os.path.join(get_bin_path(app), 'resources.ap_'),
86 '-G', os.path.join(get_build_dir(app), 'proguard_options')]
Rico Wind0ed24cc2018-03-23 07:16:35 +010087 run_aapt(aapt, args)
88
89def compile_with_javac(api, app):
90 with utils.ChangedWorkingDirectory(get_sample_dir(app)):
91 files = glob.glob(SRC_LOCATION.format(app=app))
92 command = [DEFAULT_JAVAC,
93 '-classpath', get_android_jar(api),
94 '-sourcepath', '%s:%s' % (get_src_path(app), get_gen_path(app)),
95 '-d', get_bin_path(app)]
96 command.extend(files)
97 utils.PrintCmd(command)
98 subprocess.check_call(command)
99
100def dex(app, api):
101 files = []
102 for root, dirnames, filenames in os.walk(get_bin_path(app)):
103 for filename in fnmatch.filter(filenames, '*.class'):
104 files.append(os.path.join(root, filename))
105 command = [DEFAULT_D8,
106 '--output', get_bin_path(app),
107 '--classpath', get_android_jar(api),
108 '--min-api', str(api)]
109 command.extend(files)
110 utils.PrintCmd(command)
111 subprocess.check_call(command)
112
113def create_temp_apk(app):
114 temp_apk_path = os.path.join(get_bin_path(app), '%s.ap_' % app)
115 shutil.move(os.path.join(get_bin_path(app), 'resources.ap_'),
116 temp_apk_path)
117 return temp_apk_path
118
119def aapt_add_dex(aapt, app, temp_apk_path):
120 args = ['add',
121 '-k', temp_apk_path,
122 os.path.join(get_bin_path(app), 'classes.dex')]
123 run_aapt(aapt, args)
124
125def Main():
126 (options, args) = parse_options()
127 run_aapt_pack(options.aapt, options.api, options.app)
128 compile_with_javac(options.api, options.app)
129 dex(options.app, options.api)
130 temp_apk_path = create_temp_apk(options.app)
131 aapt_add_dex(options.aapt, options.app, temp_apk_path)
132 apk_path = os.path.join(get_bin_path(options.app), '%s.apk' % options.app)
133 apk_utils.sign(temp_apk_path, apk_path, options.keystore)
134 print('Apk available at: %s' % apk_path)
135
136if __name__ == '__main__':
137 sys.exit(Main())