summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbindgen/src/codegen/mod.rs32
-rw-r--r--libbindgen/src/lib.rs68
-rw-r--r--src/options.rs25
3 files changed, 97 insertions, 28 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs
index 7fa76d56..ff18ab83 100644
--- a/libbindgen/src/codegen/mod.rs
+++ b/libbindgen/src/codegen/mod.rs
@@ -267,15 +267,19 @@ impl CodeGenerator for Item {
module.codegen(ctx, result, whitelisted_items, self);
}
ItemKind::Function(ref fun) => {
- if !ctx.options().ignore_functions {
+ if ctx.options().codegen_config.functions {
fun.codegen(ctx, result, whitelisted_items, self);
}
}
ItemKind::Var(ref var) => {
- var.codegen(ctx, result, whitelisted_items, self);
+ if ctx.options().codegen_config.vars {
+ var.codegen(ctx, result, whitelisted_items, self);
+ }
}
ItemKind::Type(ref ty) => {
- ty.codegen(ctx, result, whitelisted_items, self);
+ if ctx.options().codegen_config.types {
+ ty.codegen(ctx, result, whitelisted_items, self);
+ }
}
}
}
@@ -1152,14 +1156,16 @@ impl CodeGenerator for CompInfo {
result.push(item);
}
- let mut method_names = Default::default();
- for method in self.methods() {
- method.codegen_method(ctx,
- &mut methods,
- &mut method_names,
- result,
- whitelisted_items,
- item);
+ if ctx.options().codegen_config.methods {
+ let mut method_names = Default::default();
+ for method in self.methods() {
+ method.codegen_method(ctx,
+ &mut methods,
+ &mut method_names,
+ result,
+ whitelisted_items,
+ item);
+ }
}
}
@@ -1222,10 +1228,6 @@ impl MethodCodegen for Method {
result: &mut CodegenResult,
whitelisted_items: &ItemSet,
_parent: &Item) {
- if ctx.options().ignore_methods {
- return;
- }
-
if self.is_virtual() {
return; // FIXME
}
diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs
index f25c6cdf..b2d3593c 100644
--- a/libbindgen/src/lib.rs
+++ b/libbindgen/src/lib.rs
@@ -98,6 +98,49 @@ use syntax::print::pp::eof;
use syntax::print::pprust;
use syntax::ptr::P;
+/// A type used to indicate which kind of items do we have to generate.
+///
+/// TODO(emilio): Use `bitflags!`
+#[derive(Debug, Clone)]
+pub struct CodegenConfig {
+ /// Whether to generate functions.
+ pub functions: bool,
+ /// Whether to generate types.
+ pub types: bool,
+ /// Whether to generate constants.
+ pub vars: bool,
+ /// Whether to generate methods.
+ pub methods: bool,
+}
+
+impl CodegenConfig {
+ /// Generate all kinds of items.
+ pub fn all() -> Self {
+ CodegenConfig {
+ functions: true,
+ types: true,
+ vars: true,
+ methods: true,
+ }
+ }
+
+ /// Generate nothing.
+ pub fn nothing() -> Self {
+ CodegenConfig {
+ functions: false,
+ types: false,
+ vars: false,
+ methods: false,
+ }
+ }
+}
+
+impl Default for CodegenConfig {
+ fn default() -> Self {
+ CodegenConfig::all()
+ }
+}
+
/// Configure and generate Rust bindings for a C/C++ header.
///
/// This is the main entry point to the library.
@@ -264,13 +307,13 @@ impl Builder {
/// Ignore functions.
pub fn ignore_functions(mut self) -> Builder {
- self.options.ignore_functions = true;
+ self.options.codegen_config.functions = false;
self
}
/// Ignore methods.
pub fn ignore_methods(mut self) -> Builder {
- self.options.ignore_methods = true;
+ self.options.codegen_config.methods = false;
self
}
@@ -299,6 +342,12 @@ impl Builder {
self
}
+ /// Choose what to generate using a CodegenConfig.
+ pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
+ self.options.codegen_config = config;
+ self
+ }
+
/// Generate the Rust bindings using the options built up thus far.
pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
Bindings::generate(self.options, None)
@@ -348,14 +397,6 @@ pub struct BindgenOptions {
/// True if we should dump our internal IR for debugging purposes.
pub emit_ir: bool,
- /// True if we should ignore functions and only generate bindings for
- /// structures, types, and methods.
- pub ignore_functions: bool,
-
- /// True if we should avoid generating bindings for methods, and instead
- /// just generate code for structures and types.
- pub ignore_methods: bool,
-
/// True if we should emulate C++ namespaces with Rust modules in the
/// generated bindings.
pub enable_cxx_namespaces: bool,
@@ -403,6 +444,10 @@ pub struct BindgenOptions {
/// A user-provided type chooser to allow customizing different kinds of
/// situations.
pub type_chooser: Option<Box<chooser::TypeChooser>>,
+
+ /// Which kind of items should we generate? By default, we'll generate all
+ /// of them.
+ pub codegen_config: CodegenConfig,
}
impl Default for BindgenOptions {
@@ -418,8 +463,6 @@ impl Default for BindgenOptions {
links: vec![],
emit_ast: false,
emit_ir: false,
- ignore_functions: false,
- ignore_methods: false,
derive_debug: true,
enable_cxx_namespaces: false,
disable_name_namespacing: false,
@@ -434,6 +477,7 @@ impl Default for BindgenOptions {
input_header: None,
dummy_uses: None,
type_chooser: None,
+ codegen_config: CodegenConfig::all(),
}
}
}
diff --git a/src/options.rs b/src/options.rs
index 9632619f..a783696e 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -1,5 +1,5 @@
use clap::{App, Arg};
-use libbindgen::{Builder, builder};
+use libbindgen::{Builder, builder, CodegenConfig};
use std::fs::File;
use std::io::{self, Error, ErrorKind};
@@ -71,6 +71,12 @@ pub fn builder_from_flags<I>(args: I)
.long("ignore-functions")
.help("Do not generate bindings for functions or methods. This \
is useful when you only care about struct layouts."),
+ Arg::with_name("generate")
+ .long("generate")
+ .help("Generate a given kind of items, split by commas. \
+ Valid values are \"functions\",\"types\", \"vars\" and \
+ \"methods\".")
+ .takes_value(true),
Arg::with_name("ignore-methods")
.long("ignore-methods")
.help("Do not generate bindings for methods."),
@@ -185,6 +191,23 @@ pub fn builder_from_flags<I>(args: I)
}
}
+ if let Some(what_to_generate) = matches.value_of("generate") {
+ let mut config = CodegenConfig::nothing();
+ for what in what_to_generate.split(",") {
+ match what {
+ "functions" => config.functions = true,
+ "types" => config.types = true,
+ "vars" => config.vars = true,
+ "methods" => config.methods = true,
+ _ => {
+ return Err(
+ Error::new(ErrorKind::Other, "Unknown generate item"));
+ }
+ }
+ }
+ builder = builder.with_codegen_config(config);
+ }
+
if matches.is_present("emit-clang-ast") {
builder = builder.emit_clang_ast();
}