1#!/usr/bin/env python3 2 3# Copyright 2022 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import argparse 8import os 9import subprocess 10import sys 11 12# Set up path to be able to import action_helpers. 13sys.path.append( 14 os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, 15 os.pardir, 'build')) 16import action_helpers 17 18from filter_clang_args import filter_clang_args 19 20 21def atomic_copy(in_path, out_path): 22 with open(in_path, 'rb') as input: 23 with action_helpers.atomic_output(out_path) as output: 24 content = input.read() 25 output.write(content) 26 27 28def copy_to_prefixed_filename(path, filename, prefix): 29 atomic_copy(os.path.join(path, filename), 30 os.path.join(path, prefix + "_" + filename)) 31 32 33def main(): 34 parser = argparse.ArgumentParser("run_bindgen.py") 35 parser.add_argument("--exe", help="Path to bindgen", required=True), 36 parser.add_argument("--header", 37 help="C header file to generate bindings for", 38 required=True) 39 parser.add_argument("--depfile", 40 help="depfile to output with header dependencies") 41 parser.add_argument("--output", help="output .rs bindings", required=True) 42 parser.add_argument("--ld-library-path", 43 help="LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on Mac) to " 44 "set") 45 parser.add_argument("--libclang-path", 46 help="Path to the libclang shared libray.") 47 parser.add_argument("-I", "--include", help="include path", action="append") 48 parser.add_argument("--bindgen-flags", 49 help="flags to pass to bindgen", 50 nargs="*") 51 parser.add_argument( 52 "clangargs", 53 metavar="CLANGARGS", 54 help="arguments to pass to libclang (see " 55 "https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.clang_args)", 56 nargs="*") 57 args = parser.parse_args() 58 59 # Args passed to the actual bindgen cli 60 genargs = [] 61 genargs.append('--no-layout-tests') 62 if args.bindgen_flags is not None: 63 for flag in args.bindgen_flags: 64 genargs.append("--" + flag) 65 66 # TODO(danakj): We need to point bindgen to 67 # //third_party/rust-toolchain/bin/rustfmt. 68 genargs.append('--no-rustfmt-bindings') 69 genargs += ['--rust-target', 'nightly'] 70 71 if args.depfile: 72 genargs.append('--depfile') 73 genargs.append(args.depfile) 74 genargs.append('--output') 75 genargs.append(args.output) 76 genargs.append(args.header) 77 genargs.append('--') 78 genargs.extend(filter_clang_args(args.clangargs)) 79 env = os.environ 80 if args.ld_library_path: 81 if sys.platform == 'darwin': 82 env["DYLD_LIBRARY_PATH"] = args.ld_library_path 83 else: 84 env["LD_LIBRARY_PATH"] = args.ld_library_path 85 if args.libclang_path: 86 env["LIBCLANG_PATH"] = args.libclang_path 87 returncode = subprocess.run([args.exe, *genargs], env=env).returncode 88 if returncode != 0: 89 # Make sure we don't emit anything if bindgen failed. 90 try: 91 os.remove(args.output) 92 except FileNotFoundError: 93 pass 94 try: 95 os.remove(args.depfile) 96 except FileNotFoundError: 97 pass 98 return returncode 99 100 101if __name__ == '__main__': 102 sys.exit(main()) 103