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