From 457f314fb0b516ff7f13621a69f523ede31eab85 Mon Sep 17 00:00:00 2001 From: Vlad Panfilov Date: Wed, 27 May 2026 12:29:25 -0700 Subject: [PATCH] Fix build on macOS - fs_util: add blocking_rename_no_replace_atomic for macOS using renamex_np(RENAME_EXCL), available since macOS 10.12 - fs_util: add libc dependency for macOS target - logtee: use redirect.rs (stdout pipe tee) on macOS, same as Linux/Windows - logtee: add filedescriptor dependency for macOS target - swarm: fix wrong target_os "osx" -> "macos" - Cargo.toml: patch xpc-connection from fork to fix type mismatch (value.len() as u64 -> usize) on newer toolchains --- Cargo.lock | 125 +-------------------------------------- Cargo.toml | 4 +- fs_util/Cargo.toml | 2 +- fs_util/src/safe_move.rs | 33 +++++++++++ logtee/rust/Cargo.toml | 2 +- logtee/rust/src/lib.rs | 4 +- utils/swarm/Cargo.toml | 2 +- 7 files changed, 42 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8753799c2..c506b8e00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1427,16 +1427,6 @@ dependencies = [ "futures-util", ] -[[package]] -name = "futures-async-runtime-preview" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c03035be1dae627b7e05c6984acb1f2086043fde5249ae51604f1ff20ed037" -dependencies = [ - "futures-core-preview", - "futures-stable-preview", -] - [[package]] name = "futures-channel" version = "0.3.32" @@ -1447,30 +1437,12 @@ dependencies = [ "futures-sink", ] -[[package]] -name = "futures-channel-preview" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f8aec6b0eb1d281843ec666fba2b71a49610181e3078fbef7a8cbed481821e" -dependencies = [ - "futures-core-preview", -] - [[package]] name = "futures-core" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" -[[package]] -name = "futures-core-preview" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "098785413db44e5dbf3b1fc23c24039a9091bea5acb3eb0d293f386f18aff97d" -dependencies = [ - "either", -] - [[package]] name = "futures-executor" version = "0.3.32" @@ -1482,19 +1454,6 @@ dependencies = [ "futures-util", ] -[[package]] -name = "futures-executor-preview" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ff61425699ca85de5c63c1f135278403518c3398bd15cf4b6fd1d21c9846e4" -dependencies = [ - "futures-channel-preview", - "futures-core-preview", - "futures-util-preview", - "lazy_static", - "num_cpus", -] - [[package]] name = "futures-intrusive" version = "0.5.0" @@ -1512,16 +1471,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" -[[package]] -name = "futures-io-preview" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaa769a6ac904912c1557b4dcf85b93db2bc9ba57c349f9ce43870e49d67f8e1" -dependencies = [ - "futures-core-preview", - "iovec", -] - [[package]] name = "futures-lite" version = "2.6.1" @@ -1543,49 +1492,12 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "futures-preview" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d575096a4e2cf458f309b5b7bce5c8aaad8e874b8d77f0aa26c08d7ac18f74" -dependencies = [ - "futures-async-runtime-preview", - "futures-channel-preview", - "futures-core-preview", - "futures-executor-preview", - "futures-io-preview", - "futures-sink-preview", - "futures-stable-preview", - "futures-util-preview", -] - [[package]] name = "futures-sink" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" -[[package]] -name = "futures-sink-preview" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc4cdc628b934f18a11ba070d589655f68cfec031a16381b0e7784ff0e9cc18" -dependencies = [ - "either", - "futures-channel-preview", - "futures-core-preview", -] - -[[package]] -name = "futures-stable-preview" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6ba960b8bbbc14a9a741cc8ad9c26aff44538ea14be021db905b43f33854da" -dependencies = [ - "futures-core-preview", - "futures-executor-preview", -] - [[package]] name = "futures-task" version = "0.3.32" @@ -1609,19 +1521,6 @@ dependencies = [ "slab", ] -[[package]] -name = "futures-util-preview" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b29aa737dba9e2e47a5dcd4d58ec7c7c2d5f78e8460f609f857bcf04163235e" -dependencies = [ - "either", - "futures-channel-preview", - "futures-core-preview", - "futures-io-preview", - "futures-sink-preview", -] - [[package]] name = "genawaiter" version = "0.99.1" @@ -2205,15 +2104,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -2839,16 +2729,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_enum" version = "0.7.5" @@ -6068,11 +5948,10 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "xpc-connection" version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbcc253dcd774514d89deff5fd62053b84d7f49025cd92d18c3e52c5eae43170" +source = "git+https://github.com/madadam/xpc-connection-rs#11d71e1f7cfd409133ec01a6cc9f30d50918488a" dependencies = [ "block", - "futures-preview", + "futures", "xpc-connection-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 09a7eb03f..b4b275f04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,7 +103,9 @@ opt-level = 3 [patch.crates-io] # The upstream has outdated dependency on `bindgen` which conflicts with some of our other -# dependencies. Using this fork until the upstream updates. +# dependencies, and xpc-connection has a type mismatch on newer toolchains. Using this fork until +# the upstream updates. +xpc-connection = { git = "https://github.com/madadam/xpc-connection-rs" } xpc-connection-sys = { git = "https://github.com/madadam/xpc-connection-rs" } [workspace.lints.clippy] diff --git a/fs_util/Cargo.toml b/fs_util/Cargo.toml index 31789a919..dfbe489c9 100644 --- a/fs_util/Cargo.toml +++ b/fs_util/Cargo.toml @@ -13,7 +13,7 @@ tokio = { workspace = true, features = ["fs", "io-util", "rt", "sync"] } tokio-stream = { workspace = true } walkdir = "2.5.0" -[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "android", target_os = "macos"))'.dependencies] libc = { workspace = true } [target.'cfg(target_os = "windows")'.dependencies] diff --git a/fs_util/src/safe_move.rs b/fs_util/src/safe_move.rs index 321093d48..687e7394c 100644 --- a/fs_util/src/safe_move.rs +++ b/fs_util/src/safe_move.rs @@ -143,6 +143,39 @@ fn blocking_rename_no_replace_atomic(src: &Path, dst: &Path) -> io::Result<()> { } } +#[cfg(target_os = "macos")] +fn blocking_rename_no_replace_atomic(src: &Path, dst: &Path) -> io::Result<()> { + use std::ffi::CString; + + fn to_cstring(path: &Path) -> io::Result { + CString::new(path.as_os_str().as_encoded_bytes()) + .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error.to_string())) + } + + // Available since macOS 10.12; fails with EEXIST if dst already exists. + const RENAME_EXCL: u32 = 0x00000004; + + unsafe extern "C" { + fn renamex_np( + from: *const libc::c_char, + to: *const libc::c_char, + flags: u32, + ) -> libc::c_int; + } + + let src = to_cstring(src)?; + let dst = to_cstring(dst)?; + + // SAFETY: both pointers are valid null-terminated C strings for the duration of the call. + let result = unsafe { renamex_np(src.as_ptr(), dst.as_ptr(), RENAME_EXCL) }; + + if result == 0 { + Ok(()) + } else { + Err(io::Error::last_os_error()) + } +} + // Renames `src` to `dst` but fails if `dst` already exists. This is not atomic so it's possible // that the dst file might still get deleted if it's created concurrently with calling this // function. This is used only as a fallback on platforms/filesystems which don't support the diff --git a/logtee/rust/Cargo.toml b/logtee/rust/Cargo.toml index b58411b8c..6be5368be 100644 --- a/logtee/rust/Cargo.toml +++ b/logtee/rust/Cargo.toml @@ -16,7 +16,7 @@ crate-type = ["rlib", "cdylib"] file-rotate = "0.8.0" strip-ansi-escapes = "0.2.1" -[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "windows", target_os = "macos"))'.dependencies] filedescriptor = "0.8.3" [target.'cfg(target_os = "windows")'.dependencies] diff --git a/logtee/rust/src/lib.rs b/logtee/rust/src/lib.rs index 67fe6252b..8b6ce3ab9 100644 --- a/logtee/rust/src/lib.rs +++ b/logtee/rust/src/lib.rs @@ -1,4 +1,4 @@ -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(target_os = "linux", target_os = "windows", target_os = "macos"))] #[path = "redirect.rs"] mod inner; @@ -6,8 +6,6 @@ mod inner; #[path = "android.rs"] mod inner; -// TODO: ios and macos - #[cfg(test)] mod tests; diff --git a/utils/swarm/Cargo.toml b/utils/swarm/Cargo.toml index 7f49fb1b5..8d86c46bb 100644 --- a/utils/swarm/Cargo.toml +++ b/utils/swarm/Cargo.toml @@ -19,5 +19,5 @@ clap = { workspace = true } ctrlc = { workspace = true } os_pipe = "1.1.4" -[target.'cfg(any(target_os = "linux", target_os = "osx"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies] libc = "0.2.126"