Home | History | Annotate | Download | only in flavor
      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 
      5 import default_flavor
      6 
      7 """GN flavor utils, used for building Skia with GN."""
      8 class GNFlavorUtils(default_flavor.DefaultFlavorUtils):
      9   def _run(self, title, cmd, infra_step=False):
     10     self.m.run(self.m.step, title, cmd=cmd,
     11                infra_step=infra_step)
     12 
     13   def _py(self, title, script, infra_step=True, args=()):
     14     self.m.run(self.m.python, title, script=script, args=args,
     15                infra_step=infra_step)
     16 
     17   def build_command_buffer(self):
     18     self.m.run(self.m.python, 'build command_buffer',
     19         script=self.m.vars.skia_dir.join('tools', 'build_command_buffer.py'),
     20         args=[
     21           '--chrome-dir', self.m.vars.checkout_root,
     22           '--output-dir', self.m.vars.skia_out.join(self.m.vars.configuration),
     23           '--no-sync', '--make-output-dir'])
     24 
     25   def compile(self, unused_target):
     26     """Build Skia with GN."""
     27     compiler      = self.m.vars.builder_cfg.get('compiler',      '')
     28     configuration = self.m.vars.builder_cfg.get('configuration', '')
     29     extra_config  = self.m.vars.builder_cfg.get('extra_config',  '')
     30     os            = self.m.vars.builder_cfg.get('os',            '')
     31     target_arch   = self.m.vars.builder_cfg.get('target_arch',   '')
     32 
     33     clang_linux   = str(self.m.vars.slave_dir.join('clang_linux'))
     34     linux_vulkan_sdk   = str(self.m.vars.slave_dir.join('linux_vulkan_sdk'))
     35     win_toolchain = str(self.m.vars.slave_dir.join(
     36       't', 'depot_tools', 'win_toolchain', 'vs_files',
     37       'd3cb0e37bdd120ad0ac4650b674b09e81be45616'))
     38     win_vulkan_sdk = str(self.m.vars.slave_dir.join('win_vulkan_sdk'))
     39 
     40     cc, cxx = None, None
     41     extra_cflags = []
     42     extra_ldflags = []
     43 
     44     if compiler == 'Clang' and os == 'Ubuntu':
     45       cc  = clang_linux + '/bin/clang'
     46       cxx = clang_linux + '/bin/clang++'
     47       extra_ldflags.append('-fuse-ld=lld')
     48     elif compiler == 'Clang':
     49       cc, cxx = 'clang', 'clang++'
     50     elif compiler == 'GCC':
     51       cc, cxx = 'gcc', 'g++'
     52 
     53     if compiler != 'MSVC' and configuration == 'Debug':
     54       extra_cflags.append('-O1')
     55 
     56     if extra_config == 'Exceptions':
     57       extra_cflags.append('/EHsc')
     58     if extra_config == 'Fast':
     59       extra_cflags.extend(['-march=native', '-fomit-frame-pointer', '-O3',
     60                            '-ffp-contract=off'])
     61     if extra_config.startswith('SK'):
     62       extra_cflags.append('-D' + extra_config)
     63     if extra_config == 'MSAN':
     64       extra_ldflags.append('-L' + clang_linux + '/msan')
     65 
     66     args = {}
     67 
     68     if configuration != 'Debug':
     69       args['is_debug'] = 'false'
     70     if extra_config == 'ANGLE':
     71       args['skia_use_angle'] = 'true'
     72     if extra_config == 'CommandBuffer':
     73       self.m.run.run_once(self.build_command_buffer)
     74     if extra_config == 'GDI':
     75       args['skia_use_gdi'] = 'true'
     76     if extra_config == 'MSAN':
     77       args['skia_use_fontconfig'] = 'false'
     78     if extra_config == 'ASAN':
     79       args['skia_enable_spirv_validation'] = 'false'
     80     if extra_config == 'Mesa':
     81       args['skia_use_mesa'] = 'true'
     82     if extra_config == 'Mini':
     83       args.update({
     84         'is_component_build':     'true',   # Proves we can link a coherent .so.
     85         'is_official_build':      'true',   # No debug symbols, no tools.
     86         'skia_enable_effects':    'false',
     87         'skia_enable_gpu':        'false',
     88         'skia_enable_pdf':        'false',
     89         'skia_use_expat':         'false',
     90         'skia_use_libjpeg_turbo': 'false',
     91         'skia_use_libpng':        'false',
     92         'skia_use_libwebp':       'false',
     93         'skia_use_zlib':          'false',
     94       })
     95     if extra_config == 'NoGPU':
     96       args['skia_enable_gpu'] = 'false'
     97     if extra_config == 'Shared':
     98       args['is_component_build'] = 'true'
     99     if extra_config == 'Vulkan':
    100       args['skia_enable_vulkan_debug_layers'] = 'false'
    101       if os == 'Ubuntu':
    102         args['skia_vulkan_sdk'] = '"%s"' % linux_vulkan_sdk
    103       if 'Win' in os:
    104         args['skia_vulkan_sdk'] = '"%s"' % win_vulkan_sdk
    105 
    106     for (k,v) in {
    107       'cc':  cc,
    108       'cxx': cxx,
    109       'sanitize': extra_config if 'SAN' in extra_config else '',
    110       'target_cpu': target_arch,
    111       'target_os': 'ios' if 'iOS' in extra_config else '',
    112       'windk': win_toolchain if 'Win' in os else '',
    113     }.iteritems():
    114       if v:
    115         args[k] = '"%s"' % v
    116     if extra_cflags:
    117       args['extra_cflags'] = repr(extra_cflags).replace("'", '"')
    118     if extra_ldflags:
    119       args['extra_ldflags'] = repr(extra_ldflags).replace("'", '"')
    120 
    121     gn_args = ' '.join('%s=%s' % (k,v) for (k,v) in sorted(args.iteritems()))
    122 
    123     gn    = 'gn.exe'    if 'Win' in os else 'gn'
    124     ninja = 'ninja.exe' if 'Win' in os else 'ninja'
    125     gn = self.m.vars.skia_dir.join('bin', gn)
    126 
    127     with self.m.step.context({'cwd': self.m.vars.skia_dir}):
    128       self._py('fetch-gn', self.m.vars.skia_dir.join('bin', 'fetch-gn'))
    129       self._run('gn gen', [gn, 'gen', self.out_dir, '--args=' + gn_args])
    130       self._run('ninja', [ninja, '-C', self.out_dir])
    131 
    132   def copy_extra_build_products(self, swarming_out_dir):
    133     configuration = self.m.vars.builder_cfg.get('configuration', '')
    134     extra_config  = self.m.vars.builder_cfg.get('extra_config',  '')
    135     os            = self.m.vars.builder_cfg.get('os',            '')
    136 
    137     win_vulkan_sdk = str(self.m.vars.slave_dir.join('win_vulkan_sdk'))
    138     if 'Win' in os and extra_config == 'Vulkan':
    139       self.m.run.copy_build_products(
    140           win_vulkan_sdk,
    141           swarming_out_dir.join('out', configuration + '_x64'))
    142 
    143   def step(self, name, cmd):
    144     app = self.m.vars.skia_out.join(self.m.vars.configuration, cmd[0])
    145     cmd = [app] + cmd[1:]
    146     env = self.m.step.get_from_context('env', {})
    147 
    148     clang_linux = str(self.m.vars.slave_dir.join('clang_linux'))
    149     extra_config = self.m.vars.builder_cfg.get('extra_config', '')
    150 
    151     if 'SAN' in extra_config:
    152       # Sanitized binaries may want to run clang_linux/bin/llvm-symbolizer.
    153       env['PATH'] = '%%(PATH)s:%s' % clang_linux + '/bin'
    154     elif 'Ubuntu' == self.m.vars.builder_cfg.get('os', ''):
    155       cmd = ['catchsegv'] + cmd
    156 
    157     if 'ASAN' == extra_config:
    158       env[ 'ASAN_OPTIONS'] = 'symbolize=1 detect_leaks=1'
    159       env[ 'LSAN_OPTIONS'] = 'symbolize=1 print_suppressions=1'
    160       env['UBSAN_OPTIONS'] = 'symbolize=1 print_stacktrace=1'
    161 
    162     if 'MSAN' == extra_config:
    163       # Find the MSAN-built libc++.
    164       env['LD_LIBRARY_PATH'] = clang_linux + '/msan'
    165 
    166     to_symbolize = ['dm', 'nanobench']
    167     if name in to_symbolize and 'Ubuntu' in self.m.vars.builder_cfg['os']:
    168       # Convert path objects or placeholders into strings such that they can
    169       # be passed to symbolize_stack_trace.py
    170       args = [self.m.vars.slave_dir] + [str(x) for x in cmd]
    171       with self.m.step.context({'cwd': self.m.vars.skia_dir, 'env': env}):
    172         self._py('symbolized %s' % name,
    173                  self.m.vars.infrabots_dir.join('recipe_modules', 'core',
    174                  'resources', 'symbolize_stack_trace.py'),
    175                  args=args,
    176                  infra_step=False)
    177 
    178     else:
    179       with self.m.step.context({'env': env}):
    180         self._run(name, cmd)
    181