From 33c45a26bb73ae973fbc7e8e250c3cfa526832cb Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Fri, 27 Jul 2018 17:05:31 +0200 Subject: [PATCH] Add ability to specify features to use for macro expansion Currently, `cbindgen` uses the `--all-features` flag when expanding a dependent crate. However, this may not be desirable in a number of cases: - Some C APIs may be gated by a feature flag and would not be present in the final cdylib depending on the features provided (for instance one could want to have the ability to build a "debug" version of the library which provides extra unstable hooks). In such cases, a programmatic `cbindgen` call in a build script would want to use only the features that will get used in the current build. - Some features may bring in large dependencies and/or potentially increase compilation time without affecting the FFI surface, and it would be faster and more efficient to disable them when running `cbindgen`. - Some features may require external libraries and/or hardware (e.g. dependencies on GPU libraries such as CUDA) that may not be available on the current machine without affecting the FFI surface. To alleviate this problem, this PR adds an extended version of the `parse.expand` configuration key, allowing control over the features used when expanding in a way similar to the way cargo handles extended dependencies (although note that there is a single version of each key, since the features refer to the features of the current crate). So for instance instead of writing `expand = ["euclid"]` one would write: ``` [parse.expand] crates = ["euclid"] ``` which is equivalent to: ``` [parse.expand] crates = ["euclid"] all_features = false default_features = true features = ["feature1", "feature2"] ``` Note that `all_features` is set to `false` by default in order to match cargo's behavior. For backwards compatibility, the old syntax `expand = ["euclid"]` is still supported and is equivalent to: ``` [parse.expand] crates = ["euclid"] all_features = true default_features = true features = null ``` In this case, `all_features` is set to `true` in order to match the previous behavior of cbindgen. --- README.md | 21 ++++- src/bindgen/builder.rs | 35 ++++++++- src/bindgen/cargo/cargo.rs | 11 ++- src/bindgen/cargo/cargo_expand.rs | 21 ++++- src/bindgen/config.rs | 77 ++++++++++++++++++- src/bindgen/parser.rs | 19 ++++- .../both/expand_default_features.c | 11 +++ tests/expectations/both/expand_features.c | 13 ++++ .../both/expand_no_default_features.c | 9 +++ tests/expectations/expand_default_features.c | 11 +++ .../expectations/expand_default_features.cpp | 14 ++++ tests/expectations/expand_features.c | 13 ++++ tests/expectations/expand_features.cpp | 16 ++++ .../expectations/expand_no_default_features.c | 9 +++ .../expand_no_default_features.cpp | 12 +++ .../tag/expand_default_features.c | 11 +++ tests/expectations/tag/expand_features.c | 13 ++++ .../tag/expand_no_default_features.c | 9 +++ tests/rust/expand_default_features/Cargo.lock | 4 + tests/rust/expand_default_features/Cargo.toml | 17 ++++ .../expand_default_features/cbindgen.toml | 5 ++ tests/rust/expand_default_features/src/lib.rs | 23 ++++++ .../rust/expand_default_features/src/main.rs | 2 + tests/rust/expand_features/Cargo.lock | 4 + tests/rust/expand_features/Cargo.toml | 18 +++++ tests/rust/expand_features/cbindgen.toml | 5 ++ tests/rust/expand_features/src/lib.rs | 23 ++++++ tests/rust/expand_features/src/main.rs | 2 + .../expand_no_default_features/Cargo.lock | 4 + .../expand_no_default_features/Cargo.toml | 17 ++++ .../expand_no_default_features/cbindgen.toml | 5 ++ .../expand_no_default_features/src/lib.rs | 23 ++++++ .../expand_no_default_features/src/main.rs | 2 + 33 files changed, 467 insertions(+), 12 deletions(-) create mode 100644 tests/expectations/both/expand_default_features.c create mode 100644 tests/expectations/both/expand_features.c create mode 100644 tests/expectations/both/expand_no_default_features.c create mode 100644 tests/expectations/expand_default_features.c create mode 100644 tests/expectations/expand_default_features.cpp create mode 100644 tests/expectations/expand_features.c create mode 100644 tests/expectations/expand_features.cpp create mode 100644 tests/expectations/expand_no_default_features.c create mode 100644 tests/expectations/expand_no_default_features.cpp create mode 100644 tests/expectations/tag/expand_default_features.c create mode 100644 tests/expectations/tag/expand_features.c create mode 100644 tests/expectations/tag/expand_no_default_features.c create mode 100644 tests/rust/expand_default_features/Cargo.lock create mode 100644 tests/rust/expand_default_features/Cargo.toml create mode 100644 tests/rust/expand_default_features/cbindgen.toml create mode 100644 tests/rust/expand_default_features/src/lib.rs create mode 100644 tests/rust/expand_default_features/src/main.rs create mode 100644 tests/rust/expand_features/Cargo.lock create mode 100644 tests/rust/expand_features/Cargo.toml create mode 100644 tests/rust/expand_features/cbindgen.toml create mode 100644 tests/rust/expand_features/src/lib.rs create mode 100644 tests/rust/expand_features/src/main.rs create mode 100644 tests/rust/expand_no_default_features/Cargo.lock create mode 100644 tests/rust/expand_no_default_features/Cargo.toml create mode 100644 tests/rust/expand_no_default_features/cbindgen.toml create mode 100644 tests/rust/expand_no_default_features/src/lib.rs create mode 100644 tests/rust/expand_no_default_features/src/main.rs diff --git a/README.md b/README.md index 8f67536..b99783f 100644 --- a/README.md +++ b/README.md @@ -98,13 +98,28 @@ parse_deps = true include = ["webrender", "webrender_traits"] # A black list of crate names that are not allowed to be parsed exclude = ["libc"] -# A list of crate names that should be run through `cargo expand` before -# parsing to expand any macros -expand = ["euclid"] # Whether to use a new temporary target directory when running `rustc --pretty=expanded`. # This may be required for some build processes. clean = false +[parse.expand] +# A list of crate names that should be run through `cargo expand` before +# parsing to expand any macros +crates = ["euclid"] +# If enabled, use the `--all-features` option when expanding. Ignored when +# `expand_features` is set. Disabled by default, except when using the +# `expand = ["euclid"]` shorthand for backwards-compatibility. +all_features = false +# When `enable_all_features` is disabled and this is also disabled, use the +# `--no-default-features` option when expanding. Enabled by default. +default_features = true +# A list of feature names that should be used when running `cargo expand`. This +# combines with `default_features` like in `Cargo.toml`. Note that the features +# listed here are features for the current crate being built, *not* the crates +# being expanded. The crate's `Cargo.toml` must take care of enabling the +# appropriate features in its dependencies +features = ["cbindgen"] + [export] # A list of additional items not used by exported functions to include in # the generated bindings diff --git a/src/bindgen/builder.rs b/src/bindgen/builder.rs index 51c1773..6b9de0c 100644 --- a/src/bindgen/builder.rs +++ b/src/bindgen/builder.rs @@ -173,7 +173,30 @@ impl Builder { #[allow(unused)] pub fn with_parse_expand>(mut self, expand: &[S]) -> Builder { - self.config.parse.expand = expand.iter().map(|x| String::from(x.as_ref())).collect(); + self.config.parse.expand.crates = expand.iter().map(|x| String::from(x.as_ref())).collect(); + self + } + + #[allow(unused)] + pub fn with_parse_expand_all_features(mut self, expand_all_features: bool) -> Builder { + self.config.parse.expand.all_features = expand_all_features; + self + } + + #[allow(unused)] + pub fn with_parse_expand_default_features(mut self, expand_default_features: bool) -> Builder { + self.config.parse.expand.default_features = expand_default_features; + self + } + + #[allow(unused)] + pub fn with_parse_expand_features>(mut self, expand_features: &[S]) -> Builder { + self.config.parse.expand.features = Some( + expand_features + .iter() + .map(|x| String::from(x.as_ref())) + .collect(), + ); self } @@ -295,7 +318,10 @@ impl Builder { self.config.parse.parse_deps, &self.config.parse.include, &self.config.parse.exclude, - &self.config.parse.expand, + &self.config.parse.expand.crates, + self.config.parse.expand.all_features, + self.config.parse.expand.default_features, + &self.config.parse.expand.features, )?); } else if let Some(cargo) = self.lib_cargo.clone() { result.extend_with(&parser::parse_lib( @@ -303,7 +329,10 @@ impl Builder { self.config.parse.parse_deps, &self.config.parse.include, &self.config.parse.exclude, - &self.config.parse.expand, + &self.config.parse.expand.crates, + self.config.parse.expand.all_features, + self.config.parse.expand.default_features, + &self.config.parse.expand.features, )?); } diff --git a/src/bindgen/cargo/cargo.rs b/src/bindgen/cargo/cargo.rs index a35d42d..812bc5b 100644 --- a/src/bindgen/cargo/cargo.rs +++ b/src/bindgen/cargo/cargo.rs @@ -197,12 +197,21 @@ impl Cargo { None } - pub(crate) fn expand_crate(&self, package: &PackageRef) -> Result { + pub(crate) fn expand_crate( + &self, + package: &PackageRef, + expand_all_features: bool, + expand_default_features: bool, + expand_features: &Option>, + ) -> Result { cargo_expand::expand( &self.manifest_path, &package.name, &package.version, self.clean, + expand_all_features, + expand_default_features, + expand_features, ) } } diff --git a/src/bindgen/cargo/cargo_expand.rs b/src/bindgen/cargo/cargo_expand.rs index 492932f..6ebac39 100644 --- a/src/bindgen/cargo/cargo_expand.rs +++ b/src/bindgen/cargo/cargo_expand.rs @@ -40,6 +40,9 @@ pub fn expand( crate_name: &str, version: &str, use_tempdir: bool, + expand_all_features: bool, + expand_default_features: bool, + expand_features: &Option>, ) -> Result { let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); let mut cmd = Command::new(cargo); @@ -56,7 +59,23 @@ pub fn expand( cmd.arg("--lib"); cmd.arg("--manifest-path"); cmd.arg(manifest_path); - cmd.arg("--all-features"); + if let Some(features) = expand_features { + cmd.arg("--features"); + let mut features_str = String::new(); + for (index, feature) in features.iter().enumerate() { + if index != 0 { + features_str.push_str(" "); + } + features_str.push_str(feature); + } + cmd.arg(features_str); + } + if expand_all_features { + cmd.arg("--all-features"); + } + if !expand_default_features { + cmd.arg("--no-default-features"); + } cmd.arg("-p"); cmd.arg(&format!("{}:{}", crate_name, version)); cmd.arg("--"); diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index fe64f1b..94cee19 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -4,12 +4,16 @@ use std::collections::HashMap; use std::default::Default; +use std::fmt; use std::fs::File; use std::io::prelude::*; use std::io::{self, BufReader}; use std::path::Path; use std::str::FromStr; +use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer}; +use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor}; + use toml; use bindgen::ir::annotation::AnnotationSet; @@ -409,6 +413,72 @@ impl Default for ConstantConfig { } } +/// Settings to apply when running `rustc --pretty=expanded` +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "snake_case")] +#[serde(deny_unknown_fields)] +#[serde(default)] +pub struct ParseExpandConfig { + /// The names of crates to parse with `rustc --pretty=expanded` + pub crates: Vec, + /// Whether to enable all the features when expanding. + pub all_features: bool, + /// Whether to use the default feature set when expanding. + pub default_features: bool, + /// List of features to use when expanding. Combines with `default_features` like in + /// `Cargo.toml`. + pub features: Option>, +} + +impl Default for ParseExpandConfig { + fn default() -> ParseExpandConfig { + ParseExpandConfig { + crates: Vec::new(), + all_features: false, + default_features: true, + features: None, + } + } +} + +// Backwards-compatibility deserializer for ParseExpandConfig. This allows accepting both the +// simple `expand = ["crate"]` and the more complex `expand = {"crates": ["crate"], +// "default_features": false}` format for the `expand` key. +// +// Note that one (major) difference between the two forms is that, for backwards-compatibility +// reasons, the `expand = ["crate"]` form will enable the `--all-features` flag by default while +// the `expand = {"crates": ["crate"]}` form will use the default feature set by default. +fn retrocomp_parse_expand_config_deserialize<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + struct ParseExpandVisitor; + + impl<'de> Visitor<'de> for ParseExpandVisitor { + type Value = ParseExpandConfig; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map or sequence of string") + } + + fn visit_seq>(self, seq: A) -> Result { + let crates = + as Deserialize>::deserialize(SeqAccessDeserializer::new(seq))?; + Ok(ParseExpandConfig { + crates, + all_features: true, + default_features: true, + features: None, + }) + } + + fn visit_map>(self, map: A) -> Result { + ::deserialize(MapAccessDeserializer::new(map)) + } + } + + deserializer.deserialize_any(ParseExpandVisitor) +} + /// Settings to apply when parsing. #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "snake_case")] @@ -428,8 +498,9 @@ pub struct ParseConfig { pub include: Option>, /// The names of crates to not parse pub exclude: Vec, - /// The names of crates to parse with `rustc --pretty=expanded` - pub expand: Vec, + /// The configuration options for `rustc --pretty=expanded` + #[serde(deserialize_with = "retrocomp_parse_expand_config_deserialize")] + pub expand: ParseExpandConfig, /// Whether to use a new temporary target directory when running `rustc --pretty=expanded`. /// This may be required for some build processes. pub clean: bool, @@ -441,7 +512,7 @@ impl Default for ParseConfig { parse_deps: false, include: None, exclude: Vec::new(), - expand: Vec::new(), + expand: ParseExpandConfig::default(), clean: false, } } diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index 29ba09a..ccdb692 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -37,6 +37,9 @@ pub fn parse_src(src_file: &Path) -> ParseResult { 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(), @@ -64,6 +67,9 @@ pub(crate) fn parse_lib( include: &Option>, exclude: &Vec, expand: &Vec, + expand_all_features: bool, + expand_default_features: bool, + expand_features: &Option>, ) -> ParseResult { let mut context = Parser { binding_crate_name: lib.binding_crate_name().to_owned(), @@ -72,6 +78,9 @@ pub(crate) fn parse_lib( include: include.clone(), exclude: exclude.clone(), expand: expand.clone(), + expand_all_features, + expand_default_features, + expand_features: expand_features.clone(), parsed_crates: HashSet::new(), cache_src: HashMap::new(), cache_expanded_crate: HashMap::new(), @@ -93,6 +102,9 @@ struct Parser { include: Option>, exclude: Vec, expand: Vec, + expand_all_features: bool, + expand_default_features: bool, + expand_features: Option>, parsed_crates: HashSet, cache_src: HashMap>, @@ -163,7 +175,12 @@ impl Parser { .lib .as_ref() .unwrap() - .expand_crate(pkg) + .expand_crate( + pkg, + self.expand_all_features, + self.expand_default_features, + &self.expand_features, + ) .map_err(|x| Error::CargoExpand(pkg.name.clone(), x))?; let i = syn::parse_file(&s).map_err(|x| Error::ParseSyntaxError { crate_name: pkg.name.clone(), diff --git a/tests/expectations/both/expand_default_features.c b/tests/expectations/both/expand_default_features.c new file mode 100644 index 0000000..1b5c5ce --- /dev/null +++ b/tests/expectations/both/expand_default_features.c @@ -0,0 +1,11 @@ +#include +#include +#include + +typedef struct Foo { + +} Foo; + +void extra_debug_fn(void); + +void root(Foo a); diff --git a/tests/expectations/both/expand_features.c b/tests/expectations/both/expand_features.c new file mode 100644 index 0000000..22beed1 --- /dev/null +++ b/tests/expectations/both/expand_features.c @@ -0,0 +1,13 @@ +#include +#include +#include + +typedef struct Foo { + +} Foo; + +void cbindgen(void); + +void extra_debug_fn(void); + +void root(Foo a); diff --git a/tests/expectations/both/expand_no_default_features.c b/tests/expectations/both/expand_no_default_features.c new file mode 100644 index 0000000..d29cc3c --- /dev/null +++ b/tests/expectations/both/expand_no_default_features.c @@ -0,0 +1,9 @@ +#include +#include +#include + +typedef struct Foo { + +} Foo; + +void root(Foo a); diff --git a/tests/expectations/expand_default_features.c b/tests/expectations/expand_default_features.c new file mode 100644 index 0000000..de28a4f --- /dev/null +++ b/tests/expectations/expand_default_features.c @@ -0,0 +1,11 @@ +#include +#include +#include + +typedef struct { + +} Foo; + +void extra_debug_fn(void); + +void root(Foo a); diff --git a/tests/expectations/expand_default_features.cpp b/tests/expectations/expand_default_features.cpp new file mode 100644 index 0000000..9d67b2c --- /dev/null +++ b/tests/expectations/expand_default_features.cpp @@ -0,0 +1,14 @@ +#include +#include + +struct Foo { + +}; + +extern "C" { + +void extra_debug_fn(); + +void root(Foo a); + +} // extern "C" diff --git a/tests/expectations/expand_features.c b/tests/expectations/expand_features.c new file mode 100644 index 0000000..2968f14 --- /dev/null +++ b/tests/expectations/expand_features.c @@ -0,0 +1,13 @@ +#include +#include +#include + +typedef struct { + +} Foo; + +void cbindgen(void); + +void extra_debug_fn(void); + +void root(Foo a); diff --git a/tests/expectations/expand_features.cpp b/tests/expectations/expand_features.cpp new file mode 100644 index 0000000..fae1d12 --- /dev/null +++ b/tests/expectations/expand_features.cpp @@ -0,0 +1,16 @@ +#include +#include + +struct Foo { + +}; + +extern "C" { + +void cbindgen(); + +void extra_debug_fn(); + +void root(Foo a); + +} // extern "C" diff --git a/tests/expectations/expand_no_default_features.c b/tests/expectations/expand_no_default_features.c new file mode 100644 index 0000000..afbb0aa --- /dev/null +++ b/tests/expectations/expand_no_default_features.c @@ -0,0 +1,9 @@ +#include +#include +#include + +typedef struct { + +} Foo; + +void root(Foo a); diff --git a/tests/expectations/expand_no_default_features.cpp b/tests/expectations/expand_no_default_features.cpp new file mode 100644 index 0000000..cc9f7cc --- /dev/null +++ b/tests/expectations/expand_no_default_features.cpp @@ -0,0 +1,12 @@ +#include +#include + +struct Foo { + +}; + +extern "C" { + +void root(Foo a); + +} // extern "C" diff --git a/tests/expectations/tag/expand_default_features.c b/tests/expectations/tag/expand_default_features.c new file mode 100644 index 0000000..752cfee --- /dev/null +++ b/tests/expectations/tag/expand_default_features.c @@ -0,0 +1,11 @@ +#include +#include +#include + +struct Foo { + +}; + +void extra_debug_fn(void); + +void root(struct Foo a); diff --git a/tests/expectations/tag/expand_features.c b/tests/expectations/tag/expand_features.c new file mode 100644 index 0000000..2ce69ca --- /dev/null +++ b/tests/expectations/tag/expand_features.c @@ -0,0 +1,13 @@ +#include +#include +#include + +struct Foo { + +}; + +void cbindgen(void); + +void extra_debug_fn(void); + +void root(struct Foo a); diff --git a/tests/expectations/tag/expand_no_default_features.c b/tests/expectations/tag/expand_no_default_features.c new file mode 100644 index 0000000..16782fd --- /dev/null +++ b/tests/expectations/tag/expand_no_default_features.c @@ -0,0 +1,9 @@ +#include +#include +#include + +struct Foo { + +}; + +void root(struct Foo a); diff --git a/tests/rust/expand_default_features/Cargo.lock b/tests/rust/expand_default_features/Cargo.lock new file mode 100644 index 0000000..39194fa --- /dev/null +++ b/tests/rust/expand_default_features/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "expand" +version = "0.1.0" + diff --git a/tests/rust/expand_default_features/Cargo.toml b/tests/rust/expand_default_features/Cargo.toml new file mode 100644 index 0000000..98a968d --- /dev/null +++ b/tests/rust/expand_default_features/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "expand" +version = "0.1.0" +authors = ["cbindgen"] + +[features] +default = ["extra_headers"] +extra_headers = [] +no_parse = [] + +[lib] +name = "expand" +crate-type = ["lib", "dylib"] + +[[bin]] +name = "expand" +path = "src/main.rs" diff --git a/tests/rust/expand_default_features/cbindgen.toml b/tests/rust/expand_default_features/cbindgen.toml new file mode 100644 index 0000000..5741ca7 --- /dev/null +++ b/tests/rust/expand_default_features/cbindgen.toml @@ -0,0 +1,5 @@ +[parse] +parse_deps = false +[parse.expand] +crates = ["expand"] +all_features = false diff --git a/tests/rust/expand_default_features/src/lib.rs b/tests/rust/expand_default_features/src/lib.rs new file mode 100644 index 0000000..ee51de9 --- /dev/null +++ b/tests/rust/expand_default_features/src/lib.rs @@ -0,0 +1,23 @@ +#[repr(C)] +struct Foo { + +} + +#[cfg(feature = "extra_headers")] +#[no_mangle] +pub extern "C" fn extra_debug_fn() { +} + +#[cfg(feature = "no_parse")] +pub extern "C" fn no_parse() { + x; +} + +#[cfg(feature = "cbindgen")] +#[no_mangle] +pub extern "C" fn cbindgen() { +} + +#[no_mangle] +pub extern "C" fn root(a: Foo) { +} diff --git a/tests/rust/expand_default_features/src/main.rs b/tests/rust/expand_default_features/src/main.rs new file mode 100644 index 0000000..f79c691 --- /dev/null +++ b/tests/rust/expand_default_features/src/main.rs @@ -0,0 +1,2 @@ +fn main() { +} diff --git a/tests/rust/expand_features/Cargo.lock b/tests/rust/expand_features/Cargo.lock new file mode 100644 index 0000000..39194fa --- /dev/null +++ b/tests/rust/expand_features/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "expand" +version = "0.1.0" + diff --git a/tests/rust/expand_features/Cargo.toml b/tests/rust/expand_features/Cargo.toml new file mode 100644 index 0000000..f1dc6d4 --- /dev/null +++ b/tests/rust/expand_features/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "expand" +version = "0.1.0" +authors = ["cbindgen"] + +[features] +default = ["extra_headers"] +extra_headers = [] +no_parse = [] +cbindgen = [] + +[lib] +name = "expand" +crate-type = ["lib", "dylib"] + +[[bin]] +name = "expand" +path = "src/main.rs" diff --git a/tests/rust/expand_features/cbindgen.toml b/tests/rust/expand_features/cbindgen.toml new file mode 100644 index 0000000..3d8686e --- /dev/null +++ b/tests/rust/expand_features/cbindgen.toml @@ -0,0 +1,5 @@ +[parse] +parse_deps = false +[parse.expand] +crates = ["expand"] +features = ["cbindgen"] diff --git a/tests/rust/expand_features/src/lib.rs b/tests/rust/expand_features/src/lib.rs new file mode 100644 index 0000000..ee51de9 --- /dev/null +++ b/tests/rust/expand_features/src/lib.rs @@ -0,0 +1,23 @@ +#[repr(C)] +struct Foo { + +} + +#[cfg(feature = "extra_headers")] +#[no_mangle] +pub extern "C" fn extra_debug_fn() { +} + +#[cfg(feature = "no_parse")] +pub extern "C" fn no_parse() { + x; +} + +#[cfg(feature = "cbindgen")] +#[no_mangle] +pub extern "C" fn cbindgen() { +} + +#[no_mangle] +pub extern "C" fn root(a: Foo) { +} diff --git a/tests/rust/expand_features/src/main.rs b/tests/rust/expand_features/src/main.rs new file mode 100644 index 0000000..f79c691 --- /dev/null +++ b/tests/rust/expand_features/src/main.rs @@ -0,0 +1,2 @@ +fn main() { +} diff --git a/tests/rust/expand_no_default_features/Cargo.lock b/tests/rust/expand_no_default_features/Cargo.lock new file mode 100644 index 0000000..39194fa --- /dev/null +++ b/tests/rust/expand_no_default_features/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "expand" +version = "0.1.0" + diff --git a/tests/rust/expand_no_default_features/Cargo.toml b/tests/rust/expand_no_default_features/Cargo.toml new file mode 100644 index 0000000..98a968d --- /dev/null +++ b/tests/rust/expand_no_default_features/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "expand" +version = "0.1.0" +authors = ["cbindgen"] + +[features] +default = ["extra_headers"] +extra_headers = [] +no_parse = [] + +[lib] +name = "expand" +crate-type = ["lib", "dylib"] + +[[bin]] +name = "expand" +path = "src/main.rs" diff --git a/tests/rust/expand_no_default_features/cbindgen.toml b/tests/rust/expand_no_default_features/cbindgen.toml new file mode 100644 index 0000000..53b00d9 --- /dev/null +++ b/tests/rust/expand_no_default_features/cbindgen.toml @@ -0,0 +1,5 @@ +[parse] +parse_deps = false +[parse.expand] +crates = ["expand"] +default_features = false diff --git a/tests/rust/expand_no_default_features/src/lib.rs b/tests/rust/expand_no_default_features/src/lib.rs new file mode 100644 index 0000000..ee51de9 --- /dev/null +++ b/tests/rust/expand_no_default_features/src/lib.rs @@ -0,0 +1,23 @@ +#[repr(C)] +struct Foo { + +} + +#[cfg(feature = "extra_headers")] +#[no_mangle] +pub extern "C" fn extra_debug_fn() { +} + +#[cfg(feature = "no_parse")] +pub extern "C" fn no_parse() { + x; +} + +#[cfg(feature = "cbindgen")] +#[no_mangle] +pub extern "C" fn cbindgen() { +} + +#[no_mangle] +pub extern "C" fn root(a: Foo) { +} diff --git a/tests/rust/expand_no_default_features/src/main.rs b/tests/rust/expand_no_default_features/src/main.rs new file mode 100644 index 0000000..f79c691 --- /dev/null +++ b/tests/rust/expand_no_default_features/src/main.rs @@ -0,0 +1,2 @@ +fn main() { +}