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 derive_default): 31 args = [ 32 'bindgen', 33 '--no-layout-tests', 34 '--whitelist-function', whitelist, 35 '--whitelist-var', whitelist, 36 '--whitelist-type', whitelist, 37 '--no-prepend-enum-name', 38 '--no-rustfmt-bindings', 39 '-o', module_name + '_bindings.rs', 40 ]; 41 42 if lib_name: 43 args.extend(['--raw-line', 44 '#[cfg(feature = \"{}\")]'.format(module_name)]) 45 args.extend(['--raw-line', 46 '#[link(name = "{}")] extern {{}}'.format(lib_name)]) 47 48 if derive_default: 49 args.append('--with-derive-default') 50 51 args.extend([header, '--']) 52 args.extend(clang_args) 53 54 if verbose: 55 print(' '.join(args)) 56 57 if subprocess.Popen(args).wait() == 0: 58 return 'pass' 59 else: 60 return 'bindgen failed' 61 62 63def download_virgl(src, dst, branch): 64 virgl_src = tempfile.TemporaryDirectory(prefix='virglrenderer-src') 65 66 args = ['git', 'clone'] 67 68 if branch: 69 args.extend(['-b', branch]) 70 71 args.extend([src, dst]) 72 73 if verbose: 74 print(' '.join(args)) 75 76 if subprocess.Popen(args).wait() == 0: 77 return True 78 else: 79 80 return False 81 82 83def get_parser(): 84 """Gets the argument parser""" 85 parser = argparse.ArgumentParser(description=__doc__) 86 parser.add_argument('--sysroot', 87 default='/', 88 help='sysroot directory (default=%(default)s)') 89 parser.add_argument('--virglrenderer', 90 default='git://git.freedesktop.org/git/virglrenderer', 91 help='virglrenderer src dir/repo (default=%(default)s)') 92 parser.add_argument('--virgl_branch', 93 default='master', 94 help='virglrenderer branch name (default=%(default)s)') 95 parser.add_argument('--verbose', '-v', 96 action='store_true', 97 help='enable verbose output (default=%(default)s)') 98 return parser 99 100 101def main(argv): 102 global verbose 103 os.chdir(os.path.dirname(sys.argv[0])) 104 opts = get_parser().parse_args(argv) 105 if opts.verbose: 106 verbose = True 107 108 virgl_src_dir = opts.virglrenderer 109 virgl_src_dir_temp = None 110 if '://' in opts.virglrenderer: 111 virgl_src_dir_temp = tempfile.TemporaryDirectory(prefix='virglrenderer-src') 112 virgl_src_dir = virgl_src_dir_temp.name 113 if not download_virgl(opts.virglrenderer, virgl_src_dir, opts.virgl_branch): 114 print('failed to clone \'{}\' to \'{}\''.format(virgl_src_dir, 115 opts.virgl_branch)) 116 sys.exit(1) 117 118 clang_args = ['-I', os.path.join(opts.sysroot, 'usr/include')] 119 120 modules = ( 121 ( 122 'virgl_renderer', 123 '(virgl|VIRGL)_.+', 124 os.path.join(opts.sysroot, 'usr/include/virgl/virglrenderer.h'), 125 clang_args, 126 'virglrenderer', 127 True, 128 ), 129 ) 130 131 pool = multiprocessing.pool.Pool(len(modules)) 132 results = pool.starmap(generate_module, modules, 1) 133 134 return_fail = False 135 print('---') 136 print('generate module summary:') 137 for module, result in zip(modules, results): 138 result_color = FAIL_COLOR 139 if result == 'pass': 140 result_color = PASS_COLOR 141 else: 142 return_fail = True 143 144 print('%15s: %s%s%s' % 145 (module[0], result_color, result, END_COLOR)) 146 147 if return_fail: 148 sys.exit(1) 149 150 with open('mod.rs', 'w') as f: 151 print('/* generated by generate.py */', file=f) 152 print('#![allow(dead_code)]', file=f) 153 print('#![allow(non_camel_case_types)]', file=f) 154 print('#![allow(non_snake_case)]', file=f) 155 print('#![allow(non_upper_case_globals)]', file=f) 156 for module in modules: 157 print('pub mod', module[0] + '_bindings;', file=f) 158 159 160if __name__ == '__main__': 161 sys.exit(main(sys.argv[1:])) 162