1#!/usr/bin/env python3 2# Copyright 2018 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Generates bindings that are used gpu_renderer. 7 8A sysroot and virglrenderer source checkout is required. The defaults to the 9root directory. 10""" 11 12from __future__ import print_function 13import argparse 14import multiprocessing.pool 15import os 16import subprocess 17import sys 18import tempfile 19 20# Bright green. 21PASS_COLOR = '\033[1;32m' 22# Bright red. 23FAIL_COLOR = '\033[1;31m' 24# Default color. 25END_COLOR = '\033[0m' 26 27verbose = False 28 29def generate_module(module_name, whitelist, header, clang_args, lib_name): 30 args = [ 31 'bindgen', 32 '--no-layout-tests', 33 '--whitelist-function', whitelist, 34 '--whitelist-var', whitelist, 35 '--whitelist-type', whitelist, 36 '--no-prepend-enum-name', 37 '--no-rustfmt-bindings', 38 '-o', module_name + '.rs', 39 ]; 40 41 if lib_name: 42 args.extend(['--raw-line', 43 '#[link(name = "{}")] extern {{}}'.format(lib_name)]) 44 45 args.extend([header, '--']) 46 args.extend(clang_args) 47 48 if verbose: 49 print(' '.join(args)) 50 51 if subprocess.Popen(args).wait() == 0: 52 return 'pass' 53 else: 54 return 'bindgen failed' 55 56 57def download_virgl(src, dst, branch): 58 virgl_src = tempfile.TemporaryDirectory(prefix='virglrenderer-src') 59 60 args = ['git', 'clone'] 61 62 if branch: 63 args.extend(['-b', branch]) 64 65 args.extend([src, dst]) 66 67 if verbose: 68 print(' '.join(args)) 69 70 if subprocess.Popen(args).wait() == 0: 71 return True 72 else: 73 74 return False 75 76 77def get_parser(): 78 """Gets the argument parser""" 79 parser = argparse.ArgumentParser(description=__doc__) 80 parser.add_argument('--sysroot', 81 default='/', 82 help='sysroot directory (default=%(default)s)') 83 parser.add_argument('--virglrenderer', 84 default='git://git.freedesktop.org/git/virglrenderer', 85 help='virglrenderer src dir/repo (default=%(default)s)') 86 parser.add_argument('--virgl_branch', 87 default='master', 88 help='virglrenderer branch name (default=%(default)s)') 89 parser.add_argument('--verbose', '-v', 90 action='store_true', 91 help='enable verbose output (default=%(default)s)') 92 return parser 93 94 95def main(argv): 96 global verbose 97 os.chdir(os.path.dirname(sys.argv[0])) 98 opts = get_parser().parse_args(argv) 99 if opts.verbose: 100 verbose = True 101 102 virgl_src_dir = opts.virglrenderer 103 virgl_src_dir_temp = None 104 if '://' in opts.virglrenderer: 105 virgl_src_dir_temp = tempfile.TemporaryDirectory(prefix='virglrenderer-src') 106 virgl_src_dir = virgl_src_dir_temp.name 107 if not download_virgl(opts.virglrenderer, virgl_src_dir, opts.virgl_branch): 108 print('failed to clone \'{}\' to \'{}\''.format(virgl_src_dir, 109 opts.virgl_branch)) 110 sys.exit(1) 111 112 clang_args = ['-I', os.path.join(opts.sysroot, 'usr/include')] 113 114 modules = ( 115 ( 116 'virglrenderer', 117 '(virgl|VIRGL)_.+', 118 os.path.join(opts.sysroot, 'usr/include/virgl/virglrenderer.h'), 119 clang_args, 120 'virglrenderer', 121 ), 122 ( 123 'epoxy_egl', 124 '(E?GL)|(epoxy)_.+', 125 os.path.join(opts.sysroot, 'usr/include/epoxy/egl.h'), 126 clang_args, 127 'epoxy', 128 ), 129 ( 130 'virgl_protocol', 131 '(virgl)|(VIRGL)_.+', 132 os.path.join(virgl_src_dir, 'src/virgl_protocol.h'), 133 clang_args, 134 None, 135 ), 136 ( 137 'p_defines', 138 '(pipe)|(PIPE).+', 139 os.path.join(virgl_src_dir, 'src/gallium/include/pipe/p_defines.h'), 140 clang_args, 141 None, 142 ), 143 ( 144 'p_format', 145 'pipe_format', 146 os.path.join(virgl_src_dir, 'src/gallium/include/pipe/p_format.h'), 147 clang_args, 148 None, 149 ), 150 ) 151 152 pool = multiprocessing.pool.Pool(len(modules)) 153 results = pool.starmap(generate_module, modules, 1) 154 155 return_fail = False 156 print('---') 157 print('generate module summary:') 158 for module, result in zip(modules, results): 159 result_color = FAIL_COLOR 160 if result == 'pass': 161 result_color = PASS_COLOR 162 else: 163 return_fail = True 164 165 print('%15s: %s%s%s' % 166 (module[0], result_color, result, END_COLOR)) 167 168 if return_fail: 169 sys.exit(1) 170 171 with open('mod.rs', 'w') as f: 172 print('/* generated by generate.py */', file=f) 173 print('#![allow(dead_code)]', file=f) 174 print('#![allow(non_camel_case_types)]', file=f) 175 print('#![allow(non_snake_case)]', file=f) 176 print('#![allow(non_upper_case_globals)]', file=f) 177 for module in modules: 178 print('pub mod', module[0] + ';', file=f) 179 180 181if __name__ == '__main__': 182 sys.exit(main(sys.argv[1:])) 183