Skip to content

Commit e78018b

Browse files
committed
Hack: Copy metadata module to avoid uniffi_core dependency
In m-c we're running into linking issues in `uniffi_macros`, where it's missing symbols coming from `uniffi_core`: /bin/ld: uniffi_foreign_executor_callback_set: undefined version: /bin/ld: failed to set dynamic section sizes: bad value That's most likely this issue on Rust: rust-lang/rust#111888 It's called out that this likely actually broke because of another PR: rust-lang/rust#99944 Despite this bug there's a bit of an issue in UniFFI to begin with: We're exporting `extern "C"` functions from a crate that is a dependency of some other crates, including `uniffi_macros`, and thus the symbols land in a part where they are not needed. However for `uniffi_meta` in particular we don't need much from `uniffi_core`, so for now we just copy the necessary bits to get it all working.
1 parent 997691c commit e78018b

File tree

5 files changed

+97
-2
lines changed

5 files changed

+97
-2
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818

1919
- Crates can now use proc-macros without UDL files to export their interface. See the "Procedural Macros: Attributes and Derives" manual section for details.
2020

21+
## v0.24.2 (backend crates: v0.24.2) - (_2023-07-25_)
22+
23+
[All changes in v0.24.2](https://github.com/mozilla/uniffi-rs/compare/v0.24.1...v0.24.2).
24+
25+
### What's changed?
26+
27+
- Inline the metadata module in `uniffi_meta` to avoid a dependency of `uniffi_core` to avoid hitting an upstream bug during link time ([#1666](https://github.com/mozilla/uniffi-rs/pull/1666))
28+
2129
## v0.24.1 (backend crates: v0.24.1) - (_2023-06-23_)
2230

2331
[All changes in v0.24.1](https://github.com/mozilla/uniffi-rs/compare/v0.24.0...v0.24.1).

uniffi_meta/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,3 @@ bytes = "1.3"
1414
serde = { version = "1.0.136", features = ["derive"] }
1515
siphasher = "0.3"
1616
uniffi_checksum_derive = { version = "0.24.1", path = "../uniffi_checksum_derive" }
17-
uniffi_core = { path = "../uniffi_core", version = "=0.24.1" }

uniffi_meta/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub use reader::{read_metadata, read_metadata_type};
1919
mod types;
2020
pub use types::{AsType, ExternalKind, ObjectImpl, Type, TypeIterator};
2121

22+
mod metadata;
23+
2224
// This needs to match the minor version of the `uniffi` crate. See
2325
// `docs/uniffi-versioning.md` for details.
2426
//

uniffi_meta/src/metadata.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
// Copied from uniffi_core/src/metadata.rs
6+
// Due to a [Rust bug](https://github.com/rust-lang/rust/issues/113104) we don't want to pull in
7+
// `uniffi_core`.
8+
// This is the easy way out of that issue and is a temporary hacky solution.
9+
10+
/// Metadata constants, make sure to keep this in sync with copy in `uniffi_meta::reader`
11+
pub mod codes {
12+
// Top-level metadata item codes
13+
pub const FUNC: u8 = 0;
14+
pub const METHOD: u8 = 1;
15+
pub const RECORD: u8 = 2;
16+
pub const ENUM: u8 = 3;
17+
pub const INTERFACE: u8 = 4;
18+
pub const ERROR: u8 = 5;
19+
pub const NAMESPACE: u8 = 6;
20+
pub const CONSTRUCTOR: u8 = 7;
21+
pub const UDL_FILE: u8 = 8;
22+
pub const CALLBACK_INTERFACE: u8 = 9;
23+
pub const TRAIT_METHOD: u8 = 10;
24+
//pub const UNKNOWN: u8 = 255;
25+
26+
// Type codes
27+
pub const TYPE_U8: u8 = 0;
28+
pub const TYPE_U16: u8 = 1;
29+
pub const TYPE_U32: u8 = 2;
30+
pub const TYPE_U64: u8 = 3;
31+
pub const TYPE_I8: u8 = 4;
32+
pub const TYPE_I16: u8 = 5;
33+
pub const TYPE_I32: u8 = 6;
34+
pub const TYPE_I64: u8 = 7;
35+
pub const TYPE_F32: u8 = 8;
36+
pub const TYPE_F64: u8 = 9;
37+
pub const TYPE_BOOL: u8 = 10;
38+
pub const TYPE_STRING: u8 = 11;
39+
pub const TYPE_OPTION: u8 = 12;
40+
pub const TYPE_RECORD: u8 = 13;
41+
pub const TYPE_ENUM: u8 = 14;
42+
// 15 no longer used.
43+
pub const TYPE_INTERFACE: u8 = 16;
44+
pub const TYPE_VEC: u8 = 17;
45+
pub const TYPE_HASH_MAP: u8 = 18;
46+
pub const TYPE_SYSTEM_TIME: u8 = 19;
47+
pub const TYPE_DURATION: u8 = 20;
48+
pub const TYPE_CALLBACK_INTERFACE: u8 = 21;
49+
pub const TYPE_CUSTOM: u8 = 22;
50+
pub const TYPE_RESULT: u8 = 23;
51+
//pub const TYPE_FUTURE: u8 = 24;
52+
pub const TYPE_FOREIGN_EXECUTOR: u8 = 25;
53+
pub const TYPE_UNIT: u8 = 255;
54+
55+
// Literal codes
56+
pub const LIT_STR: u8 = 0;
57+
pub const LIT_INT: u8 = 1;
58+
pub const LIT_FLOAT: u8 = 2;
59+
pub const LIT_BOOL: u8 = 3;
60+
pub const LIT_NULL: u8 = 4;
61+
}
62+
63+
// Create a checksum for a MetadataBuffer
64+
//
65+
// This is used by the bindings code to verify that the library they link to is the same one
66+
// that the bindings were generated from.
67+
pub const fn checksum_metadata(buf: &[u8]) -> u16 {
68+
calc_checksum(buf, buf.len())
69+
}
70+
71+
const fn calc_checksum(bytes: &[u8], size: usize) -> u16 {
72+
// Taken from the fnv_hash() function from the FNV crate (https://github.com/servo/rust-fnv/blob/master/lib.rs).
73+
// fnv_hash() hasn't been released in a version yet.
74+
const INITIAL_STATE: u64 = 0xcbf29ce484222325;
75+
const PRIME: u64 = 0x100000001b3;
76+
77+
let mut hash = INITIAL_STATE;
78+
let mut i = 0;
79+
while i < size {
80+
hash ^= bytes[i] as u64;
81+
hash = hash.wrapping_mul(PRIME);
82+
i += 1;
83+
}
84+
// Convert the 64-bit hash to a 16-bit hash by XORing everything together
85+
(hash ^ (hash >> 16) ^ (hash >> 32) ^ (hash >> 48)) as u16
86+
}

uniffi_meta/src/reader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5+
use crate::metadata::{checksum_metadata, codes};
56
use crate::*;
67
use anyhow::{bail, ensure, Context, Result};
7-
use uniffi_core::metadata::{checksum_metadata, codes};
88

99
pub fn read_metadata(data: &[u8]) -> Result<Metadata> {
1010
MetadataReader::new(data).read_metadata()

0 commit comments

Comments
 (0)