From 88a2125ff157a11a33247f21189da1d361e3bd6d Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Tue, 25 Feb 2025 10:36:11 +0000 Subject: [PATCH] Add option for all module raw lines Provide an option to add a line to every mod generated by bindgen. Part of https://github.com/google/autocxx/issues/124, though this is only in fact necessary if we make the changes given in https://github.com/google/autocxx/pull/1456. --- .../tests/expectations/tests/namespace.rs | 6 ++++++ bindgen-tests/tests/headers/namespace.hpp | 2 +- bindgen/codegen/mod.rs | 9 +++++++++ bindgen/options/cli.rs | 5 +++++ bindgen/options/mod.rs | 18 ++++++++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/bindgen-tests/tests/expectations/tests/namespace.rs b/bindgen-tests/tests/expectations/tests/namespace.rs index 4e58fa7ab1..a993d31dc9 100644 --- a/bindgen-tests/tests/expectations/tests/namespace.rs +++ b/bindgen-tests/tests/expectations/tests/namespace.rs @@ -3,6 +3,7 @@ pub mod root { #[allow(unused_imports)] use self::super::root; + struct PerModStruct; unsafe extern "C" { #[link_name = "\u{1}_Z9top_levelv"] pub fn top_level(); @@ -11,6 +12,7 @@ pub mod root { #[allow(unused_imports)] use self::super::super::root; pub type whatever_other_thing_t = whatever_int_t; + struct PerModStruct; pub type whatever_int_t = ::std::os::raw::c_int; unsafe extern "C" { #[link_name = "\u{1}_ZN8whatever11in_whateverEv"] @@ -20,6 +22,7 @@ pub mod root { pub mod _bindgen_mod_id_17 { #[allow(unused_imports)] use self::super::super::root; + struct PerModStruct; #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct A { @@ -53,6 +56,7 @@ pub mod root { pub mod w { #[allow(unused_imports)] use self::super::super::root; + struct PerModStruct; pub type whatever_int_t = ::std::os::raw::c_uint; #[repr(C)] #[derive(Debug)] @@ -85,6 +89,7 @@ pub mod root { pub mod foobar { #[allow(unused_imports)] use self::super::super::root; + struct PerModStruct; unsafe extern "C" { #[link_name = "\u{1}_ZN6foobar3fooEv"] pub fn foo(); @@ -93,6 +98,7 @@ pub mod root { pub mod faraway { #[allow(unused_imports)] use self::super::super::root; + struct PerModStruct; unsafe extern "C" { #[link_name = "\u{1}_ZN7faraway3barEv"] pub fn bar(); diff --git a/bindgen-tests/tests/headers/namespace.hpp b/bindgen-tests/tests/headers/namespace.hpp index 7e4197da5f..2676328104 100644 --- a/bindgen-tests/tests/headers/namespace.hpp +++ b/bindgen-tests/tests/headers/namespace.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --enable-cxx-namespaces --module-raw-line root::whatever 'pub type whatever_other_thing_t = whatever_int_t;' +// bindgen-flags: --enable-cxx-namespaces --module-raw-line root::whatever 'pub type whatever_other_thing_t = whatever_int_t;' --every-module-raw-line 'struct PerModStruct;' void top_level(); diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index f5518e432d..02eb0b4681 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -609,6 +609,7 @@ impl CodeGenerator for Module { .namespace_aware_canonical_path(ctx) .join("::") .into_boxed_str(); + if let Some(raw_lines) = ctx.options().module_lines.get(&path) { for raw_line in raw_lines { found_any = true; @@ -617,6 +618,14 @@ impl CodeGenerator for Module { ); } } + // For lines we add to all modules, don't modify `found_any` + // since we don't want to generate this module unless there's + // other stuff present. + result.extend(ctx.options().every_module_raw_lines.iter().map( + |raw_line| { + proc_macro2::TokenStream::from_str(raw_line).unwrap() + }, + )); codegen_self(result, &mut found_any); }); diff --git a/bindgen/options/cli.rs b/bindgen/options/cli.rs index f9a8572976..43af10830f 100644 --- a/bindgen/options/cli.rs +++ b/bindgen/options/cli.rs @@ -336,6 +336,9 @@ struct BindgenCommand { /// Add a raw line of Rust code at the beginning of output. #[arg(long)] raw_line: Vec, + /// Add a raw line of Rust code at the beginning of each module. + #[arg(long)] + every_module_raw_line: Vec, /// Add a RAW_LINE of Rust code to a given module with name MODULE_NAME. #[arg(long, number_of_values = 2, value_names = ["MODULE_NAME", "RAW_LINE"])] module_raw_line: Vec, @@ -601,6 +604,7 @@ where opaque_type, output, raw_line, + every_module_raw_line, module_raw_line, rust_target, rust_edition, @@ -907,6 +911,7 @@ where block_extern_crate, opaque_type, raw_line, + every_module_raw_line, use_core => |b, _| b.use_core(), distrust_clang_mangling => |b, _| b.trust_clang_mangling(false), conservative_inline_namespaces => |b, _| b.conservative_inline_namespaces(), diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs index ab6b232ec3..f33e702a3d 100644 --- a/bindgen/options/mod.rs +++ b/bindgen/options/mod.rs @@ -1161,6 +1161,24 @@ options! { } }, }, + /// The set of raw lines to be prepended to every module of the generated Rust code. + every_module_raw_lines: Vec> { + methods: { + /// Add a line of Rust code at the beginning of each module (i.e. + /// C++ namespace) in the generated code. The string is + /// passed through without any modification. + pub fn every_module_raw_line>(mut self, arg: T) -> Self { + self.options.every_module_raw_lines.push(arg.into().into_boxed_str()); + self + } + }, + as_args: |every_module_raw_lines, args| { + for line in every_module_raw_lines { + args.push("--every-module-raw-line".to_owned()); + args.push(line.clone().into()); + } + }, + }, /// The set of raw lines to prepend to different modules. module_lines: HashMap, Vec>> { methods: {