diff --git a/Cargo.lock b/Cargo.lock index 0ea9474809..251244184c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,8 @@ dependencies = [ "bitflags 2.2.1", "cexpr", "clang-sys", + "clap", + "clap_complete", "itertools", "log", "prettyplease", @@ -51,8 +53,6 @@ name = "bindgen-cli" version = "0.70.1" dependencies = [ "bindgen", - "clap", - "clap_complete", "env_logger 0.10.0", "log", "proc-macro2", @@ -72,8 +72,6 @@ name = "bindgen-tests" version = "0.1.0" dependencies = [ "bindgen", - "clap", - "clap_complete", "owo-colors", "prettyplease", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 7bfd8baca1..e0535a1c66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,6 @@ default-members = [ # Dependencies shared between crates [workspace.dependencies] -clap = { version = "4", features = ["derive"] } -clap_complete = "4" shlex = "1" syn = "2.0" proc-macro2 = { version = "1", default-features = false } diff --git a/bindgen-cli/Cargo.toml b/bindgen-cli/Cargo.toml index dc5a8ae706..2e5bf1b47f 100644 --- a/bindgen-cli/Cargo.toml +++ b/bindgen-cli/Cargo.toml @@ -24,8 +24,6 @@ bindgen = { path = "../bindgen", version = "=0.70.1", default-features = false, env_logger = { version = "0.10.0", optional = true } log = { version = "0.4", optional = true } -clap.workspace = true -clap_complete.workspace = true proc-macro2.workspace = true shlex.workspace = true diff --git a/bindgen-cli/main.rs b/bindgen-cli/main.rs index caa47c6268..c15aa00f91 100644 --- a/bindgen-cli/main.rs +++ b/bindgen-cli/main.rs @@ -1,7 +1,6 @@ use std::env; -mod options; -use crate::options::builder_from_flags; +use bindgen::builder_from_flags; #[cfg(feature = "logging")] fn clang_version_check() { diff --git a/bindgen-tests/Cargo.toml b/bindgen-tests/Cargo.toml index 613994a04e..4a92f81f55 100644 --- a/bindgen-tests/Cargo.toml +++ b/bindgen-tests/Cargo.toml @@ -11,8 +11,6 @@ prettyplease = { version = "0.2.7", features = ["verbatim"] } similar = { version = "2.2.1", features = ["inline"] } tempfile = "3" -clap.workspace = true -clap_complete.workspace = true proc-macro2.workspace = true shlex.workspace = true syn.workspace = true diff --git a/bindgen-tests/tests/tests.rs b/bindgen-tests/tests/tests.rs index 14988e463f..c008766d72 100644 --- a/bindgen-tests/tests/tests.rs +++ b/bindgen-tests/tests/tests.rs @@ -7,10 +7,7 @@ use std::fs; use std::io::{BufRead, BufReader, Error, ErrorKind, Read, Write}; use std::path::{Path, PathBuf}; -use crate::options::builder_from_flags; - -#[path = "../../bindgen-cli/options.rs"] -mod options; +use bindgen::builder_from_flags; mod parse_callbacks; @@ -709,8 +706,7 @@ fn build_flags_output_helper(builder: &bindgen::Builder) { println!("{}", flags_str); let (builder, _output, _verbose) = - crate::options::builder_from_flags(command_line_flags.into_iter()) - .unwrap(); + builder_from_flags(command_line_flags.into_iter()).unwrap(); builder.generate().expect("failed to generate bindings"); } diff --git a/bindgen/Cargo.toml b/bindgen/Cargo.toml index 9c351f28c6..d8b872b77c 100644 --- a/bindgen/Cargo.toml +++ b/bindgen/Cargo.toml @@ -29,6 +29,8 @@ annotate-snippets = { version = "0.11.4", optional = true } bitflags = "2.2.1" cexpr = "0.6" clang-sys = { version = "1", features = ["clang_11_0"] } +clap = { version = "4", features = ["derive"], optional = true } +clap_complete = { version = "4", optional = true} itertools = { version = ">=0.10,<0.14", default-features = false } log = { version = "0.4", optional = true } prettyplease = { version = "0.2.7", optional = true, features = ["verbatim"] } @@ -52,7 +54,7 @@ experimental = ["dep:annotate-snippets"] ## The following features are for internal use and they shouldn't be used if ## you're not hacking on bindgen # Features used by `bindgen-cli` -__cli = [] +__cli = ["dep:clap", "dep:clap_complete"] # Features used for CI testing __testing_only_extra_assertions = [] __testing_only_libclang_9 = [] diff --git a/bindgen/lib.rs b/bindgen/lib.rs index 1a9932b534..134e3d6d91 100644 --- a/bindgen/lib.rs +++ b/bindgen/lib.rs @@ -50,12 +50,11 @@ mod regex_set; pub use codegen::{ AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle, }; -#[cfg(feature = "__cli")] -pub use features::RUST_TARGET_STRINGS; pub use features::{RustTarget, LATEST_STABLE_RUST}; pub use ir::annotations::FieldVisibilityKind; pub use ir::function::Abi; -pub use regex_set::RegexSet; +#[cfg(feature = "__cli")] +pub use options::cli::builder_from_flags; use codegen::CodegenError; use features::RustFeatures; diff --git a/bindgen/options/as_args.rs b/bindgen/options/as_args.rs index 6918ad9fec..83103fdaf4 100644 --- a/bindgen/options/as_args.rs +++ b/bindgen/options/as_args.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use crate::RegexSet; +use crate::regex_set::RegexSet; /// Trait used to turn [`crate::BindgenOptions`] fields into CLI args. pub(super) trait AsArgs { diff --git a/bindgen-cli/options.rs b/bindgen/options/cli.rs similarity index 96% rename from bindgen-cli/options.rs rename to bindgen/options/cli.rs index ad96664bd2..1f51b3bece 100644 --- a/bindgen-cli/options.rs +++ b/bindgen/options/cli.rs @@ -1,11 +1,18 @@ -use bindgen::callbacks::TypeKind; -use bindgen::{ - builder, Abi, AliasVariation, Builder, CodegenConfig, EnumVariation, +use crate::{ + builder, + callbacks::{ + AttributeInfo, DeriveInfo, ItemInfo, ParseCallbacks, TypeKind, + }, + features::RUST_TARGET_STRINGS, + regex_set::RegexSet, + Abi, AliasVariation, Builder, CodegenConfig, EnumVariation, FieldVisibilityKind, Formatter, MacroTypeVariation, NonCopyUnionStyle, - RegexSet, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, + RustTarget, DEFAULT_ANON_FIELDS_PREFIX, +}; +use clap::{ + error::{Error, ErrorKind}, + CommandFactory, Parser, }; -use clap::error::{Error, ErrorKind}; -use clap::{CommandFactory, Parser}; use proc_macro2::TokenStream; use std::fs::File; use std::io; @@ -491,6 +498,7 @@ struct BindgenCommand { #[arg(long, value_name = "VISIBILITY")] default_visibility: Option, /// Whether to emit diagnostics or not. + #[cfg(feature = "experimental")] #[arg(long, requires = "experimental")] emit_diagnostics: bool, /// Generates completions for the specified SHELL, sends them to `stdout` and exits. @@ -633,6 +641,7 @@ where wrap_static_fns_path, wrap_static_fns_suffix, default_visibility, + #[cfg(feature = "experimental")] emit_diagnostics, generate_shell_completions, experimental: _, @@ -657,7 +666,7 @@ where option_env!("CARGO_PKG_VERSION").unwrap_or("unknown") ); if verbose { - println!("Clang: {}", bindgen::clang_version().full); + println!("Clang: {}", crate::clang_version().full); } std::process::exit(0); } @@ -1046,10 +1055,10 @@ where prefix: String, } - impl bindgen::callbacks::ParseCallbacks for PrefixLinkNameCallback { + impl ParseCallbacks for PrefixLinkNameCallback { fn generated_link_name_override( &self, - item_info: bindgen::callbacks::ItemInfo<'_>, + item_info: ItemInfo<'_>, ) -> Option { let mut prefix = self.prefix.clone(); prefix.push_str(item_info.name); @@ -1114,10 +1123,10 @@ where struct CustomDeriveCallback { derives: Vec, kind: Option, - regex_set: bindgen::RegexSet, + regex_set: RegexSet, } - impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback { + impl ParseCallbacks for CustomDeriveCallback { fn cli_args(&self) -> Vec { let mut args = vec![]; @@ -1140,10 +1149,7 @@ where args } - fn add_derives( - &self, - info: &bindgen::callbacks::DeriveInfo<'_>, - ) -> Vec { + fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec { if self.kind.map(|kind| kind == info.kind).unwrap_or(true) && self.regex_set.matches(info.name) { @@ -1153,7 +1159,7 @@ where } } - for (custom_derives, kind, name) in [ + for (custom_derives, kind, _name) in [ (with_derive_custom, None, "--with-derive-custom"), ( with_derive_custom_struct, @@ -1171,11 +1177,17 @@ where "--with-derive-custom-union", ), ] { - let name = emit_diagnostics.then_some(name); + #[cfg(feature = "experimental")] + let name = emit_diagnostics.then_some(_name); + for (derives, regex) in custom_derives { - let mut regex_set = RegexSet::new(); + let mut regex_set = RegexSet::default(); regex_set.insert(regex); + + #[cfg(feature = "experimental")] regex_set.build_with_diagnostics(false, name); + #[cfg(not(feature = "experimental"))] + regex_set.build(false); builder = builder.parse_callbacks(Box::new(CustomDeriveCallback { derives, @@ -1189,10 +1201,10 @@ where struct CustomAttributeCallback { attributes: Vec, kind: Option, - regex_set: bindgen::RegexSet, + regex_set: RegexSet, } - impl bindgen::callbacks::ParseCallbacks for CustomAttributeCallback { + impl ParseCallbacks for CustomAttributeCallback { fn cli_args(&self) -> Vec { let mut args = vec![]; @@ -1215,10 +1227,7 @@ where args } - fn add_attributes( - &self, - info: &bindgen::callbacks::AttributeInfo<'_>, - ) -> Vec { + fn add_attributes(&self, info: &AttributeInfo<'_>) -> Vec { if self.kind.map(|kind| kind == info.kind).unwrap_or(true) && self.regex_set.matches(info.name) { @@ -1228,7 +1237,7 @@ where } } - for (custom_attributes, kind, name) in [ + for (custom_attributes, kind, _name) in [ (with_attribute_custom, None, "--with-attribute-custom"), ( with_attribute_custom_struct, @@ -1246,11 +1255,17 @@ where "--with-attribute-custom-union", ), ] { - let name = emit_diagnostics.then_some(name); + #[cfg(feature = "experimental")] + let name = emit_diagnostics.then_some(_name); + for (attributes, regex) in custom_attributes { - let mut regex_set = RegexSet::new(); + let mut regex_set = RegexSet::default(); regex_set.insert(regex); + + #[cfg(feature = "experimental")] regex_set.build_with_diagnostics(false, name); + #[cfg(not(feature = "experimental"))] + regex_set.build(false); builder = builder.parse_callbacks(Box::new(CustomAttributeCallback { @@ -1277,6 +1292,7 @@ where builder = builder.default_visibility(visibility); } + #[cfg(feature = "experimental")] if emit_diagnostics { builder = builder.emit_diagnostics(); } diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs index e9f4fb811c..57988e79e6 100644 --- a/bindgen/options/mod.rs +++ b/bindgen/options/mod.rs @@ -4,6 +4,8 @@ #[macro_use] mod helpers; mod as_args; +#[cfg(feature = "__cli")] +pub(crate) mod cli; use crate::callbacks::ParseCallbacks; use crate::codegen::{ diff --git a/bindgen/regex_set.rs b/bindgen/regex_set.rs index 7f40af3c79..3375632761 100644 --- a/bindgen/regex_set.rs +++ b/bindgen/regex_set.rs @@ -6,7 +6,7 @@ use std::cell::Cell; /// A dynamic set of regular expressions. #[derive(Clone, Debug, Default)] -pub struct RegexSet { +pub(crate) struct RegexSet { items: Vec>, /// Whether any of the items in the set was ever matched. The length of this /// vector is exactly the length of `items`. @@ -17,18 +17,13 @@ pub struct RegexSet { } impl RegexSet { - /// Create a new RegexSet - pub fn new() -> RegexSet { - RegexSet::default() - } - /// Is this set empty? - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { self.items.is_empty() } /// Insert a new regex into this set. - pub fn insert(&mut self, string: S) + pub(crate) fn insert(&mut self, string: S) where S: AsRef, { @@ -38,13 +33,13 @@ impl RegexSet { } /// Returns slice of String from its field 'items' - pub fn get_items(&self) -> &[Box] { + pub(crate) fn get_items(&self) -> &[Box] { &self.items } /// Returns an iterator over regexes in the set which didn't match any /// strings yet. - pub fn unmatched_items(&self) -> impl Iterator { + pub(crate) fn unmatched_items(&self) -> impl Iterator { self.items.iter().enumerate().filter_map(move |(i, item)| { if !self.record_matches || self.matched[i].get() { return None; @@ -59,7 +54,8 @@ impl RegexSet { /// Must be called before calling `matches()`, or it will always return /// false. #[inline] - pub fn build(&mut self, record_matches: bool) { + #[allow(unused)] + pub(crate) fn build(&mut self, record_matches: bool) { self.build_inner(record_matches, None) } @@ -70,7 +66,7 @@ impl RegexSet { /// Must be called before calling `matches()`, or it will always return /// false. #[inline] - pub fn build_with_diagnostics( + pub(crate) fn build_with_diagnostics( &mut self, record_matches: bool, name: Option<&'static str>, @@ -114,7 +110,7 @@ impl RegexSet { } /// Does the given `string` match any of the regexes in this set? - pub fn matches(&self, string: S) -> bool + pub(crate) fn matches(&self, string: S) -> bool where S: AsRef, {