@@ -57,47 +57,41 @@ fn main() {
5757 build_bundled ( & out_dir, & out_path) ;
5858}
5959
60- #[ cfg( target_os = "windows" ) ]
61- fn copy_with_cp ( src : impl AsRef < Path > , dst : impl AsRef < Path > ) -> io:: Result < ( ) > {
62- fs:: copy ( src, dst) ?; // do a regular file copy on Windows
60+ fn copy_dir_all ( src : impl AsRef < Path > , dst : impl AsRef < Path > ) -> io:: Result < ( ) > {
61+ let dst = dst. as_ref ( ) ;
62+ fs:: create_dir_all ( dst) ?;
63+ for entry in fs:: read_dir ( src) ? {
64+ let entry = entry?;
65+ let ty = entry. file_type ( ) ?;
66+ if ty. is_dir ( ) {
67+ copy_dir_all ( entry. path ( ) , dst. join ( entry. file_name ( ) ) ) ?;
68+ } else {
69+ fs:: copy ( entry. path ( ) , dst. join ( entry. file_name ( ) ) ) ?;
70+ }
71+ }
6372 Ok ( ( ) )
6473}
6574
66- #[ cfg( target_os = "linux" ) ]
67- fn copy_with_cp ( src : impl AsRef < Path > , dst : impl AsRef < Path > ) -> io:: Result < ( ) > {
75+ /// This ensures that in sandboxed environments, such as Nix, permissions from other sources don't
76+ /// propagate into OUT_DIR. If not present, when trying to rewrite a file, a `Permission denied`
77+ /// error will occur.
78+ fn copy_with_cp ( from : impl AsRef < Path > , to : impl AsRef < Path > ) -> io:: Result < ( ) > {
6879 let status = Command :: new ( "cp" )
6980 . arg ( "--no-preserve=mode,ownership" )
7081 . arg ( "-R" )
71- . arg ( src . as_ref ( ) . to_str ( ) . unwrap ( ) )
72- . arg ( dst . as_ref ( ) . to_str ( ) . unwrap ( ) )
82+ . arg ( from . as_ref ( ) . to_str ( ) . unwrap ( ) )
83+ . arg ( to . as_ref ( ) . to_str ( ) . unwrap ( ) )
7384 . status ( ) ?;
7485
75- if !status. success ( ) {
76- Err ( io:: Error :: new (
77- io:: ErrorKind :: Other ,
78- "Failed to copy using cp" ,
79- ) )
80- } else {
81- Ok ( ( ) )
86+ if status. success ( ) {
87+ return Ok ( ( ) ) ;
8288 }
83- }
84-
85- #[ cfg( target_os = "macos" ) ]
86- fn copy_with_cp ( src : impl AsRef < Path > , dst : impl AsRef < Path > ) -> io:: Result < ( ) > {
87- let status = Command :: new ( "cp" )
88- . arg ( "-R" )
89- . arg ( src. as_ref ( ) . to_str ( ) . unwrap ( ) )
90- . arg ( dst. as_ref ( ) . to_str ( ) . unwrap ( ) )
91- . status ( ) ?;
9289
93- if !status. success ( ) {
94- Err ( io:: Error :: new (
95- io:: ErrorKind :: Other ,
96- "Failed to copy using cp" ,
97- ) )
98- } else {
99- Ok ( ( ) )
100- }
90+ return match fs:: copy ( from. as_ref ( ) , to. as_ref ( ) ) {
91+ Err ( err) if err. kind ( ) == io:: ErrorKind :: InvalidInput => copy_dir_all ( from, to) ,
92+ Ok ( _) => Ok ( ( ) ) ,
93+ Err ( err) => Err ( err) ,
94+ } ;
10195}
10296
10397fn make_amalgamation ( ) {
@@ -114,17 +108,19 @@ fn make_amalgamation() {
114108 . env ( "CFLAGS" , flags. join ( " " ) )
115109 . output ( )
116110 . unwrap ( ) ;
111+
117112 Command :: new ( "make" )
118113 . current_dir ( SQLITE_DIR )
119114 . output ( )
120115 . unwrap ( ) ;
121116
122- std :: fs :: copy (
117+ copy_with_cp (
123118 ( SQLITE_DIR . as_ref ( ) as & Path ) . join ( "sqlite3.c" ) ,
124119 ( BUNDLED_DIR . as_ref ( ) as & Path ) . join ( "src/sqlite3.c" ) ,
125120 )
126121 . unwrap ( ) ;
127- std:: fs:: copy (
122+
123+ copy_with_cp (
128124 ( SQLITE_DIR . as_ref ( ) as & Path ) . join ( "sqlite3.h" ) ,
129125 ( BUNDLED_DIR . as_ref ( ) as & Path ) . join ( "src/sqlite3.h" ) ,
130126 )
@@ -195,7 +191,7 @@ pub fn build_bundled(out_dir: &str, out_path: &Path) {
195191 }
196192
197193 let dir = env ! ( "CARGO_MANIFEST_DIR" ) ;
198- std :: fs :: copy ( format ! ( "{dir}/{bindgen_rs_path}" ) , out_path) . unwrap ( ) ;
194+ copy_with_cp ( format ! ( "{dir}/{bindgen_rs_path}" ) , out_path) . unwrap ( ) ;
199195
200196 let mut cfg = cc:: Build :: new ( ) ;
201197 cfg. flag ( "-std=c11" )
@@ -267,9 +263,7 @@ pub fn build_bundled(out_dir: &str, out_path: &Path) {
267263
268264 cfg. files ( sqlean_sources) ;
269265
270- let sqlean = Path :: new ( BUNDLED_DIR )
271- . join ( "src" )
272- . join ( "sqlite3-sqlean-generated.c" ) ;
266+ let sqlean = Path :: new ( & env:: var ( "OUT_DIR" ) . unwrap ( ) ) . join ( "sqlite3-sqlean-generated.c" ) ;
273267 generate_sqlean ( & enabled_extensions, & sqlean) . unwrap ( ) ;
274268 cfg. file ( & sqlean) ;
275269
@@ -415,7 +409,7 @@ fn copy_multiple_ciphers(target: &str, out_dir: &str, out_path: &Path) {
415409 build_multiple_ciphers ( target, out_path) ;
416410 }
417411
418- std :: fs :: copy ( dylib, format ! ( "{out_dir}/libsqlite3mc.a" ) ) . unwrap ( ) ;
412+ copy_with_cp ( dylib, format ! ( "{out_dir}/libsqlite3mc.a" ) ) . unwrap ( ) ;
419413 println ! ( "cargo:rustc-link-lib=static=sqlite3mc" ) ;
420414 println ! ( "cargo:rustc-link-search={out_dir}" ) ;
421415}
@@ -426,32 +420,31 @@ fn build_multiple_ciphers(target: &str, out_path: &Path) {
426420 } else {
427421 "bundled/bindings/bindgen.rs"
428422 } ;
423+
429424 if std:: env:: var ( "LIBSQL_DEV" ) . is_ok ( ) {
430425 let header = HeaderLocation :: FromPath ( format ! ( "{BUNDLED_DIR}/src/sqlite3.h" ) ) ;
431426 bindings:: write_to_out_dir ( header, bindgen_rs_path. as_ref ( ) ) ;
432427 }
428+
433429 let dir = env ! ( "CARGO_MANIFEST_DIR" ) ;
434- std:: fs:: copy ( format ! ( "{dir}/{bindgen_rs_path}" ) , out_path) . unwrap ( ) ;
435-
436- std:: fs:: copy (
437- ( BUNDLED_DIR . as_ref ( ) as & Path )
438- . join ( "src" )
439- . join ( "sqlite3.c" ) ,
440- ( BUNDLED_DIR . as_ref ( ) as & Path )
441- . join ( "SQLite3MultipleCiphers" )
442- . join ( "src" )
443- . join ( "sqlite3.c" ) ,
430+ copy_with_cp ( format ! ( "{dir}/{bindgen_rs_path}" ) , out_path) . unwrap ( ) ;
431+
432+ let out_dir = env:: var ( "OUT_DIR" ) . unwrap ( ) ;
433+
434+ copy_with_cp (
435+ dbg ! ( format!( "{BUNDLED_DIR}/SQLite3MultipleCiphers" ) ) ,
436+ format ! ( "{out_dir}/sqlite3mc" ) ,
444437 )
445438 . unwrap ( ) ;
446439
447- let bundled_dir = env:: current_dir ( )
448- . unwrap ( )
449- . join ( BUNDLED_DIR )
450- . join ( "SQLite3MultipleCiphers" ) ;
451- let out_dir = env:: var ( "OUT_DIR" ) . unwrap ( ) ;
440+ copy_with_cp (
441+ PathBuf :: from ( BUNDLED_DIR ) . join ( "src" ) . join ( "sqlite3.c" ) ,
442+ format ! ( "{out_dir}/sqlite3mc/src/sqlite3.c" ) ,
443+ )
444+ . unwrap ( ) ;
445+
446+ let bundled_dir = format ! ( "{out_dir}/sqlite3mc" ) ;
452447 let sqlite3mc_build_dir = env:: current_dir ( ) . unwrap ( ) . join ( out_dir) . join ( "sqlite3mc" ) ;
453- let _ = fs:: remove_dir_all ( sqlite3mc_build_dir. clone ( ) ) ;
454- fs:: create_dir_all ( sqlite3mc_build_dir. clone ( ) ) . unwrap ( ) ;
455448
456449 let mut cmake_opts: Vec < & str > = vec ! [ ] ;
457450
@@ -474,15 +467,35 @@ fn build_multiple_ciphers(target: &str, out_path: &Path) {
474467 . unwrap ( ) ;
475468
476469 if let Some ( ref cc) = cross_cc {
477- if cc. contains ( "aarch64" ) && cc. contains ( "linux" ) {
478- cmake_opts. push ( & cmake_toolchain_opt) ;
479- writeln ! ( toolchain_file, "set(CMAKE_SYSTEM_NAME \" Linux\" )" ) . unwrap ( ) ;
480- writeln ! ( toolchain_file, "set(CMAKE_SYSTEM_PROCESSOR \" arm64\" )" ) . unwrap ( ) ;
481- }
482- }
483- if let Some ( cc) = cross_cc {
470+ let system_name = if cc. contains ( "linux" ) {
471+ "Linux"
472+ } else if cc. contains ( "darwin" ) {
473+ "Darwin"
474+ } else if cc. contains ( "w64" ) {
475+ "Windows"
476+ } else {
477+ panic ! ( "Unsupported cross target {}" , cc)
478+ } ;
479+
480+ let system_processor = if cc. contains ( "x86_64" ) {
481+ "x86_64"
482+ } else if cc. contains ( "aarch64" ) {
483+ "arm64"
484+ } else {
485+ panic ! ( "Unsupported cross target {}" , cc)
486+ } ;
487+
488+ cmake_opts. push ( & cmake_toolchain_opt) ;
489+ writeln ! ( toolchain_file, "set(CMAKE_SYSTEM_NAME \" {}\" )" , system_name) . unwrap ( ) ;
490+ writeln ! (
491+ toolchain_file,
492+ "set(CMAKE_SYSTEM_PROCESSOR \" {}\" )" ,
493+ system_processor
494+ )
495+ . unwrap ( ) ;
484496 writeln ! ( toolchain_file, "set(CMAKE_C_COMPILER {})" , cc) . unwrap ( ) ;
485497 }
498+
486499 if let Some ( cxx) = cross_cxx {
487500 writeln ! ( toolchain_file, "set(CMAKE_CXX_COMPILER {})" , cxx) . unwrap ( ) ;
488501 }
0 commit comments