Skip to content

Commit

Permalink
Merge pull request #362 from emilio/outside-items
Browse files Browse the repository at this point in the history
Add an option to generate consts / globals / fn from parsed dependencies.
  • Loading branch information
emilio authored Jun 26, 2019
2 parents 540224c + 5f8e027 commit a3c1334
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 70 deletions.
6 changes: 6 additions & 0 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,12 @@ exclude = ["libc"]
# default: false
clean = false

# Which crates other than the top-level binding crate we should generate
# bindings for.
#
# default: []
extra_bindings = ["my_awesome_dep"]

[parse.expand]
# A list of crate names that should be run through `cargo expand` before
# parsing to expand any macros. Note that if a crate is named here, it
Expand Down
16 changes: 2 additions & 14 deletions src/bindgen/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,25 +322,13 @@ impl Builder {
result.extend_with(&parser::parse_lib(
cargo,
&self.config.macro_expansion,
self.config.parse.parse_deps,
&self.config.parse.include,
&self.config.parse.exclude,
&self.config.parse.expand.crates,
self.config.parse.expand.all_features,
self.config.parse.expand.default_features,
&self.config.parse.expand.features,
&self.config.parse,
)?);
} else if let Some(cargo) = self.lib_cargo.clone() {
result.extend_with(&parser::parse_lib(
cargo,
&self.config.macro_expansion,
self.config.parse.parse_deps,
&self.config.parse.include,
&self.config.parse.exclude,
&self.config.parse.expand.crates,
self.config.parse.expand.all_features,
self.config.parse.expand.default_features,
&self.config.parse.expand.features,
&self.config.parse,
)?);
}

Expand Down
24 changes: 15 additions & 9 deletions src/bindgen/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ fn retrocomp_parse_expand_config_deserialize<'de, D: Deserializer<'de>>(
}

/// Settings to apply when parsing.
#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Default, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
Expand All @@ -562,17 +562,23 @@ pub struct ParseConfig {
/// Whether to use a new temporary target directory when running `rustc --pretty=expanded`.
/// This may be required for some build processes.
pub clean: bool,
/// List of crate names which generate consts, statics, and fns. By default
/// no dependent crates generate them.
pub extra_bindings: Vec<String>,
}

impl Default for ParseConfig {
fn default() -> ParseConfig {
ParseConfig {
parse_deps: false,
include: None,
exclude: Vec::new(),
expand: ParseExpandConfig::default(),
clean: false,
impl ParseConfig {
pub(crate) fn should_generate_top_level_item(
&self,
crate_name: &str,
binding_crate_name: &str,
) -> bool {
if crate_name == binding_crate_name {
// Always generate items for the binding crate.
return true;
}

self.extra_bindings.iter().any(|dep| dep == crate_name)
}
}

Expand Down
100 changes: 53 additions & 47 deletions src/bindgen/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use syn;

use bindgen::bitflags;
use bindgen::cargo::{Cargo, PackageRef};
use bindgen::config::MacroExpansionConfig;
use bindgen::config::{MacroExpansionConfig, ParseConfig};
use bindgen::error::Error;
use bindgen::ir::{
AnnotationSet, Cfg, Constant, Documentation, Enum, Function, GenericParams, ItemMap,
Expand All @@ -36,18 +36,16 @@ pub fn parse_src(
macro_expansion_config: &MacroExpansionConfig,
) -> ParseResult {
let mod_name = src_file.file_stem().unwrap().to_str().unwrap();
let parse_config = ParseConfig {
parse_deps: true,
..ParseConfig::default()
};

let mut context = Parser {
binding_crate_name: mod_name.to_owned(),
macro_expansion_config,
parse_config: &parse_config,
lib: None,
parse_deps: true,
include: None,
exclude: Vec::new(),
expand: Vec::new(),
expand_all_features: true,
expand_default_features: true,
expand_features: None,
parsed_crates: HashSet::new(),
cache_src: HashMap::new(),
cache_expanded_crate: HashMap::new(),
Expand All @@ -72,25 +70,13 @@ pub fn parse_src(
pub(crate) fn parse_lib(
lib: Cargo,
macro_expansion_config: &MacroExpansionConfig,
parse_deps: bool,
include: &Option<Vec<String>>,
exclude: &[String],
expand: &[String],
expand_all_features: bool,
expand_default_features: bool,
expand_features: &Option<Vec<String>>,
parse_config: &ParseConfig,
) -> ParseResult {
let mut context = Parser {
binding_crate_name: lib.binding_crate_name().to_owned(),
macro_expansion_config,
parse_config,
lib: Some(lib),
parse_deps: parse_deps,
include: include.clone(),
exclude: exclude.to_owned(),
expand: expand.to_owned(),
expand_all_features,
expand_default_features,
expand_features: expand_features.clone(),
parsed_crates: HashSet::new(),
cache_src: HashMap::new(),
cache_expanded_crate: HashMap::new(),
Expand All @@ -106,16 +92,9 @@ pub(crate) fn parse_lib(
#[derive(Debug, Clone)]
struct Parser<'a> {
binding_crate_name: String,
macro_expansion_config: &'a MacroExpansionConfig,
lib: Option<Cargo>,
parse_deps: bool,

include: Option<Vec<String>>,
exclude: Vec<String>,
expand: Vec<String>,
expand_all_features: bool,
expand_default_features: bool,
expand_features: Option<Vec<String>>,
macro_expansion_config: &'a MacroExpansionConfig,
parse_config: &'a ParseConfig,

parsed_crates: HashSet<String>,
cache_src: HashMap<FilePathBuf, Vec<syn::Item>>,
Expand All @@ -132,32 +111,33 @@ impl<'a> Parser<'a> {
return false;
}

if !self.parse_deps {
if !self.parse_config.parse_deps {
return false;
}

// Skip any whitelist or blacklist for expand
if self.expand.contains(&pkg_name) {
if self.parse_config.expand.crates.contains(&pkg_name) {
return true;
}

// If we have a whitelist, check it
if let Some(ref include) = self.include {
if let Some(ref include) = self.parse_config.include {
if !include.contains(&pkg_name) {
return false;
}
}

// Check the blacklist
return !STD_CRATES.contains(&pkg_name.as_ref()) && !self.exclude.contains(&pkg_name);
return !STD_CRATES.contains(&pkg_name.as_ref())
&& !self.parse_config.exclude.contains(&pkg_name);
}

fn parse_crate(&mut self, pkg: &PackageRef) -> Result<(), Error> {
assert!(self.lib.is_some());
self.parsed_crates.insert(pkg.name.clone());

// Check if we should use cargo expand for this crate
if self.expand.contains(&pkg.name) {
if self.parse_config.expand.crates.contains(&pkg.name) {
return self.parse_expand_crate(pkg);
}

Expand Down Expand Up @@ -207,9 +187,9 @@ impl<'a> Parser<'a> {
.unwrap()
.expand_crate(
pkg,
self.expand_all_features,
self.expand_default_features,
&self.expand_features,
self.parse_config.expand.all_features,
self.parse_config.expand.default_features,
&self.parse_config.expand.features,
)
.map_err(|x| Error::CargoExpand(pkg.name.clone(), x))?;
let i = syn::parse_file(&s).map_err(|x| Error::ParseSyntaxError {
Expand All @@ -229,6 +209,7 @@ impl<'a> Parser<'a> {
fn process_expanded_mod(&mut self, pkg: &PackageRef, items: &[syn::Item]) -> Result<(), Error> {
self.out.load_syn_crate_mod(
&self.macro_expansion_config,
&self.parse_config,
&self.binding_crate_name,
&pkg.name,
Cfg::join(&self.cfg_stack).as_ref(),
Expand Down Expand Up @@ -304,6 +285,7 @@ impl<'a> Parser<'a> {
) -> Result<(), Error> {
self.out.load_syn_crate_mod(
&self.macro_expansion_config,
&self.parse_config,
&self.binding_crate_name,
&pkg.name,
Cfg::join(&self.cfg_stack).as_ref(),
Expand Down Expand Up @@ -446,6 +428,7 @@ impl Parse {
pub fn load_syn_crate_mod(
&mut self,
macro_expansion_config: &MacroExpansionConfig,
parse_config: &ParseConfig,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
Expand All @@ -459,16 +442,34 @@ impl Parse {
}
match item {
syn::Item::ForeignMod(ref item) => {
self.load_syn_foreign_mod(binding_crate_name, crate_name, mod_cfg, item);
self.load_syn_foreign_mod(
parse_config,
binding_crate_name,
crate_name,
mod_cfg,
item,
);
}
syn::Item::Fn(ref item) => {
self.load_syn_fn(binding_crate_name, crate_name, mod_cfg, item);
self.load_syn_fn(parse_config, binding_crate_name, crate_name, mod_cfg, item);
}
syn::Item::Const(ref item) => {
self.load_syn_const(binding_crate_name, crate_name, mod_cfg, item);
self.load_syn_const(
parse_config,
binding_crate_name,
crate_name,
mod_cfg,
item,
);
}
syn::Item::Static(ref item) => {
self.load_syn_static(binding_crate_name, crate_name, mod_cfg, item);
self.load_syn_static(
parse_config,
binding_crate_name,
crate_name,
mod_cfg,
item,
);
}
syn::Item::Struct(ref item) => {
self.load_syn_struct(crate_name, mod_cfg, item);
Expand Down Expand Up @@ -524,6 +525,7 @@ impl Parse {
/// Enters a `extern "C" { }` declaration and loads function declarations.
fn load_syn_foreign_mod(
&mut self,
parse_config: &ParseConfig,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
Expand All @@ -537,7 +539,8 @@ impl Parse {
for foreign_item in &item.items {
match *foreign_item {
syn::ForeignItem::Fn(ref function) => {
if crate_name != binding_crate_name {
if !parse_config.should_generate_top_level_item(crate_name, binding_crate_name)
{
info!(
"Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name, &function.ident
Expand Down Expand Up @@ -567,12 +570,13 @@ impl Parse {
/// Loads a `fn` declaration
fn load_syn_fn(
&mut self,
parse_config: &ParseConfig,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
item: &syn::ItemFn,
) {
if crate_name != binding_crate_name {
if !parse_config.should_generate_top_level_item(crate_name, binding_crate_name) {
info!(
"Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name, &item.ident
Expand Down Expand Up @@ -681,12 +685,13 @@ impl Parse {
/// Loads a `const` declaration
fn load_syn_const(
&mut self,
parse_config: &ParseConfig,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
item: &syn::ItemConst,
) {
if crate_name != binding_crate_name {
if !parse_config.should_generate_top_level_item(crate_name, binding_crate_name) {
info!(
"Skip {}::{} - (const's outside of the binding crate are not used).",
crate_name, &item.ident
Expand Down Expand Up @@ -719,12 +724,13 @@ impl Parse {
/// Loads a `static` declaration
fn load_syn_static(
&mut self,
parse_config: &ParseConfig,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: Option<&Cfg>,
item: &syn::ItemStatic,
) {
if crate_name != binding_crate_name {
if !parse_config.should_generate_top_level_item(crate_name, binding_crate_name) {
info!(
"Skip {}::{} - (static's outside of the binding crate are not used).",
crate_name, &item.ident
Expand Down
1 change: 1 addition & 0 deletions template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ parse_deps = false
# include = []
exclude = []
clean = false
extra_bindings = []



Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/both/workspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdlib.h>

#define EXT_CONST 0

typedef struct ExtType {
uint32_t data;
} ExtType;
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/both/workspace.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdlib.h>

#define EXT_CONST 0

typedef struct ExtType {
uint32_t data;
} ExtType;
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/tag/workspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdlib.h>

#define EXT_CONST 0

struct ExtType {
uint32_t data;
};
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/tag/workspace.compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdlib.h>

#define EXT_CONST 0

struct ExtType {
uint32_t data;
};
Expand Down
2 changes: 2 additions & 0 deletions tests/expectations/workspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdlib.h>

#define EXT_CONST 0

typedef struct {
uint32_t data;
} ExtType;
Expand Down
Loading

0 comments on commit a3c1334

Please sign in to comment.