diff --git a/Cargo.lock b/Cargo.lock index 6a26af7576..63466c0d8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1282,6 +1282,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.1" @@ -2960,6 +2969,7 @@ version = "0.9.9" dependencies = [ "bindgen", "cc", + "cmake", "glob", "libsql-wasmtime-bindings", ] diff --git a/libsql-ffi/Cargo.toml b/libsql-ffi/Cargo.toml index eff5ef288d..f769cacf1c 100644 --- a/libsql-ffi/Cargo.toml +++ b/libsql-ffi/Cargo.toml @@ -18,6 +18,7 @@ exclude = [ libsql-wasmtime-bindings = { version = "0.2.1", optional = true } [build-dependencies] +cmake = "0.1.54" bindgen = "0.66.1" cc = "1.0" glob = "0.3" diff --git a/libsql-ffi/build.rs b/libsql-ffi/build.rs index 3de70f5e66..8cd32fa9ea 100644 --- a/libsql-ffi/build.rs +++ b/libsql-ffi/build.rs @@ -1,8 +1,8 @@ use glob::glob; use std::env; use std::ffi::OsString; -use std::fs::{self, OpenOptions}; -use std::io::{self, Write}; +use std::fs; +use std::io; use std::path::{Path, PathBuf}; use std::process::Command; @@ -29,7 +29,7 @@ fn main() { if std::env::var("LIBSQL_DEV").is_ok() { make_amalgamation(); - build_multiple_ciphers(&target, &out_path); + build_multiple_ciphers(&out_path); } let bindgen_rs_path = if cfg!(feature = "session") { @@ -50,7 +50,7 @@ fn main() { } if cfg!(feature = "multiple-ciphers") { - copy_multiple_ciphers(&target, &out_dir, &out_path); + copy_multiple_ciphers(&out_path); return; } @@ -409,18 +409,22 @@ pub fn build_bundled(out_dir: &str, out_path: &Path) { println!("cargo:lib_dir={out_dir}"); } -fn copy_multiple_ciphers(target: &str, out_dir: &str, out_path: &Path) { - let dylib = format!("{out_dir}/sqlite3mc/libsqlite3mc_static.a"); - if !Path::new(&dylib).exists() { - build_multiple_ciphers(target, out_path); - } +fn copy_multiple_ciphers(out_path: &Path) { + let dst = dbg!(build_multiple_ciphers(out_path)); - copy_with_cp(dylib, format!("{out_dir}/libsqlite3mc.a")).unwrap(); - println!("cargo:rustc-link-lib=static=sqlite3mc"); - println!("cargo:rustc-link-search={out_dir}"); + println!("cargo:rustc-link-search={}", dst.join("build").display()); + println!( + "cargo:rustc-link-search={}", + dst.join("build").join("Release").display() + ); + println!( + "cargo:rustc-link-search={}", + dst.join("build").join("Debug").display() + ); + println!("cargo:rustc-link-lib=static=sqlite3mc_static"); } -fn build_multiple_ciphers(target: &str, out_path: &Path) { +fn build_multiple_ciphers(out_path: &Path) -> PathBuf { let bindgen_rs_path = if cfg!(feature = "session") { "bundled/bindings/session_bindgen.rs" } else { @@ -450,112 +454,33 @@ fn build_multiple_ciphers(target: &str, out_path: &Path) { .unwrap(); let bundled_dir = format!("{out_dir}/sqlite3mc"); - let sqlite3mc_build_dir = env::current_dir().unwrap().join(out_dir).join("sqlite3mc"); - - let mut cmake_opts: Vec<&str> = vec![]; - let target_postfix = target.to_string().replace("-", "_"); - let cross_cc_var_name = format!("CC_{}", target_postfix); - println!("cargo:warning=CC_var_name={}", cross_cc_var_name); - let cross_cc = env::var(&cross_cc_var_name).ok(); + let mut config = cmake::Config::new(&bundled_dir); + + config + .build_target("sqlite3mc_static") + .define("SQLITE3MC_STATIC", "ON") + .define("CODEC_TYPE", "AES256") + .define("SQLITE3MC_BUILD_SHELL", "OFF") + .define("SQLITE_SHELL_IS_UTF8", "OFF") + .define("SQLITE_USER_AUTHENTICATION", "OFF") + .define("SQLITE_SECURE_DELETE", "OFF") + .define("SQLITE_ENABLE_COLUMN_METADATA", "ON") + .define("SQLITE_USE_URI", "ON") + .define("CMAKE_POSITION_INDEPENDENT_CODE", "ON") + .profile("Release"); - let cross_cxx_var_name = format!("CXX_{}", target_postfix); - let cross_cxx = env::var(&cross_cxx_var_name).ok(); - - let toolchain_path = sqlite3mc_build_dir.join("toolchain.cmake"); - let cmake_toolchain_opt = "-DCMAKE_TOOLCHAIN_FILE=toolchain.cmake".to_string(); - - let mut toolchain_file = OpenOptions::new() - .create(true) - .write(true) - .append(true) - .open(toolchain_path.clone()) - .unwrap(); - - if let Some(ref cc) = cross_cc { - let system_name = if cc.contains("linux") { - "Linux" - } else if cc.contains("darwin") { - "Darwin" - } else if cc.contains("w64") { - "Windows" - } else { - panic!("Unsupported cross target {}", cc) - }; - - let system_processor = if cc.contains("x86_64") { - "x86_64" - } else if cc.contains("aarch64") { - "arm64" - } else if cc.contains("arm") { - "arm" - } else { - panic!("Unsupported cross target {}", cc) - }; - - cmake_opts.push(&cmake_toolchain_opt); - writeln!(toolchain_file, "set(CMAKE_SYSTEM_NAME \"{}\")", system_name).unwrap(); - writeln!( - toolchain_file, - "set(CMAKE_SYSTEM_PROCESSOR \"{}\")", - system_processor - ) - .unwrap(); - writeln!(toolchain_file, "set(CMAKE_C_COMPILER {})", cc).unwrap(); - } - - if let Some(cxx) = cross_cxx { - writeln!(toolchain_file, "set(CMAKE_CXX_COMPILER {})", cxx).unwrap(); - } - - cmake_opts.push("-DCMAKE_BUILD_TYPE=Release"); - cmake_opts.push("-DSQLITE3MC_STATIC=ON"); - cmake_opts.push("-DCODEC_TYPE=AES256"); - cmake_opts.push("-DSQLITE3MC_BUILD_SHELL=OFF"); - cmake_opts.push("-DSQLITE_SHELL_IS_UTF8=OFF"); - cmake_opts.push("-DSQLITE_USER_AUTHENTICATION=OFF"); - cmake_opts.push("-DSQLITE_SECURE_DELETE=OFF"); - cmake_opts.push("-DSQLITE_ENABLE_COLUMN_METADATA=ON"); - cmake_opts.push("-DSQLITE_USE_URI=ON"); - cmake_opts.push("-DCMAKE_POSITION_INDEPENDENT_CODE=ON"); - - if target.contains("musl") { - cmake_opts.push("-DCMAKE_C_FLAGS=\"-U_FORTIFY_SOURCE\" -D_FILE_OFFSET_BITS=32"); - cmake_opts.push("-DCMAKE_CXX_FLAGS=\"-U_FORTIFY_SOURCE\" -D_FILE_OFFSET_BITS=32"); - } - - let mut cmake = Command::new("cmake"); - cmake.current_dir(sqlite3mc_build_dir.clone()); - cmake.args(cmake_opts.clone()); - cmake.arg(bundled_dir.clone()); if cfg!(feature = "wasmtime-bindings") { - cmake.arg("-DLIBSQL_ENABLE_WASM_RUNTIME=1"); + config.define("LIBSQL_ENABLE_WASM_RUNTIME", "1"); } + if cfg!(feature = "session") { - cmake.arg("-DSQLITE_ENABLE_PREUPDATE_HOOK=ON"); - cmake.arg("-DSQLITE_ENABLE_SESSION=ON"); - } - println!("Running `cmake` with options: {}", cmake_opts.join(" ")); - let status = cmake.status().unwrap(); - if !status.success() { - panic!("Failed to run cmake with options: {}", cmake_opts.join(" ")); - } - - let mut make = Command::new("cmake"); - make.current_dir(sqlite3mc_build_dir.clone()); - make.args(["--build", "."]); - make.args(["--config", "Release"]); - if !make.status().unwrap().success() { - panic!("Failed to run make"); - } - // The `msbuild` tool puts the output in a different place so let's move it. - if Path::exists(&sqlite3mc_build_dir.join("Release/sqlite3mc_static.lib")) { - fs::rename( - sqlite3mc_build_dir.join("Release/sqlite3mc_static.lib"), - sqlite3mc_build_dir.join("libsqlite3mc_static.a"), - ) - .unwrap(); + config + .define("SQLITE_ENABLE_PREUPDATE_HOOK", "ON") + .define("SQLITE_ENABLE_SESSION", "ON"); } + + config.build() } fn env(name: &str) -> Option {