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