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, title, *cmd, **kwargs): |
13 path = self.m.vars.default_env['PATH'] | 28 self.m.vars.default_env = {k: v for (k,v) |
14 self.m.vars.default_env = {'PATH': path} | 29 in self.m.vars.default_env.iteritems() |
15 self.m.run(self.m.step, title, cmd=cmd, cwd=self.m.vars.skia_dir, env={}) | 30 if k in ['PATH']} |
| 31 return self.m.run(self.m.step, title, cmd=list(cmd), |
| 32 cwd=self.m.vars.skia_dir, env={}, **kwargs) |
| 33 |
| 34 def _adb(self, title, *cmd, **kwargs): |
| 35 self._ever_ran_adb = True |
| 36 return self._run(title, 'adb', *cmd, **kwargs) |
16 | 37 |
17 def compile(self, unused_target, **kwargs): | 38 def compile(self, unused_target, **kwargs): |
18 compiler = self.m.vars.builder_cfg.get('compiler') | 39 compiler = self.m.vars.builder_cfg.get('compiler') |
19 configuration = self.m.vars.builder_cfg.get('configuration') | 40 configuration = self.m.vars.builder_cfg.get('configuration') |
20 os = self.m.vars.builder_cfg.get('os') | 41 os = self.m.vars.builder_cfg.get('os') |
21 target_arch = self.m.vars.builder_cfg.get('target_arch') | 42 target_arch = self.m.vars.builder_cfg.get('target_arch') |
22 | 43 |
23 assert compiler == 'Clang' # At this rate we might not ever support GCC. | 44 assert compiler == 'Clang' # At this rate we might not ever support GCC. |
24 | 45 |
25 ndk_asset = 'android_ndk_linux' if os == 'Ubuntu' else 'android_ndk_darwin' | 46 ndk_asset = 'android_ndk_linux' if os == 'Ubuntu' else 'android_ndk_darwin' |
26 | 47 |
27 quote = lambda x: '"%s"' % x | 48 quote = lambda x: '"%s"' % x |
28 gn_args = ' '.join('%s=%s' % (k,v) for (k,v) in sorted({ | 49 gn_args = ' '.join('%s=%s' % (k,v) for (k,v) in sorted({ |
29 'is_debug': 'true' if configuration == 'Debug' else 'false', | 50 'is_debug': 'true' if configuration == 'Debug' else 'false', |
30 'ndk': quote(self.m.vars.slave_dir.join(ndk_asset)), | 51 'ndk': quote(self.m.vars.slave_dir.join(ndk_asset)), |
31 'target_cpu': quote(target_arch), | 52 'target_cpu': quote(target_arch), |
32 }.iteritems())) | 53 }.iteritems())) |
33 | 54 |
34 self._run('fetch-gn', [self.m.vars.skia_dir.join('bin', 'fetch-gn')]) | 55 self._run('fetch-gn', self.m.vars.skia_dir.join('bin', 'fetch-gn')) |
35 self._run('gn gen', ['gn', 'gen', self.out_dir, '--args=' + gn_args]) | 56 self._run('gn gen', 'gn', 'gen', self.out_dir, '--args=' + gn_args) |
36 self._run('ninja', ['ninja', '-C', self.out_dir]) | 57 self._run('ninja', 'ninja', '-C', self.out_dir) |
| 58 |
| 59 def install(self): |
| 60 self._adb('reboot', 'reboot') |
| 61 self._adb('wait for device', 'wait-for-usb-device') |
| 62 self._adb('TEMPORARY clear /data/local/tmp', |
| 63 'shell', 'rm', '-rf', '/data/local/tmp/*') |
| 64 self._adb('mkdir /data/local/tmp/resources', |
| 65 'shell', 'mkdir', '-p', '/data/local/tmp/resources') |
| 66 |
| 67 def cleanup_steps(self): |
| 68 if self._ever_ran_adb: |
| 69 self._adb('TEMPORARY clear /data/local/tmp', |
| 70 'shell', 'rm', '-rf', '/data/local/tmp/*') |
| 71 self._adb('TEMPORARY reboot', 'reboot') |
| 72 self._adb('kill adb server', 'kill-server') |
| 73 |
| 74 def step(self, name, cmd, env=None, **kwargs): |
| 75 app = self.m.vars.skia_out.join(self.m.vars.configuration, cmd[0]) |
| 76 self._adb('push %s' % cmd[0], |
| 77 'push', app, '/data/local/tmp') |
| 78 |
| 79 sh = '%s.sh' % cmd[0] |
| 80 self.m.run.writefile(self.m.vars.tmp_dir.join(sh), |
| 81 'set -x; /data/local/tmp/%s; echo $? >/data/local/tmp/rc' % |
| 82 subprocess.list2cmdline(map(str, cmd))) |
| 83 self._adb('push %s' % sh, |
| 84 'push', self.m.vars.tmp_dir.join(sh), '/data/local/tmp') |
| 85 |
| 86 self._adb('clear log', 'logcat', '-c') |
| 87 self._adb(cmd[0], 'shell', 'sh', '/data/local/tmp/' + sh) |
| 88 self._adb('dump log ', 'logcat', '-d') |
| 89 |
| 90 self.m.python.inline('check %s rc' % cmd[0], """ |
| 91 import subprocess |
| 92 import sys |
| 93 sys.exit(int(subprocess.check_output(['adb', 'shell', 'cat', |
| 94 '/data/local/tmp/rc']))) |
| 95 """) |
| 96 |
| 97 def copy_file_to_device(self, host, device): |
| 98 self._adb('push %s %s' % (host, device), 'push', host, device) |
| 99 |
| 100 def copy_directory_contents_to_device(self, host, device): |
| 101 # Copy the tree, avoiding hidden directories and resolving symlinks. |
| 102 self.m.python.inline('push %s/* %s' % (host, device), """ |
| 103 import os |
| 104 import subprocess |
| 105 import sys |
| 106 host = sys.argv[1] |
| 107 device = sys.argv[2] |
| 108 for d, _, fs in os.walk(host): |
| 109 p = os.path.relpath(d, host) |
| 110 if p != '.' and p.startswith('.'): |
| 111 continue |
| 112 for f in fs: |
| 113 print os.path.join(p,f) |
| 114 subprocess.check_call(['adb', 'push', |
| 115 os.path.realpath(os.path.join(host, p, f)), |
| 116 os.path.join(device, p, f)]) |
| 117 """, args=[host, device], cwd=self.m.vars.skia_dir) |
| 118 |
| 119 def copy_directory_contents_to_host(self, device, host): |
| 120 self._adb('pull %s %s' % (device, host), 'pull', device, host) |
| 121 |
| 122 def read_file_on_device(self, path): |
| 123 return self._adb('read %s' % path, |
| 124 'shell', 'cat', path, stdout=self.m.raw_io.output()).stdout |
| 125 |
| 126 def remove_file_on_device(self, path): |
| 127 self._adb('rm %s' % path, 'shell', 'rm', '-f', path) |
| 128 |
| 129 def create_clean_device_dir(self, path): |
| 130 self._adb('rm %s' % path, 'shell', 'rm', '-rf', path) |
| 131 self._adb('mkdir %s' % path, 'shell', 'mkdir', '-p', path) |
OLD | NEW |