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 3# found in the LICENSE file. 4 5from recipe_engine import recipe_api 6 7import default_flavor 8import gn_android_flavor 9import subprocess 10 11 12"""GN Chromecast flavor utils, used for building Skia for Chromecast with GN""" 13class GNChromecastFlavorUtils(gn_android_flavor.GNAndroidFlavorUtils): 14 def __init__(self, m): 15 super(GNChromecastFlavorUtils, self).__init__(m) 16 self._ever_ran_adb = False 17 18 def compile(self, unused_target): 19 configuration = self.m.vars.builder_cfg.get('configuration') 20 os = self.m.vars.builder_cfg.get('os') 21 target_arch = self.m.vars.builder_cfg.get('target_arch') 22 23 # Makes the binary small enough to fit on the small disk. 24 extra_cflags = ['-g0'] 25 # Chromecast does not package libstdc++ 26 extra_ldflags = ['-static-libstdc++', '-static-libgcc'] 27 28 toolchain_dir = self.m.vars.slave_dir.join('cast_toolchain') 29 30 quote = lambda x: '"%s"' % x 31 args = { 32 'cc': quote(toolchain_dir.join('bin','armv7a-cros-linux-gnueabi-gcc')), 33 'cxx': quote(toolchain_dir.join('bin','armv7a-cros-linux-gnueabi-g++')), 34 'ar': quote(toolchain_dir.join('bin','armv7a-cros-linux-gnueabi-ar')), 35 'target_cpu': quote(target_arch), 36 'skia_use_fontconfig': 'false', 37 'skia_enable_gpu': 'false', 38 # The toolchain won't allow system libraries to be used 39 # when cross-compiling 40 'skia_use_system_freetype2': 'false', 41 # Makes the binary smaller 42 'skia_use_icu': 'false', 43 } 44 45 if configuration != 'Debug': 46 args['is_debug'] = 'false' 47 args['extra_cflags'] = repr(extra_cflags).replace("'", '"') 48 args['extra_ldflags'] = repr(extra_ldflags).replace("'", '"') 49 50 gn_args = ' '.join('%s=%s' % (k,v) for (k,v) in sorted(args.iteritems())) 51 52 gn = 'gn.exe' if 'Win' in os else 'gn' 53 ninja = 'ninja.exe' if 'Win' in os else 'ninja' 54 gn = self.m.vars.skia_dir.join('bin', gn) 55 56 self._py('fetch-gn', self.m.vars.skia_dir.join('bin', 'fetch-gn')) 57 self._run('gn gen', gn, 'gen', self.out_dir, '--args=' + gn_args) 58 # We only build perf for the chromecasts. 59 self._run('ninja', ninja, '-C', self.out_dir, 'nanobench') 60 61 def _adb(self, title, *cmd, **kwargs): 62 if not self._ever_ran_adb: 63 self._connect_to_remote() 64 65 self._ever_ran_adb = True 66 # The only non-infra adb steps (dm / nanobench) happen to not use _adb(). 67 if 'infra_step' not in kwargs: 68 kwargs['infra_step'] = True 69 return self._run(title, 'adb', *cmd, **kwargs) 70 71 def _connect_to_remote(self): 72 73 ip_address = self.m.run(self.m.python.inline, 'read chromecast ip', 74 program=""" 75 import os 76 CHROMECAST_IP_FILE = os.path.expanduser('~/chromecast.txt') 77 with open(CHROMECAST_IP_FILE, 'r') as f: 78 print f.read() 79 """, 80 stdout=self.m.raw_io.output(), 81 infra_step=True).stdout 82 83 self.m.run(self.m.step, 'adb connect %s' % ip_address, cmd=['adb', 84 'connect', ip_address], infra_step=True) 85 86 def create_clean_device_dir(self, path): 87 # Note: Chromecast does not support -rf 88 self._adb('rm %s' % path, 'shell', 'rm', '-r', path) 89 self._adb('mkdir %s' % path, 'shell', 'mkdir', '-p', path) 90 91 def copy_directory_contents_to_device(self, host, device): 92 # Copy the tree, avoiding hidden directories and resolving symlinks. 93 # Additionally, due to space restraints, we don't push files > 3 MB 94 # which cuts down the size of the SKP asset to be around 50 MB as of 95 # version 41. 96 self.m.run(self.m.python.inline, 'push %s/* %s' % (host, device), 97 program=""" 98 import os 99 import subprocess 100 import sys 101 host = sys.argv[1] 102 device = sys.argv[2] 103 for d, _, fs in os.walk(host): 104 p = os.path.relpath(d, host) 105 if p != '.' and p.startswith('.'): 106 continue 107 for f in fs: 108 print os.path.join(p,f) 109 hp = os.path.realpath(os.path.join(host, p, f)) 110 if os.stat(hp).st_size > (3 * 1024 * 1024): 111 print "Skipping because it is too big" 112 else: 113 subprocess.check_call(['adb', 'push', 114 hp, os.path.join(device, p, f)]) 115 """, args=[host, device], infra_step=True) 116