Allow controlling the Cargo profile used for macro expansion
If there's already a release build, it's better for cbindgen to reuse the build artifacts from that to expand macros rather than starting from scratch with a debug build. Controlled with --profile (debug|release) as well as parse.expand.profile in cbindgen.toml, though hardcoding a profile in a config file seems unlikely.
This commit is contained in:
parent
398b28ca30
commit
0ba241498e
83
Cargo.lock
generated
83
Cargo.lock
generated
@ -44,6 +44,7 @@ dependencies = [
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serial_test",
|
||||
"syn",
|
||||
"tempfile",
|
||||
"toml",
|
||||
@ -70,6 +71,15 @@ dependencies = [
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.15"
|
||||
@ -121,12 +131,27 @@ version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
@ -136,6 +161,30 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cloudabi",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.9"
|
||||
@ -222,6 +271,12 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.116"
|
||||
@ -253,6 +308,34 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b15f74add9a9d4a3eb2bf739c9a427d266d3895b53d992c3a7c234fec2ff1f1"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
"serial_test_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test_derive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65f59259be9fc1bf677d06cc1456e97756004a1a5a577480f71430bd7c17ba33"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
|
@ -31,6 +31,9 @@ version = "1.0.3"
|
||||
default-features = false
|
||||
features = ["clone-impls", "extra-traits", "full", "parsing", "printing"]
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.5.0"
|
||||
|
||||
[features]
|
||||
default = ["clap"]
|
||||
|
||||
|
@ -6,7 +6,7 @@ use std::path;
|
||||
|
||||
use crate::bindgen::bindings::Bindings;
|
||||
use crate::bindgen::cargo::Cargo;
|
||||
use crate::bindgen::config::{Braces, Config, Language, Style};
|
||||
use crate::bindgen::config::{Braces, Config, Language, Profile, Style};
|
||||
use crate::bindgen::error::Error;
|
||||
use crate::bindgen::library::Library;
|
||||
use crate::bindgen::parser::{self, Parse};
|
||||
@ -225,6 +225,12 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn with_parse_expand_profile(mut self, profile: Profile) -> Builder {
|
||||
self.config.parse.expand.profile = profile;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn with_documentation(mut self, documentation: bool) -> Builder {
|
||||
self.config.documentation = documentation;
|
||||
|
@ -11,6 +11,7 @@ use crate::bindgen::cargo::cargo_metadata::{self, Metadata};
|
||||
use crate::bindgen::cargo::cargo_toml;
|
||||
use crate::bindgen::error::Error;
|
||||
use crate::bindgen::ir::Cfg;
|
||||
pub(crate) use cargo_expand::Profile;
|
||||
|
||||
/// Parse a dependency string used in Cargo.lock
|
||||
fn parse_dep_string(dep_string: &str) -> (&str, Option<&str>) {
|
||||
@ -233,6 +234,7 @@ impl Cargo {
|
||||
expand_all_features: bool,
|
||||
expand_default_features: bool,
|
||||
expand_features: &Option<Vec<String>>,
|
||||
profile: Profile,
|
||||
) -> Result<String, cargo_expand::Error> {
|
||||
cargo_expand::expand(
|
||||
&self.manifest_path,
|
||||
@ -242,6 +244,7 @@ impl Cargo {
|
||||
expand_all_features,
|
||||
expand_default_features,
|
||||
expand_features,
|
||||
profile,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,14 @@ pub enum Error {
|
||||
Compile(String),
|
||||
}
|
||||
|
||||
/// Which Cargo profile (group) to use when expanding macros.
|
||||
pub enum Profile {
|
||||
/// Do not pass `--release` when expanding macros
|
||||
Debug,
|
||||
/// Pass `--release` when expanding macros
|
||||
Release,
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(err: io::Error) -> Self {
|
||||
Error::Io(err)
|
||||
@ -65,6 +73,7 @@ pub fn expand(
|
||||
expand_all_features: bool,
|
||||
expand_default_features: bool,
|
||||
expand_features: &Option<Vec<String>>,
|
||||
profile: Profile,
|
||||
) -> Result<String, Error> {
|
||||
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
|
||||
let mut cmd = Command::new(cargo);
|
||||
@ -108,6 +117,12 @@ pub fn expand(
|
||||
if !expand_default_features {
|
||||
cmd.arg("--no-default-features");
|
||||
}
|
||||
match profile {
|
||||
Profile::Debug => {}
|
||||
Profile::Release => {
|
||||
cmd.arg("--release");
|
||||
}
|
||||
}
|
||||
cmd.arg("-p");
|
||||
let mut package = crate_name.to_owned();
|
||||
if let Some(version) = version {
|
||||
|
@ -668,6 +668,27 @@ pub struct MacroExpansionConfig {
|
||||
pub bitflags: bool,
|
||||
}
|
||||
|
||||
/// Controls which Cargo profile is used for macro expansion.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum Profile {
|
||||
Debug,
|
||||
Release,
|
||||
}
|
||||
|
||||
impl FromStr for Profile {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Profile, Self::Err> {
|
||||
match s {
|
||||
"debug" | "Debug" => Ok(Profile::Debug),
|
||||
"release" | "Release" => Ok(Profile::Release),
|
||||
_ => Err(format!("Unrecognized Profile: '{}'.", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deserialize_enum_str!(Profile);
|
||||
|
||||
/// Settings to apply when running `rustc --pretty=expanded`
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@ -683,6 +704,8 @@ pub struct ParseExpandConfig {
|
||||
/// List of features to use when expanding. Combines with `default_features` like in
|
||||
/// `Cargo.toml`.
|
||||
pub features: Option<Vec<String>>,
|
||||
/// Controls whether or not to pass `--release` when expanding.
|
||||
pub profile: Profile,
|
||||
}
|
||||
|
||||
impl Default for ParseExpandConfig {
|
||||
@ -692,6 +715,7 @@ impl Default for ParseExpandConfig {
|
||||
all_features: false,
|
||||
default_features: true,
|
||||
features: None,
|
||||
profile: Profile::Debug,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -723,6 +747,7 @@ fn retrocomp_parse_expand_config_deserialize<'de, D: Deserializer<'de>>(
|
||||
all_features: true,
|
||||
default_features: true,
|
||||
features: None,
|
||||
profile: Profile::Debug,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -60,5 +60,6 @@ pub(crate) use self::cargo::*;
|
||||
|
||||
pub use self::bindings::Bindings;
|
||||
pub use self::builder::Builder;
|
||||
pub use self::config::Profile; // disambiguate with cargo::Profile
|
||||
pub use self::config::*;
|
||||
pub use self::error::Error;
|
||||
|
@ -9,8 +9,9 @@ use std::io::Read;
|
||||
use std::path::{Path as FilePath, PathBuf as FilePathBuf};
|
||||
|
||||
use crate::bindgen::bitflags;
|
||||
use crate::bindgen::cargo;
|
||||
use crate::bindgen::cargo::{Cargo, PackageRef};
|
||||
use crate::bindgen::config::{Config, ParseConfig};
|
||||
use crate::bindgen::config::{Config, ParseConfig, Profile};
|
||||
use crate::bindgen::error::Error;
|
||||
use crate::bindgen::ir::{
|
||||
AnnotationSet, Cfg, Constant, Documentation, Enum, Function, GenericParams, ItemMap,
|
||||
@ -191,6 +192,10 @@ impl<'a> Parser<'a> {
|
||||
self.config.parse.expand.all_features,
|
||||
self.config.parse.expand.default_features,
|
||||
&self.config.parse.expand.features,
|
||||
match self.config.parse.expand.profile {
|
||||
Profile::Debug => cargo::Profile::Debug,
|
||||
Profile::Release => cargo::Profile::Release,
|
||||
},
|
||||
)
|
||||
.map_err(|x| Error::CargoExpand(pkg.name.clone(), x))?;
|
||||
let i = syn::parse_file(&s).map_err(|x| Error::ParseSyntaxError {
|
||||
|
23
src/main.rs
23
src/main.rs
@ -5,6 +5,7 @@
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
extern crate clap;
|
||||
#[macro_use]
|
||||
@ -24,7 +25,7 @@ use clap::{App, Arg, ArgMatches};
|
||||
mod bindgen;
|
||||
mod logging;
|
||||
|
||||
use crate::bindgen::{Bindings, Builder, Cargo, Config, Error, Language, Style};
|
||||
use crate::bindgen::{Bindings, Builder, Cargo, Config, Error, Language, Profile, Style};
|
||||
|
||||
fn apply_config_overrides<'a>(config: &mut Config, matches: &ArgMatches<'a>) {
|
||||
// We allow specifying a language to override the config default. This is
|
||||
@ -61,6 +62,16 @@ fn apply_config_overrides<'a>(config: &mut Config, matches: &ArgMatches<'a>) {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(profile) = matches.value_of("profile") {
|
||||
config.parse.expand.profile = match Profile::from_str(profile) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_present("d") {
|
||||
config.parse.parse_deps = true;
|
||||
}
|
||||
@ -226,6 +237,16 @@ fn main() {
|
||||
)
|
||||
.required(false),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("profile")
|
||||
.long("profile")
|
||||
.value_name("PROFILE")
|
||||
.help(
|
||||
"Specify the profile to use when expanding macros. \
|
||||
Has no effect otherwise."
|
||||
)
|
||||
.possible_values(&["Debug", "debug", "Release", "release"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("quiet")
|
||||
.short("q")
|
||||
|
99
tests/profile.rs
Normal file
99
tests/profile.rs
Normal file
@ -0,0 +1,99 @@
|
||||
use cbindgen::*;
|
||||
|
||||
use serial_test::serial;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
fn build_using_lib(config: fn(Builder) -> Builder) -> tempfile::TempDir {
|
||||
let expand_dep_test_dir = {
|
||||
let mut this_file = PathBuf::from(file!());
|
||||
this_file.pop();
|
||||
this_file.extend(&["rust", "expand_dep"]);
|
||||
this_file
|
||||
};
|
||||
|
||||
let tmp_dir = tempfile::Builder::new()
|
||||
.prefix("cbindgen-test-output-")
|
||||
.tempdir()
|
||||
.expect("Creating tmp dir failed");
|
||||
|
||||
std::env::set_var("CARGO_EXPAND_TARGET_DIR", tmp_dir.path());
|
||||
let builder = Builder::new()
|
||||
.with_config(Config::from_file(expand_dep_test_dir.join("cbindgen.toml")).unwrap())
|
||||
.with_crate(expand_dep_test_dir);
|
||||
let builder = config(builder);
|
||||
builder.generate().expect("build should succeed");
|
||||
|
||||
tmp_dir
|
||||
}
|
||||
|
||||
fn build_using_bin(extra_args: &[&str]) -> tempfile::TempDir {
|
||||
let expand_dep_test_dir = {
|
||||
let mut this_file = PathBuf::from(file!());
|
||||
this_file.pop();
|
||||
this_file.extend(&["rust", "expand_dep"]);
|
||||
this_file
|
||||
};
|
||||
|
||||
let tmp_dir = tempfile::Builder::new()
|
||||
.prefix("cbindgen-test-output-")
|
||||
.tempdir()
|
||||
.expect("Creating tmp dir failed");
|
||||
|
||||
let cbindgen_path = env!("CARGO_BIN_EXE_cbindgen");
|
||||
Command::new(cbindgen_path)
|
||||
.current_dir(expand_dep_test_dir)
|
||||
.env("CARGO_EXPAND_TARGET_DIR", tmp_dir.path())
|
||||
.args(extra_args)
|
||||
.output()
|
||||
.expect("build should succed");
|
||||
|
||||
tmp_dir
|
||||
}
|
||||
|
||||
fn get_contents_of_dir(path: &Path) -> Vec<String> {
|
||||
path.read_dir()
|
||||
.unwrap()
|
||||
.map(|f| f.unwrap().file_name().to_str().unwrap().to_string())
|
||||
.filter(|name| !name.starts_with("."))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn lib_default_uses_debug_build() {
|
||||
let target_dir = build_using_lib(|b| b);
|
||||
assert_eq!(get_contents_of_dir(target_dir.path()), &["debug"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn lib_explicit_debug_build() {
|
||||
let target_dir = build_using_lib(|b| b.with_parse_expand_profile(Profile::Debug));
|
||||
assert_eq!(get_contents_of_dir(target_dir.path()), &["debug"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn lib_explicit_release_build() {
|
||||
let target_dir = build_using_lib(|b| b.with_parse_expand_profile(Profile::Release));
|
||||
assert_eq!(get_contents_of_dir(target_dir.path()), &["release"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bin_default_uses_debug_build() {
|
||||
let target_dir = build_using_bin(&[]);
|
||||
assert_eq!(get_contents_of_dir(target_dir.path()), &["debug"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bin_explicit_debug_build() {
|
||||
let target_dir = build_using_bin(&["--profile", "debug"]);
|
||||
assert_eq!(get_contents_of_dir(target_dir.path()), &["debug"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bin_explicit_release_build() {
|
||||
let target_dir = build_using_bin(&["--profile", "release"]);
|
||||
assert_eq!(get_contents_of_dir(target_dir.path()), &["release"]);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user