Added support for integrating the package_version information in a comment of the header file.
The new command line argument for this is --package-version. The TOML config file flag is package_version=true||false. Closes #926 Co-Authored-By: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
400f437643
commit
af469996e0
@ -33,6 +33,7 @@ pub struct Bindings {
|
||||
/// Bindings are generated by a recursive call to cbindgen
|
||||
/// and shouldn't do anything when written anywhere.
|
||||
noop: bool,
|
||||
package_version: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
@ -53,6 +54,7 @@ impl Bindings {
|
||||
functions: Vec<Function>,
|
||||
source_files: Vec<path::PathBuf>,
|
||||
noop: bool,
|
||||
package_version: String,
|
||||
) -> Bindings {
|
||||
Bindings {
|
||||
config,
|
||||
@ -65,6 +67,7 @@ impl Bindings {
|
||||
functions,
|
||||
source_files,
|
||||
noop,
|
||||
package_version,
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +212,20 @@ impl Bindings {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.config.package_version {
|
||||
out.new_line_if_not_start();
|
||||
match self.config.language {
|
||||
Language::C | Language::Cxx => {
|
||||
write!(out, "/* Package version: {} */", self.package_version);
|
||||
}
|
||||
Language::Cython => {
|
||||
write!(out, "''' Package version: {} '''", self.package_version);
|
||||
}
|
||||
}
|
||||
|
||||
out.new_line();
|
||||
}
|
||||
|
||||
if let Some(ref f) = self.config.header {
|
||||
out.new_line_if_not_start();
|
||||
write!(out, "{}", f);
|
||||
@ -228,11 +245,23 @@ impl Bindings {
|
||||
}
|
||||
if self.config.include_version {
|
||||
out.new_line_if_not_start();
|
||||
match self.config.language {
|
||||
Language::C | Language::Cxx => {
|
||||
write!(
|
||||
out,
|
||||
"/* Generated with cbindgen:{} */",
|
||||
crate::bindgen::config::VERSION
|
||||
);
|
||||
}
|
||||
Language::Cython => {
|
||||
write!(
|
||||
out,
|
||||
"''' Generated with cbindgen:{} '''",
|
||||
crate::bindgen::config::VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
out.new_line();
|
||||
}
|
||||
if let Some(ref f) = self.config.autogen_warning {
|
||||
|
@ -361,6 +361,7 @@ impl Builder {
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
true,
|
||||
String::new(),
|
||||
));
|
||||
}
|
||||
|
||||
@ -405,6 +406,7 @@ impl Builder {
|
||||
result.typedefs,
|
||||
result.functions,
|
||||
result.source_files,
|
||||
result.package_version,
|
||||
)
|
||||
.generate()
|
||||
}
|
||||
|
@ -919,6 +919,8 @@ pub struct Config {
|
||||
/// This option is useful when using cbindgen with tools such as python's cffi which
|
||||
/// doesn't understand include directives
|
||||
pub no_includes: bool,
|
||||
// Package version: True if the package version should appear as a comment in the .h file
|
||||
pub package_version: bool,
|
||||
/// Optional text to output at major sections to deter manual editing
|
||||
pub autogen_warning: Option<String>,
|
||||
/// Include a comment with the version of cbindgen used to generate the file
|
||||
@ -1040,6 +1042,7 @@ impl Default for Config {
|
||||
autogen_warning: None,
|
||||
include_version: false,
|
||||
no_includes: false,
|
||||
package_version: false,
|
||||
namespace: None,
|
||||
namespaces: None,
|
||||
using_namespaces: None,
|
||||
|
@ -7,7 +7,7 @@ use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
|
||||
use syn::ext::IdentExt;
|
||||
use syn::{self, UnOp};
|
||||
use syn::UnOp;
|
||||
|
||||
use crate::bindgen::config::{Config, Language};
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
|
||||
|
@ -27,6 +27,7 @@ pub struct Library {
|
||||
typedefs: ItemMap<Typedef>,
|
||||
functions: Vec<Function>,
|
||||
source_files: Vec<PathBuf>,
|
||||
package_version: String,
|
||||
}
|
||||
|
||||
impl Library {
|
||||
@ -42,6 +43,7 @@ impl Library {
|
||||
typedefs: ItemMap<Typedef>,
|
||||
functions: Vec<Function>,
|
||||
source_files: Vec<PathBuf>,
|
||||
package_version: String,
|
||||
) -> Library {
|
||||
Library {
|
||||
config,
|
||||
@ -54,6 +56,7 @@ impl Library {
|
||||
typedefs,
|
||||
functions,
|
||||
source_files,
|
||||
package_version,
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,6 +144,7 @@ impl Library {
|
||||
functions,
|
||||
self.source_files,
|
||||
false,
|
||||
self.package_version,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,13 @@ pub(crate) fn parse_lib(lib: Cargo, config: &Config) -> ParseResult {
|
||||
let binding_crate = context.lib.as_ref().unwrap().binding_crate_ref();
|
||||
context.parse_crate(&binding_crate)?;
|
||||
context.out.source_files = context.cache_src.keys().map(|k| k.to_owned()).collect();
|
||||
context.out.package_version = context
|
||||
.lib
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.binding_crate_ref()
|
||||
.version
|
||||
.unwrap();
|
||||
Ok(context.out)
|
||||
}
|
||||
|
||||
@ -409,6 +416,7 @@ pub struct Parse {
|
||||
pub typedefs: ItemMap<Typedef>,
|
||||
pub functions: Vec<Function>,
|
||||
pub source_files: Vec<FilePathBuf>,
|
||||
pub package_version: String,
|
||||
}
|
||||
|
||||
impl Parse {
|
||||
@ -423,6 +431,7 @@ impl Parse {
|
||||
typedefs: ItemMap::default(),
|
||||
functions: Vec::new(),
|
||||
source_files: Vec::new(),
|
||||
package_version: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,6 +480,7 @@ impl Parse {
|
||||
self.typedefs.extend_with(&other.typedefs);
|
||||
self.functions.extend_from_slice(&other.functions);
|
||||
self.source_files.extend_from_slice(&other.source_files);
|
||||
self.package_version = other.package_version.clone();
|
||||
}
|
||||
|
||||
fn load_syn_crate_mod<'a>(
|
||||
|
10
src/main.rs
10
src/main.rs
@ -49,6 +49,10 @@ fn apply_config_overrides(config: &mut Config, matches: &ArgMatches) {
|
||||
config.only_target_dependencies = true;
|
||||
}
|
||||
|
||||
if matches.get_flag("package-version") {
|
||||
config.package_version = true;
|
||||
}
|
||||
|
||||
match matches.try_get_one::<String>("style") {
|
||||
Ok(Some(style)) => {
|
||||
config.style = bindgen::Style::from_str(style).unwrap();
|
||||
@ -163,6 +167,12 @@ fn main() {
|
||||
.help("Specify the language to output bindings in")
|
||||
.value_parser(["c++", "C++", "c", "C", "cython", "Cython"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("package-version")
|
||||
.long("package-version")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Include the package version in the header comment")
|
||||
)
|
||||
.arg(
|
||||
Arg::new("cpp-compat")
|
||||
.long("cpp-compat")
|
||||
|
12
tests/expectations/package_version.c
Normal file
12
tests/expectations/package_version.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t bar;
|
||||
} Foo;
|
||||
|
||||
void doit(const Foo*);
|
20
tests/expectations/package_version.compat.c
Normal file
20
tests/expectations/package_version.compat.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t bar;
|
||||
} Foo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void doit(const Foo*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
17
tests/expectations/package_version.cpp
Normal file
17
tests/expectations/package_version.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <new>
|
||||
|
||||
struct Foo {
|
||||
uint64_t bar;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
void doit(const Foo*);
|
||||
|
||||
} // extern "C"
|
14
tests/expectations/package_version.pyx
Normal file
14
tests/expectations/package_version.pyx
Normal file
@ -0,0 +1,14 @@
|
||||
''' Package version: 0.1.0 '''
|
||||
|
||||
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
|
||||
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
|
||||
cdef extern from *:
|
||||
ctypedef bint bool
|
||||
ctypedef struct va_list
|
||||
|
||||
cdef extern from *:
|
||||
|
||||
ctypedef struct Foo:
|
||||
uint64_t bar;
|
||||
|
||||
void doit(const Foo*);
|
12
tests/expectations/package_version_both.c
Normal file
12
tests/expectations/package_version_both.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Foo {
|
||||
uint64_t bar;
|
||||
} Foo;
|
||||
|
||||
void doit(const struct Foo*);
|
20
tests/expectations/package_version_both.compat.c
Normal file
20
tests/expectations/package_version_both.compat.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Foo {
|
||||
uint64_t bar;
|
||||
} Foo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void doit(const struct Foo*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
12
tests/expectations/package_version_tag.c
Normal file
12
tests/expectations/package_version_tag.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Foo {
|
||||
uint64_t bar;
|
||||
};
|
||||
|
||||
void doit(const struct Foo*);
|
20
tests/expectations/package_version_tag.compat.c
Normal file
20
tests/expectations/package_version_tag.compat.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Package version: 0.1.0 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Foo {
|
||||
uint64_t bar;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void doit(const struct Foo*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
14
tests/expectations/package_version_tag.pyx
Normal file
14
tests/expectations/package_version_tag.pyx
Normal file
@ -0,0 +1,14 @@
|
||||
''' Package version: 0.1.0 '''
|
||||
|
||||
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
|
||||
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
|
||||
cdef extern from *:
|
||||
ctypedef bint bool
|
||||
ctypedef struct va_list
|
||||
|
||||
cdef extern from *:
|
||||
|
||||
cdef struct Foo:
|
||||
uint64_t bar;
|
||||
|
||||
void doit(const Foo*);
|
5
tests/rust/package_version/Cargo.lock
generated
Normal file
5
tests/rust/package_version/Cargo.lock
generated
Normal file
@ -0,0 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "package_version"
|
||||
version = "0.1.0"
|
7
tests/rust/package_version/Cargo.toml
Normal file
7
tests/rust/package_version/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "package_version"
|
||||
version = "0.1.0"
|
||||
authors = ["hitbear"]
|
||||
|
||||
[features]
|
||||
cbindgen = []
|
1
tests/rust/package_version/cbindgen.toml
Normal file
1
tests/rust/package_version/cbindgen.toml
Normal file
@ -0,0 +1 @@
|
||||
package_version = true
|
7
tests/rust/package_version/src/lib.rs
Normal file
7
tests/rust/package_version/src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#[repr(C)]
|
||||
pub struct Foo {
|
||||
bar: u64,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn doit(_: &Foo) {}
|
@ -26,6 +26,7 @@ fn run_cbindgen(
|
||||
cpp_compat: bool,
|
||||
style: Option<Style>,
|
||||
generate_depfile: bool,
|
||||
package_version: bool,
|
||||
) -> (Vec<u8>, Option<String>) {
|
||||
assert!(
|
||||
!(output.is_none() && generate_depfile),
|
||||
@ -58,6 +59,10 @@ fn run_cbindgen(
|
||||
}
|
||||
}
|
||||
|
||||
if package_version {
|
||||
command.arg("--package-version");
|
||||
}
|
||||
|
||||
if let Some(style) = style {
|
||||
command.arg("--style").arg(style_str(style));
|
||||
}
|
||||
@ -200,6 +205,7 @@ fn run_compile_test(
|
||||
cpp_compat: bool,
|
||||
style: Option<Style>,
|
||||
cbindgen_outputs: &mut HashSet<Vec<u8>>,
|
||||
package_version: bool,
|
||||
) {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let tests_path = Path::new(&crate_dir).join("tests");
|
||||
@ -248,6 +254,7 @@ fn run_compile_test(
|
||||
cpp_compat,
|
||||
style,
|
||||
generate_depfile,
|
||||
package_version,
|
||||
);
|
||||
if generate_depfile {
|
||||
let depfile = depfile_contents.expect("No depfile generated");
|
||||
@ -329,6 +336,7 @@ fn test_file(name: &'static str, filename: &'static str) {
|
||||
*cpp_compat,
|
||||
Some(*style),
|
||||
&mut cbindgen_outputs,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -341,6 +349,7 @@ fn test_file(name: &'static str, filename: &'static str) {
|
||||
/* cpp_compat = */ false,
|
||||
None,
|
||||
&mut HashSet::new(),
|
||||
false,
|
||||
);
|
||||
|
||||
// `Style::Both` should be identical to `Style::Tag` for Cython.
|
||||
@ -354,6 +363,7 @@ fn test_file(name: &'static str, filename: &'static str) {
|
||||
/* cpp_compat = */ false,
|
||||
Some(*style),
|
||||
&mut cbindgen_outputs,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user