diff --git a/Cargo.toml b/Cargo.toml index c7789f383e59..70487c3e6bf8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ bitflags = "2.9" gir-format-check = "^0.1" glib-sys = { path = "glib/sys", version = "0.22" } gobject-sys = { path = "glib/gobject-sys", version = "0.22" } -glib = { path = "glib", version = "0.22" } +glib = { path = "glib", version = "0.22", default-features = false } gio-sys = { path = "gio/sys", version = "0.22" } gio = { path = "gio", version = "0.22" } pango-sys = { path = "pango/sys", version = "0.22" } @@ -48,6 +48,6 @@ pango = { path = "pango", version = "0.22" } pangocairo-sys = { path = "pangocairo/sys", version = "0.22" } cairo-sys-rs = { path = "cairo/sys", version = "0.22" } cairo-rs = { path = "cairo", version = "0.22" } -glib-macros = { path = "glib-macros", version = "0.22" } +glib-macros = { path = "glib-macros", version = "0.22", default-features = false } gdk-pixbuf-sys = { path = "gdk-pixbuf/sys", version = "0.22" } graphene-sys = { path = "graphene/sys", version = "0.22" } diff --git a/gio/Cargo.toml b/gio/Cargo.toml index b3e073bfa61f..02b1c7759b58 100644 --- a/gio/Cargo.toml +++ b/gio/Cargo.toml @@ -41,7 +41,7 @@ futures-channel = "0.3" futures-io = "0.3" futures-util = { version = "0.3", default-features = false } gio-sys.workspace = true -glib.workspace = true +glib = { workspace = true, features = ["futures"] } pin-project-lite = "0.2" smallvec = "1" diff --git a/glib-macros/Cargo.toml b/glib-macros/Cargo.toml index 3cb0f51f2c67..7f347827712e 100644 --- a/glib-macros/Cargo.toml +++ b/glib-macros/Cargo.toml @@ -12,12 +12,16 @@ repository.workspace = true rust-version.workspace = true version.workspace = true +[features] +default = ["proc_macro_crate"] +proc_macro_crate = ["proc-macro-crate"] + [dependencies] heck = "0.5" proc-macro2 = "1.0" quote = "1.0" syn = { version = "2.0.106", features = ["full"] } -proc-macro-crate = "3.3" +proc-macro-crate = { version = "3.3", optional = true } [lib] proc-macro = true diff --git a/glib-macros/src/utils.rs b/glib-macros/src/utils.rs index 9860e2df0f5c..0447fbfd00fa 100644 --- a/glib-macros/src/utils.rs +++ b/glib-macros/src/utils.rs @@ -1,7 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. use proc_macro2::{Ident, Span, TokenStream}; -use proc_macro_crate::crate_name; use quote::{quote, quote_spanned, ToTokens}; use syn::{ meta::ParseNestedMeta, parse::Parse, punctuated::Punctuated, spanned::Spanned, token::Comma, @@ -185,8 +184,9 @@ pub fn parse_optional_nested_meta_items<'a>( } } +#[cfg(feature = "proc_macro_crate")] pub fn crate_ident_new() -> TokenStream { - use proc_macro_crate::FoundCrate; + use proc_macro_crate::{crate_name, FoundCrate}; match crate_name("glib") { Ok(FoundCrate::Name(name)) => Some(name), @@ -214,6 +214,12 @@ pub fn crate_ident_new() -> TokenStream { }) } +#[cfg(not(feature = "proc_macro_crate"))] +pub fn crate_ident_new() -> TokenStream { + let glib = Ident::new("glib", Span::call_site()); + quote!(#glib) +} + // Generate i32 to enum mapping, used to implement // glib::translate::TryFromGlib, such as: // diff --git a/glib/Cargo.toml b/glib/Cargo.toml index 8c134dc984a0..c45399cfce02 100644 --- a/glib/Cargo.toml +++ b/glib/Cargo.toml @@ -19,14 +19,14 @@ name = "glib" [dependencies] libc.workspace = true bitflags.workspace = true -futures-core = { version = "0.3", default-features = false } -futures-task = { version = "0.3", default-features = false } -futures-executor = "0.3" -futures-channel = "0.3" -futures-util = "0.3" +futures-core = { version = "0.3", default-features = false, optional = true } +futures-task = { version = "0.3", default-features = false, optional = true } +futures-executor = { version = "0.3", optional = true } +futures-channel = { version = "0.3", optional = true } +futures-util = { version = "0.3", optional = true } glib-sys.workspace = true gobject-sys.workspace = true -glib-macros.workspace = true +glib-macros = { workspace = true, default-features = false } rs-log = { package = "log", version = "0.4", optional = true } smallvec = { version = "1.15", features = ["union", "const_generics", "const_new"] } gio-sys = { workspace = true, optional = true } @@ -39,7 +39,7 @@ trybuild2 = "1" criterion = "0.7.0" [features] -default = ["gio"] +default = ["gio", "futures"] v2_58 = ["glib-sys/v2_58", "gobject-sys/v2_58"] v2_60 = ["v2_58", "glib-sys/v2_60"] v2_62 = ["v2_60", "glib-sys/v2_62", "gobject-sys/v2_62"] @@ -59,7 +59,8 @@ log = ["rs-log"] log_kv = ["log", "rs-log/kv"] log_macros = ["log"] compiletests = [] -gio = ["gio-sys"] +gio = ["gio-sys", "futures"] +futures = ["futures-core", "futures-task", "futures-executor", "futures-channel", "futures-util"] [[test]] name = "subclass_compiletest" diff --git a/glib/src/functions.rs b/glib/src/functions.rs index 612951fc3d36..aaa7a0548270 100644 --- a/glib/src/functions.rs +++ b/glib/src/functions.rs @@ -283,6 +283,7 @@ pub fn file_open_tmp( /// /// This can be called from any thread and will execute the future from the thread /// where main context is running, e.g. via a `MainLoop`. +#[cfg(feature = "futures")] pub fn spawn_future + Send + 'static>( f: F, ) -> crate::JoinHandle { @@ -298,6 +299,7 @@ pub fn spawn_future + Send /// This can be called only from the thread where the main context is running, e.g. /// from any other `Future` that is executed on this main context, or after calling /// `with_thread_default` or `acquire` on the main context. +#[cfg(feature = "futures")] pub fn spawn_future_local + 'static>( f: F, ) -> crate::JoinHandle { diff --git a/glib/src/lib.rs b/glib/src/lib.rs index 661d5fc573c8..e2a93064ae6b 100644 --- a/glib/src/lib.rs +++ b/glib/src/lib.rs @@ -26,6 +26,9 @@ //! [`translate`]: mod@translate #![doc = include_str!("../README.md")] +// for macros +extern crate self as glib; + pub use bitflags; #[doc(hidden)] pub use glib_macros::cstr_bytes; @@ -228,12 +231,18 @@ pub use self::bridged_logging::{ #[macro_use] pub mod subclass; +#[cfg(feature = "futures")] mod main_context_futures; +#[cfg(feature = "futures")] pub use main_context_futures::{JoinError, JoinHandle, SpawnWithinJoinHandle}; +#[cfg(feature = "futures")] mod source_futures; +#[cfg(feature = "futures")] pub use self::source_futures::*; +#[cfg(feature = "futures")] mod future_with_timeout; +#[cfg(feature = "futures")] pub use self::future_with_timeout::*; mod thread_pool; diff --git a/glib/src/thread_pool.rs b/glib/src/thread_pool.rs index 38cc94362503..6ff1256b4711 100644 --- a/glib/src/thread_pool.rs +++ b/glib/src/thread_pool.rs @@ -1,8 +1,11 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use std::{future::Future, panic, ptr}; +use std::{panic, ptr}; +#[cfg(feature = "futures")] use futures_channel::oneshot; +#[cfg(feature = "futures")] +use std::future::Future; use crate::{ffi, translate::*}; @@ -104,6 +107,7 @@ impl ThreadPool { } } + #[cfg(feature = "futures")] pub fn push_future T + Send + 'static>( &self, func: F, @@ -241,6 +245,7 @@ mod tests { assert_eq!(receiver.recv(), Ok(true)); } + #[cfg(feature = "futures")] #[test] fn test_push_future() { let c = crate::MainContext::new(); diff --git a/glib/tests/clone.rs b/glib/tests/clone.rs index 354c80b2a34e..d9b380f1977c 100644 --- a/glib/tests/clone.rs +++ b/glib/tests/clone.rs @@ -9,7 +9,6 @@ use std::{ thread, }; -use futures_executor::block_on; use glib::clone; struct State { @@ -1053,11 +1052,12 @@ fn test_clone_macro_body() { assert_eq!(10, *v.lock().expect("failed to lock")); } +#[cfg(feature = "futures")] #[test] fn test_clone_macro_async_kinds() { let v = Rc::new(RefCell::new(1)); - block_on(clone!( + futures_executor::block_on(clone!( #[weak] v, async move {