Skip to content

Commit 0175152

Browse files
committed
libsql-ffi: Fix file copying on Windows
1 parent 7ab4d35 commit 0175152

1 file changed

Lines changed: 39 additions & 19 deletions

File tree

libsql-ffi/build.rs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ fn main() {
3333
}
3434

3535
let bindgen_rs_path = if cfg!(feature = "session") {
36-
"bundled/bindings/session_bindgen.rs"
36+
Path::new("bundled/bindings/session_bindgen.rs")
3737
} else {
38-
"bundled/bindings/bindgen.rs"
38+
Path::new("bundled/bindings/bindgen.rs")
3939
};
4040

4141
let dir = env!("CARGO_MANIFEST_DIR");
4242

4343
let full_src_path = Path::new(dir).join(bindgen_rs_path);
44-
copy_with_cp(full_src_path, &out_path).unwrap();
44+
platform_copy(full_src_path, &out_path).unwrap();
4545

4646
println!("cargo:lib_dir={out_dir}");
4747

@@ -75,7 +75,8 @@ fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()>
7575
/// This ensures that in sandboxed environments, such as Nix, permissions from other sources don't
7676
/// propagate into OUT_DIR. If not present, when trying to rewrite a file, a `Permission denied`
7777
/// error will occur.
78-
fn copy_with_cp(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
78+
#[cfg(unix)]
79+
fn platform_copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
7980
let status = Command::new("cp")
8081
.arg("--no-preserve=mode,ownership")
8182
.arg("-R")
@@ -94,6 +95,25 @@ fn copy_with_cp(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()>
9495
};
9596
}
9697

98+
#[cfg(windows)]
99+
fn platform_copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
100+
let from = from.as_ref();
101+
let to = to.as_ref();
102+
if let Some(parent) = to.parent() {
103+
fs::create_dir_all(parent)?;
104+
}
105+
if from.is_file() {
106+
fs::copy(from, to).map(|_| ())
107+
} else if from.is_dir() {
108+
copy_dir_all(from, to)
109+
} else {
110+
Err(io::Error::new(
111+
io::ErrorKind::InvalidInput,
112+
"Source path is neither a file nor a directory",
113+
))
114+
}
115+
}
116+
97117
fn make_amalgamation() {
98118
let flags = ["-DSQLITE_ENABLE_COLUMN_METADATA=1"];
99119

@@ -114,15 +134,15 @@ fn make_amalgamation() {
114134
.output()
115135
.unwrap();
116136

117-
copy_with_cp(
137+
platform_copy(
118138
(SQLITE_DIR.as_ref() as &Path).join("sqlite3.c"),
119-
(BUNDLED_DIR.as_ref() as &Path).join("src/sqlite3.c"),
139+
(BUNDLED_DIR.as_ref() as &Path).join("src").join("sqlite3.c"),
120140
)
121141
.unwrap();
122142

123-
copy_with_cp(
143+
platform_copy(
124144
(SQLITE_DIR.as_ref() as &Path).join("sqlite3.h"),
125-
(BUNDLED_DIR.as_ref() as &Path).join("src/sqlite3.h"),
145+
(BUNDLED_DIR.as_ref() as &Path).join("src").join("sqlite3.c"),
126146
)
127147
.unwrap();
128148
}
@@ -180,18 +200,18 @@ int core_init(const char* dummy) {
180200

181201
pub fn build_bundled(out_dir: &str, out_path: &Path) {
182202
let bindgen_rs_path = if cfg!(feature = "session") {
183-
"bundled/bindings/session_bindgen.rs"
203+
Path::new("bundled/bindings/session_bindgen.rs")
184204
} else {
185-
"bundled/bindings/bindgen.rs"
205+
Path::new("bundled/bindings/bindgen.rs")
186206
};
187207

188208
if std::env::var("LIBSQL_DEV").is_ok() {
189209
let header = HeaderLocation::FromPath(format!("{BUNDLED_DIR}/src/sqlite3.h"));
190210
bindings::write_to_out_dir(header, bindgen_rs_path.as_ref());
191211
}
192212

193-
let dir = env!("CARGO_MANIFEST_DIR");
194-
copy_with_cp(format!("{dir}/{bindgen_rs_path}"), out_path).unwrap();
213+
let dir = Path::new(env!("CARGO_MANIFEST_DIR"));
214+
platform_copy(dir.join(bindgen_rs_path), out_path).unwrap();
195215

196216
let mut cfg = cc::Build::new();
197217
cfg.flag("-std=c11")
@@ -409,35 +429,35 @@ fn copy_multiple_ciphers(target: &str, out_dir: &str, out_path: &Path) {
409429
build_multiple_ciphers(target, out_path);
410430
}
411431

412-
copy_with_cp(dylib, format!("{out_dir}/libsqlite3mc.a")).unwrap();
432+
platform_copy(dylib, format!("{out_dir}/libsqlite3mc.a")).unwrap();
413433
println!("cargo:rustc-link-lib=static=sqlite3mc");
414434
println!("cargo:rustc-link-search={out_dir}");
415435
}
416436

417437
fn build_multiple_ciphers(target: &str, out_path: &Path) {
418438
let bindgen_rs_path = if cfg!(feature = "session") {
419-
"bundled/bindings/session_bindgen.rs"
439+
Path::new("bundled/bindings/session_bindgen.rs")
420440
} else {
421-
"bundled/bindings/bindgen.rs"
441+
Path::new("bundled/bindings/bindgen.rs")
422442
};
423443

424444
if std::env::var("LIBSQL_DEV").is_ok() {
425445
let header = HeaderLocation::FromPath(format!("{BUNDLED_DIR}/src/sqlite3.h"));
426446
bindings::write_to_out_dir(header, bindgen_rs_path.as_ref());
427447
}
428448

429-
let dir = env!("CARGO_MANIFEST_DIR");
430-
copy_with_cp(format!("{dir}/{bindgen_rs_path}"), out_path).unwrap();
449+
let dir = Path::new(env!("CARGO_MANIFEST_DIR"));
450+
platform_copy(dir.join(bindgen_rs_path), out_path).unwrap();
431451

432452
let out_dir = env::var("OUT_DIR").unwrap();
433453

434-
copy_with_cp(
454+
platform_copy(
435455
dbg!(format!("{BUNDLED_DIR}/SQLite3MultipleCiphers")),
436456
format!("{out_dir}/sqlite3mc"),
437457
)
438458
.unwrap();
439459

440-
copy_with_cp(
460+
platform_copy(
441461
PathBuf::from(BUNDLED_DIR).join("src").join("sqlite3.c"),
442462
format!("{out_dir}/sqlite3mc/src/sqlite3.c"),
443463
)

0 commit comments

Comments
 (0)