| # Copyright 2023 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # This script intentionally does not have a shebang; it uses tools that are not |
| # available in the Fuchsia repo and must be installed to the local host, so we |
| # cannot use the hermetic Fuchsia Python. Since this script is rarely used, it's |
| # also not worth the effort to import the tools and all the maintenance costs |
| # that would come along with it (b/295039695). |
| # |
| # In order to avoid confusion, we remove the shebang to force the user to call |
| # the script explicitly through a host Python installation; see README.md for |
| # usage. |
| |
| import logging |
| import os |
| import pathlib |
| import subprocess |
| |
| MY_NAME = pathlib.Path(__file__).name |
| MY_DIR = pathlib.Path(__file__).parent |
| BINDINGS_PATH = MY_DIR / "ffi_c" / "bindings.h" |
| |
| |
| def generate_ffi(): |
| # Generate a Cargo.toml file in the out/ directory. |
| logging.info("Building Cargo.toml") |
| subprocess.run(["fx", "build", "build/rust:cargo_toml_gen"], check=True) |
| |
| # Copy the generated file into this directory as required by cbindgen. |
| subprocess.run( |
| [ |
| "fx", |
| "gen-cargo", |
| "//src/firmware/lib/fastboot/rust:_fastboot_c_rustc_static", |
| ], |
| check=True, |
| ) |
| |
| # Generate and format the bindings. |
| logging.info("Generating C bindings at %s", BINDINGS_PATH) |
| subprocess.run(["cbindgen", MY_DIR, "-o", BINDINGS_PATH], check=True) |
| |
| # cbindgen doesn't currently add header guards and fx format-code won't add |
| # them if they don't exist, so put something there and let fx format-code |
| # fix it up. We also need a license header and some lint checks. |
| BINDINGS_PATH.write_text( |
| f"""\ |
| // Copyright 2023 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This file is auto-generated by {MY_NAME}. See README for details. |
| |
| #ifndef FOO_H_ |
| #define FOO_H_ |
| |
| // LINT.IfChange |
| |
| {BINDINGS_PATH.read_text()} |
| |
| // LINT.ThenChange(../src/lib.rs) |
| |
| #endif // FOO_H_ |
| """ |
| ) |
| subprocess.run( |
| ["fx", "format-code", f"--files={BINDINGS_PATH}"], check=True |
| ) |
| |
| # Remove the generated Cargo files. |
| logging.info("Removing Cargo files") |
| os.remove(MY_DIR / "Cargo.toml") |
| os.remove(MY_DIR / "Cargo.lock") |
| |
| |
| def main(): |
| logging.basicConfig(level=logging.INFO) |
| |
| generate_ffi() |
| |
| |
| if __name__ == "__main__": |
| main() |