blob: 14c2d4a06beb6b634dbf0fbedd6e92c46d27b67e [file] [log] [blame]
# 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()