From 6344ff77e500f4d5d79ca6b0789c627cd052d236 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 31 Jul 2023 20:38:47 +0200 Subject: [PATCH] uniffi_macros: Force-include the `Cargo.toml` to read --- uniffi_macros/src/lib.rs | 22 ++++++++++++++++++++++ uniffi_macros/src/util.rs | 16 ++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/uniffi_macros/src/lib.rs b/uniffi_macros/src/lib.rs index ee4f600939..fcbb848713 100644 --- a/uniffi_macros/src/lib.rs +++ b/uniffi_macros/src/lib.rs @@ -186,9 +186,31 @@ pub fn include_scaffolding(component_name: TokenStream) -> TokenStream { }, None, ); + + let toml_path = match util::manifest_path() { + Ok(path) => path.display().to_string(), + Err(_) => { + return quote! { + compile_error!("This macro assumes the crate has a build.rs script, but $OUT_DIR is not present"); + }.into(); + } + }; + quote! { #metadata + // FIXME(HACK): + // Include the `Cargo.toml` file into the build. + // That way cargo tracks the file and other tools relying on file + // tracking see it as well. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1846223 + // In the future we should handle that by using the `track_path::path` API, + // see https://github.com/rust-lang/rust/pull/84029 + #[allow(dead_code)] + mod __unused { + const _: &[u8] = include_bytes!(#toml_path); + } + include!(concat!(env!("OUT_DIR"), "/", #name, ".uniffi.rs")); } }.into() diff --git a/uniffi_macros/src/util.rs b/uniffi_macros/src/util.rs index b516666dac..2e4164b392 100644 --- a/uniffi_macros/src/util.rs +++ b/uniffi_macros/src/util.rs @@ -4,18 +4,24 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{format_ident, quote, ToTokens}; +use std::path::{Path as StdPath, PathBuf}; use syn::{ ext::IdentExt, parse::{Parse, ParseStream}, Attribute, Path, Token, }; +pub fn manifest_path() -> Result { + let manifest_dir = + std::env::var_os("CARGO_MANIFEST_DIR").ok_or("`CARGO_MANIFEST_DIR` is not set")?; + + Ok(StdPath::new(&manifest_dir).join("Cargo.toml")) +} + #[cfg(not(feature = "nightly"))] pub fn mod_path() -> syn::Result { // Without the nightly feature and TokenStream::expand_expr, just return the crate name - use std::path::Path; - use fs_err as fs; use once_cell::sync::Lazy; use serde::Deserialize; @@ -38,11 +44,9 @@ pub fn mod_path() -> syn::Result { } static LIB_CRATE_MOD_PATH: Lazy> = Lazy::new(|| { - let manifest_dir = - std::env::var_os("CARGO_MANIFEST_DIR").ok_or("`CARGO_MANIFEST_DIR` is not set")?; + let file = manifest_path()?; + let cargo_toml_bytes = fs::read(file).map_err(|e| e.to_string())?; - let cargo_toml_bytes = - fs::read(Path::new(&manifest_dir).join("Cargo.toml")).map_err(|e| e.to_string())?; let cargo_toml = toml::from_slice::(&cargo_toml_bytes) .map_err(|e| format!("Failed to parse `Cargo.toml`: {e}"))?;