OLD | NEW |
---|---|
1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import default_flavor | 5 import default_flavor |
6 import subprocess | |
6 | 7 |
7 """GN Android flavor utils, used for building Skia for Android with GN.""" | 8 """GN Android flavor utils, used for building Skia for Android with GN.""" |
8 class GNAndroidFlavorUtils(default_flavor.DefaultFlavorUtils): | 9 class GNAndroidFlavorUtils(default_flavor.DefaultFlavorUtils): |
10 def __init__(self, m): | |
11 super(GNAndroidFlavorUtils, self).__init__(m) | |
12 self._ever_ran_adb = False | |
13 | |
14 prefix = '/data/local/tmp/' | |
15 self.device_dirs = default_flavor.DeviceDirs( | |
16 dm_dir = prefix + 'dm_out', | |
17 perf_data_dir = prefix + 'perf', | |
18 resource_dir = prefix + 'resources', | |
19 images_dir = prefix + 'images', | |
20 skp_dir = prefix + 'skps', | |
21 svg_dir = prefix + 'svgs', | |
22 tmp_dir = prefix + 'tmp') | |
23 | |
9 def supported(self): | 24 def supported(self): |
10 return 'GN_Android' == self.m.vars.builder_cfg.get('extra_config', '') | 25 return 'GN_Android' == self.m.vars.builder_cfg.get('extra_config', '') |
11 | 26 |
12 def _run(self, title, cmd): | 27 def _run(self, *cmd, **kwargs): |
13 path = self.m.vars.default_env['PATH'] | 28 cmd = map(str, cmd) |
14 self.m.vars.default_env = {'PATH': path} | 29 title = subprocess.list2cmdline(cmd) |
borenet
2016/09/12 13:10:12
This generates bad step names, eg. containing symb
mtklein
2016/09/12 14:12:12
Huh. What error did you see?
But, done... update
borenet
2016/09/12 14:32:00
No error here, but the master refuses to create lo
| |
15 self.m.run(self.m.step, title, cmd=cmd, cwd=self.m.vars.skia_dir, env={}) | 30 self.m.vars.default_env = {k: v for (k,v) |
31 in self.m.vars.default_env.iteritems() | |
32 if k in ['PATH']} | |
borenet
2016/09/12 13:10:12
Why do we need to overwrite the default_env here?
mtklein
2016/09/12 14:12:12
Same deal as in gn_flavor.py and this file previou
borenet
2016/09/12 14:32:00
This is fine for now, but the assumption for defau
| |
33 return self.m.run(self.m.step, title, cmd=cmd, | |
34 cwd=self.m.vars.skia_dir, env={}, **kwargs) | |
35 | |
36 def _adb(self, *cmd, **kwargs): | |
37 self._ever_ran_adb = True | |
38 return self._run('adb', *cmd, **kwargs) | |
16 | 39 |
17 def compile(self, unused_target, **kwargs): | 40 def compile(self, unused_target, **kwargs): |
18 compiler = self.m.vars.builder_cfg.get('compiler') | 41 compiler = self.m.vars.builder_cfg.get('compiler') |
19 configuration = self.m.vars.builder_cfg.get('configuration') | 42 configuration = self.m.vars.builder_cfg.get('configuration') |
20 os = self.m.vars.builder_cfg.get('os') | 43 os = self.m.vars.builder_cfg.get('os') |
21 target_arch = self.m.vars.builder_cfg.get('target_arch') | 44 target_arch = self.m.vars.builder_cfg.get('target_arch') |
22 | 45 |
23 assert compiler == 'Clang' # At this rate we might not ever support GCC. | 46 assert compiler == 'Clang' # At this rate we might not ever support GCC. |
24 | 47 |
25 ndk_asset = 'android_ndk_linux' if os == 'Ubuntu' else 'android_ndk_darwin' | 48 ndk_asset = 'android_ndk_linux' if os == 'Ubuntu' else 'android_ndk_darwin' |
26 | 49 |
27 quote = lambda x: '"%s"' % x | 50 quote = lambda x: '"%s"' % x |
28 gn_args = ' '.join('%s=%s' % (k,v) for (k,v) in sorted({ | 51 gn_args = ' '.join('%s=%s' % (k,v) for (k,v) in sorted({ |
29 'is_debug': 'true' if configuration == 'Debug' else 'false', | 52 'is_debug': 'true' if configuration == 'Debug' else 'false', |
30 'ndk': quote(self.m.vars.slave_dir.join(ndk_asset)), | 53 'ndk': quote(self.m.vars.slave_dir.join(ndk_asset)), |
31 'target_cpu': quote(target_arch), | 54 'target_cpu': quote(target_arch), |
32 }.iteritems())) | 55 }.iteritems())) |
33 | 56 |
34 self._run('fetch-gn', [self.m.vars.skia_dir.join('bin', 'fetch-gn')]) | 57 self._run(self.m.vars.skia_dir.join('bin', 'fetch-gn')) |
35 self._run('gn gen', ['gn', 'gen', self.out_dir, '--args=' + gn_args]) | 58 self._run('gn', 'gen', self.out_dir, '--args=' + gn_args) |
36 self._run('ninja', ['ninja', '-C', self.out_dir]) | 59 self._run('ninja', '-C', self.out_dir) |
60 | |
61 def install(self): | |
62 self._adb('reboot') | |
63 self._adb('wait-for-usb-device') | |
64 self._adb('shell', 'rm', '-rf', '/data/local/tmp/*') # TEMPORARY | |
borenet
2016/09/12 13:10:12
Do we really need this? It's going to require us
mtklein
2016/09/12 14:12:12
Not sure, but we definitely don't need it in the l
borenet
2016/09/12 14:32:00
SGTM
| |
65 self._adb('shell', 'mkdir', '-p', '/data/local/tmp/resources') | |
66 | |
67 def cleanup_steps(self): | |
68 if self._ever_ran_adb: | |
69 self._adb('shell', 'rm', '-rf', '/data/local/tmp/*') # TEMPORARY | |
70 self._adb('reboot') # TEMPORARY | |
71 self._adb('kill-server') | |
72 | |
73 def step(self, name, cmd, env=None, **kwargs): | |
74 app = self.m.vars.skia_out.join(self.m.vars.configuration, cmd[0]) | |
75 self._adb('push', app, '/data/local/tmp') | |
76 | |
77 sh = '%s.sh' % cmd[0] | |
78 self.m.run.writefile(self.m.vars.tmp_dir.join(sh), | |
79 'set -x; /data/local/tmp/%s; echo $? >/data/local/tmp/rc' % | |
80 subprocess.list2cmdline(map(str, cmd))) | |
81 self._adb('push', self.m.vars.tmp_dir.join(sh), '/data/local/tmp') | |
82 | |
83 self._adb('logcat', '-c') | |
84 self._adb('shell', 'sh', '/data/local/tmp/' + sh) | |
85 self._adb('logcat', '-d') | |
86 | |
87 self.m.python.inline('check %s rc' % sh, """ | |
88 import subprocess | |
89 import sys | |
90 sys.exit(int(subprocess.check_output(['adb', 'shell', 'cat', | |
91 '/data/local/tmp/rc']))) | |
92 """) | |
93 | |
94 def copy_file_to_device(self, host, device): | |
95 self._adb('push', host, device) | |
96 | |
97 def copy_directory_contents_to_device(self, host, device): | |
98 # Copy the tree, avoiding hidden directories and resolving symlinks. | |
99 self.m.python.inline('push %s/* %s' % (host, device), """ | |
100 import os | |
101 import subprocess | |
102 import sys | |
103 host = sys.argv[1] | |
104 device = sys.argv[2] | |
105 for d, _, fs in os.walk(host): | |
106 p = os.path.relpath(d, host) | |
107 if p != '.' and p.startswith('.'): | |
108 continue | |
109 for f in fs: | |
110 print os.path.join(p,f) | |
111 subprocess.check_call(['adb', 'push', | |
112 os.path.realpath(os.path.join(host, p, f)), | |
113 os.path.join(device, p, f)]) | |
114 """, args=[host, device], cwd=self.m.vars.skia_dir) | |
115 | |
116 def copy_directory_contents_to_host(self, device, host): | |
117 self._adb('pull', device, host) | |
118 | |
119 def read_file_on_device(self, path): | |
120 return self._adb('shell', 'cat', path, | |
121 stdout=self.m.raw_io.output()).stdout | |
122 | |
123 def remove_file_on_device(self, path): | |
124 self._adb('shell', 'rm', '-f', path) | |
125 | |
126 def create_clean_device_dir(self, path): | |
127 self._adb('shell', 'rm', '-rf', path) | |
128 self._adb('shell', 'mkdir', '-p', path) | |
OLD | NEW |