|
| 1 | +// Copyright (c) 2024 Linaro LTD |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +// Pre-build code for zephyr module. |
| 5 | + |
| 6 | +// This module makes the values from the generated .config available as conditional compilation. |
| 7 | +// Note that this only applies to the zephyr module, and the user's application will not be able to |
| 8 | +// see these definitions. To make that work, this will need to be moved into a support crate which |
| 9 | +// can be invoked by the user's build.rs. |
| 10 | + |
| 11 | +// This builds a program that is run on the compilation host before the code is compiled. It can |
| 12 | +// output configuration settings that affect the compilation. |
| 13 | + |
| 14 | +use anyhow::Result; |
| 15 | + |
| 16 | +use bindgen::Builder; |
| 17 | + |
| 18 | +use std::env; |
| 19 | +use std::path::PathBuf; |
| 20 | + |
| 21 | +fn main() -> Result<()> { |
| 22 | + // Pass in the target used to build the native code. |
| 23 | + let target_arg = format!("--target={}", env::var("TARGET")?); |
| 24 | + |
| 25 | + // println!("includes: {:?}", env::var("INCLUDE_DIRS")); |
| 26 | + // println!("defines: {:?}", env::var("INCLUDE_DEFINES")); |
| 27 | + |
| 28 | + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 29 | + let wrapper_path = PathBuf::from(env::var("WRAPPER_FILE").unwrap()); |
| 30 | + |
| 31 | + // Bindgen everything. |
| 32 | + let bindings = Builder::default() |
| 33 | + .header("wrapper.h") |
| 34 | + .use_core() |
| 35 | + .clang_arg(&target_arg); |
| 36 | + let bindings = define_args(bindings, "-I", "INCLUDE_DIRS"); |
| 37 | + let bindings = define_args(bindings, "-D", "INCLUDE_DEFINES"); |
| 38 | + let bindings = bindings |
| 39 | + .wrap_static_fns(true) |
| 40 | + .wrap_static_fns_path(wrapper_path) |
| 41 | + // <inttypes.h> seems to come from somewhere mysterious in Zephyr. For us, just pull in the |
| 42 | + // one from the minimal libc. |
| 43 | + .clang_arg("-DRUST_BINDGEN") |
| 44 | + .clang_arg("-I../../../lib/libc/minimal/include") |
| 45 | + .derive_copy(false) |
| 46 | + .allowlist_function("k_.*") |
| 47 | + .allowlist_function("gpio_.*") |
| 48 | + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) |
| 49 | + .generate() |
| 50 | + .expect("Unable to generate bindings"); |
| 51 | + |
| 52 | + bindings |
| 53 | + .write_to_file(out_path.join("bindings.rs")) |
| 54 | + .expect("Couldn't write bindings!"); |
| 55 | + |
| 56 | + Ok(()) |
| 57 | +} |
| 58 | + |
| 59 | +fn define_args(bindings: Builder, prefix: &str, var_name: &str) -> Builder { |
| 60 | + let text = env::var(var_name).unwrap(); |
| 61 | + let mut bindings = bindings; |
| 62 | + for entry in text.split(" ") { |
| 63 | + if entry.is_empty() { |
| 64 | + continue; |
| 65 | + } |
| 66 | + println!("Entry: {}{}", prefix, entry); |
| 67 | + let arg = format!("{}{}", prefix, entry); |
| 68 | + bindings = bindings.clang_arg(arg); |
| 69 | + } |
| 70 | + bindings |
| 71 | +} |
0 commit comments