Skip to content

Commit affce70

Browse files
YumeYukaShIroRRen
andauthored
stdbuf: support cross-platform building (#11609)
This PR fixes e.g. building Android targets on Windows. Because `build.rs` uses `#[cfg]` to determine, the suffix of the platform to be built cannot be correctly determined during cross-platform building. After changing from `#[cfg]` to `env::var`, `feat_os_unix_android`, which includes `stdbuf`, can be compiled normally. There is no actual test for other cross-platform compilation scenarios, but in theory it can be used normally. Co-authored-by: 白彩恋 <169267914+shirorren@users.noreply.github.com>
1 parent 56210f1 commit affce70

File tree

1 file changed

+23
-29
lines changed

1 file changed

+23
-29
lines changed

src/uu/stdbuf/build.rs

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,6 @@ use std::fs;
99
use std::path::Path;
1010
use std::process::Command;
1111

12-
#[cfg(any(
13-
target_os = "linux",
14-
target_os = "android",
15-
target_os = "freebsd",
16-
target_os = "netbsd",
17-
target_os = "openbsd",
18-
target_os = "dragonfly"
19-
))]
20-
mod platform {
21-
pub const DYLIB_EXT: &str = ".so";
22-
}
23-
24-
#[cfg(target_vendor = "apple")]
25-
mod platform {
26-
pub const DYLIB_EXT: &str = ".dylib";
27-
}
28-
29-
#[cfg(target_os = "cygwin")]
30-
mod platform {
31-
pub const DYLIB_EXT: &str = ".dll";
32-
}
33-
3412
fn main() {
3513
println!("cargo:rerun-if-changed=build.rs");
3614
println!("cargo:rerun-if-changed=src/libstdbuf/src/libstdbuf.rs");
@@ -58,14 +36,29 @@ fn main() {
5836
let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set");
5937
let target = env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
6038

39+
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
40+
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
41+
let target_family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
42+
43+
if target_family != "unix" {
44+
return;
45+
}
46+
let dylib_ext = if target_vendor == "apple" {
47+
".dylib"
48+
} else if target_os == "cygwin" {
49+
".dll"
50+
} else {
51+
".so"
52+
};
53+
6154
// Check if we're building from the repository (where src/libstdbuf exists)
6255
// or from crates.io (where it doesn't)
6356
let libstdbuf_src = Path::new("src/libstdbuf");
6457
if !libstdbuf_src.exists() {
6558
// When building from crates.io, libstdbuf is already available as a dependency
6659
// We can't build it here, so we'll need to handle this differently
6760
// For now, we'll create a dummy library file to satisfy the include_bytes! macro
68-
let lib_name = format!("libstdbuf{}", platform::DYLIB_EXT);
61+
let lib_name = format!("libstdbuf{dylib_ext}");
6962
let dest_path = Path::new(&out_dir).join(&lib_name);
7063

7164
// Create an empty file as a placeholder
@@ -108,11 +101,12 @@ fn main() {
108101
assert!(status.success(), "Failed to build libstdbuf");
109102

110103
// Copy the built library to OUT_DIR for include_bytes! to find
111-
#[cfg(target_os = "cygwin")]
112-
let lib_name = format!("stdbuf{}", platform::DYLIB_EXT);
113-
#[cfg(not(target_os = "cygwin"))]
114-
let lib_name = format!("libstdbuf{}", platform::DYLIB_EXT);
115-
let dest_path = Path::new(&out_dir).join(format!("libstdbuf{}", platform::DYLIB_EXT));
104+
let lib_name = if target_os == "cygwin" {
105+
format!("stdbuf{dylib_ext}")
106+
} else {
107+
format!("libstdbuf{dylib_ext}")
108+
};
109+
let dest_path = Path::new(&out_dir).join(format!("libstdbuf{dylib_ext}"));
116110

117111
// Check multiple possible locations for the built library
118112
let possible_paths = if !target.is_empty() && target != "unknown" {
@@ -162,7 +156,7 @@ fn main() {
162156
.and_then(|p| p.parent())
163157
.and_then(|p| p.parent())
164158
{
165-
let lib_filename = format!("libstdbuf{}", platform::DYLIB_EXT);
159+
let lib_filename = format!("libstdbuf{dylib_ext}");
166160
let source = target_dir.join("deps").join(&lib_filename);
167161
let dest = target_dir.join(&lib_filename);
168162

0 commit comments

Comments
 (0)