From ef9c344f085b93440792321d0453dc51fb0fa6f6 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Fri, 3 Jan 2020 11:59:38 +0100 Subject: [PATCH] Fix for finding dependency version in lockfile v2 With lockfile v2 a version is not required for dependencies if the lock file only contains a single entry for a specified crate. However, without a version present, at a later stage, a dependant crate will not be found in the metadata cache which causes the dependency to be ignored completely. This commit tries to infer the version of dependant crates when the version specifier is missing from the contents of the lockfile. --- src/bindgen/cargo/cargo.rs | 20 ++++++++++++++++++++ tests/expectations/both/dep_v2.c | 11 +++++++++++ tests/expectations/both/dep_v2.compat.c | 19 +++++++++++++++++++ tests/expectations/dep_v2.c | 11 +++++++++++ tests/expectations/dep_v2.compat.c | 19 +++++++++++++++++++ tests/expectations/dep_v2.cpp | 15 +++++++++++++++ tests/expectations/tag/dep_v2.c | 11 +++++++++++ tests/expectations/tag/dep_v2.compat.c | 19 +++++++++++++++++++ tests/rust/dep_v2/Cargo.lock | 12 ++++++++++++ tests/rust/dep_v2/Cargo.toml | 8 ++++++++ tests/rust/dep_v2/cbindgen.toml | 3 +++ tests/rust/dep_v2/dep/Cargo.toml | 7 +++++++ tests/rust/dep_v2/dep/src/lib.rs | 5 +++++ tests/rust/dep_v2/src/lib.rs | 6 ++++++ 14 files changed, 166 insertions(+) create mode 100644 tests/expectations/both/dep_v2.c create mode 100644 tests/expectations/both/dep_v2.compat.c create mode 100644 tests/expectations/dep_v2.c create mode 100644 tests/expectations/dep_v2.compat.c create mode 100644 tests/expectations/dep_v2.cpp create mode 100644 tests/expectations/tag/dep_v2.c create mode 100644 tests/expectations/tag/dep_v2.compat.c create mode 100644 tests/rust/dep_v2/Cargo.lock create mode 100644 tests/rust/dep_v2/Cargo.toml create mode 100644 tests/rust/dep_v2/cbindgen.toml create mode 100644 tests/rust/dep_v2/dep/Cargo.toml create mode 100644 tests/rust/dep_v2/dep/src/lib.rs create mode 100644 tests/rust/dep_v2/src/lib.rs diff --git a/src/bindgen/cargo/cargo.rs b/src/bindgen/cargo/cargo.rs index 1718a3d7f..5470b8667 100644 --- a/src/bindgen/cargo/cargo.rs +++ b/src/bindgen/cargo/cargo.rs @@ -135,6 +135,26 @@ impl Cargo { .map(|dep| { let (dep_name, dep_version) = parse_dep_string(dep); + // If a version was not specified find the only package with the name of the dependency + let dep_version = dep_version.or_else(|| { + let mut versions = self.metadata.packages.iter().filter_map(|package| { + if package.name_and_version.name != dep_name { + return None; + } + package.name_and_version.version.as_ref().map(|v| v.as_str()) + }); + + // If the iterator contains more items, meaning multiple versions of the same + // package are present, warn! amd abort. + let version = versions.next(); + if versions.next().is_none() { + version + } else { + warn!("when looking for a version for package {}, multiple versions where found", dep_name); + None + } + }); + // Try to find the cfgs in the Cargo.toml let cfg = self .metadata diff --git a/tests/expectations/both/dep_v2.c b/tests/expectations/both/dep_v2.c new file mode 100644 index 000000000..401228965 --- /dev/null +++ b/tests/expectations/both/dep_v2.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +typedef struct dep_struct { + uint32_t x; + double y; +} dep_struct; + +uint32_t get_x(const dep_struct *dep_struct); diff --git a/tests/expectations/both/dep_v2.compat.c b/tests/expectations/both/dep_v2.compat.c new file mode 100644 index 000000000..056089ef0 --- /dev/null +++ b/tests/expectations/both/dep_v2.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef struct dep_struct { + uint32_t x; + double y; +} dep_struct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +uint32_t get_x(const dep_struct *dep_struct); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/dep_v2.c b/tests/expectations/dep_v2.c new file mode 100644 index 000000000..3d2cf8e14 --- /dev/null +++ b/tests/expectations/dep_v2.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +typedef struct { + uint32_t x; + double y; +} dep_struct; + +uint32_t get_x(const dep_struct *dep_struct); diff --git a/tests/expectations/dep_v2.compat.c b/tests/expectations/dep_v2.compat.c new file mode 100644 index 000000000..4dc7fb377 --- /dev/null +++ b/tests/expectations/dep_v2.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef struct { + uint32_t x; + double y; +} dep_struct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +uint32_t get_x(const dep_struct *dep_struct); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/dep_v2.cpp b/tests/expectations/dep_v2.cpp new file mode 100644 index 000000000..f03f098b1 --- /dev/null +++ b/tests/expectations/dep_v2.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +struct dep_struct { + uint32_t x; + double y; +}; + +extern "C" { + +uint32_t get_x(const dep_struct *dep_struct); + +} // extern "C" diff --git a/tests/expectations/tag/dep_v2.c b/tests/expectations/tag/dep_v2.c new file mode 100644 index 000000000..45fcba665 --- /dev/null +++ b/tests/expectations/tag/dep_v2.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +struct dep_struct { + uint32_t x; + double y; +}; + +uint32_t get_x(const struct dep_struct *dep_struct); diff --git a/tests/expectations/tag/dep_v2.compat.c b/tests/expectations/tag/dep_v2.compat.c new file mode 100644 index 000000000..344af6468 --- /dev/null +++ b/tests/expectations/tag/dep_v2.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +struct dep_struct { + uint32_t x; + double y; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +uint32_t get_x(const struct dep_struct *dep_struct); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/rust/dep_v2/Cargo.lock b/tests/rust/dep_v2/Cargo.lock new file mode 100644 index 000000000..8019bb0d9 --- /dev/null +++ b/tests/rust/dep_v2/Cargo.lock @@ -0,0 +1,12 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "dep" +version = "0.1.0" + +[[package]] +name = "expand-dep" +version = "0.1.0" +dependencies = [ + "dep", +] diff --git a/tests/rust/dep_v2/Cargo.toml b/tests/rust/dep_v2/Cargo.toml new file mode 100644 index 000000000..40e3e8b86 --- /dev/null +++ b/tests/rust/dep_v2/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "expand-dep" +version = "0.1.0" +authors = ["cbindgen"] +edition = "2018" + +[dependencies] +dep = { path = "dep" } diff --git a/tests/rust/dep_v2/cbindgen.toml b/tests/rust/dep_v2/cbindgen.toml new file mode 100644 index 000000000..ac9c27815 --- /dev/null +++ b/tests/rust/dep_v2/cbindgen.toml @@ -0,0 +1,3 @@ +[parse] +parse_deps = true +include = ["dep"] diff --git a/tests/rust/dep_v2/dep/Cargo.toml b/tests/rust/dep_v2/dep/Cargo.toml new file mode 100644 index 000000000..1cc8d6241 --- /dev/null +++ b/tests/rust/dep_v2/dep/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "dep" +version = "0.1.0" +authors = ["cbindgen"] +edition = "2018" + +[dependencies] diff --git a/tests/rust/dep_v2/dep/src/lib.rs b/tests/rust/dep_v2/dep/src/lib.rs new file mode 100644 index 000000000..7253c5770 --- /dev/null +++ b/tests/rust/dep_v2/dep/src/lib.rs @@ -0,0 +1,5 @@ +#[repr(C)] +pub struct dep_struct { + pub x: u32, + pub y: f64, +} diff --git a/tests/rust/dep_v2/src/lib.rs b/tests/rust/dep_v2/src/lib.rs new file mode 100644 index 000000000..639678d07 --- /dev/null +++ b/tests/rust/dep_v2/src/lib.rs @@ -0,0 +1,6 @@ +use dep::dep_struct; + +#[no_mangle] +pub unsafe extern "C" fn get_x(dep_struct: *const dep_struct) -> u32 { + dep_struct.read().x +}