diff --git a/libsql-ffi/build.rs b/libsql-ffi/build.rs index 32a9a3e47e..c1bd0d2c5b 100644 --- a/libsql-ffi/build.rs +++ b/libsql-ffi/build.rs @@ -1,5 +1,7 @@ use std::env; use std::ffi::OsString; +use std::fs::{self, OpenOptions}; +use std::io::Write; use std::path::{Path, PathBuf}; use std::process::Command; @@ -280,20 +282,95 @@ fn build_multiple_ciphers(out_path: &Path) { ) .unwrap(); - let mut cmd = Command::new("./build_libsqlite3mc.sh"); - cmd.current_dir(BUNDLED_DIR); + let bundled_dir = fs::canonicalize(BUNDLED_DIR).unwrap(); - if cfg!(feature = "wasmtime-bindings") { - cmd.arg("-DLIBSQL_ENABLE_WASM_RUNTIME=1"); + let mut cmd = Command::new("git"); + cmd.args(&["submodule", "update", "--init", "SQLite3MultipleCiphers"]); + cmd.current_dir(bundled_dir.clone()); + // The submodule is there only for development builds, but the + // command is expected to fail when libsql is fetched via cargo. + cmd.status().unwrap(); + + let build_dir = bundled_dir.join("SQLite3MultipleCiphers").join("build"); + let _ = fs::remove_dir_all(build_dir.clone()); + fs::create_dir_all(build_dir.clone()).unwrap(); + + let mut cmake_opts: Vec<&str> = vec![]; + + let cargo_build_target = env::var("CARGO_BUILD_TARGET").unwrap_or_default(); + let cross_cc_var_name = format!("CC_{}", cargo_build_target.replace("-", "_")); + let cross_cc = env::var(&cross_cc_var_name).ok(); + + let cross_cxx_var_name = format!("CXX_{}", cargo_build_target.replace("-", "_")); + let cross_cxx = env::var(&cross_cxx_var_name).ok(); + + let toolchain_path = build_dir.join("toolchain.cmake"); + let cmake_toolchain_opt = format!("-DCMAKE_TOOLCHAIN_FILE=toolchain.cmake"); + + let mut toolchain_file = OpenOptions::new() + .create(true) + .write(true) + .append(true) + .open(toolchain_path.clone()) + .unwrap(); + + if let Some(ref cc) = cross_cc { + if cc.contains("aarch64") && cc.contains("linux") { + cmake_opts.push(&cmake_toolchain_opt); + writeln!(toolchain_file, "set(CMAKE_SYSTEM_NAME \"Linux\")").unwrap(); + writeln!(toolchain_file, "set(CMAKE_SYSTEM_PROCESSOR \"arm64\")").unwrap(); + } + } + if let Some(cc) = cross_cc { + 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"); + + let mut cmake = Command::new("cmake"); + cmake.current_dir("bundled/SQLite3MultipleCiphers/build"); + cmake.args(cmake_opts.clone()); + cmake.arg(".."); + if cfg!(feature = "wasmtime-bindings") { + cmake.arg("-DLIBSQL_ENABLE_WASM_RUNTIME=1"); + } if cfg!(feature = "session") { - cmd.arg("-DSQLITE_ENABLE_PREUPDATE_HOOK=ON"); - cmd.arg("-DSQLITE_ENABLE_SESSION=ON"); + 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 out = cmd.output().unwrap(); - assert!(out.status.success(), "{:?}", out); + let mut make = Command::new("cmake"); + make.current_dir("bundled/SQLite3MultipleCiphers/build"); + 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(&build_dir.join("Release/sqlite3mc_static.lib")) { + fs::rename( + build_dir.join("Release/sqlite3mc_static.lib"), + build_dir.join("libsqlite3mc_static.a"), + ) + .unwrap(); + } } fn env(name: &str) -> Option { diff --git a/libsql-ffi/bundled/build_libsqlite3mc.sh b/libsql-ffi/bundled/build_libsqlite3mc.sh deleted file mode 100755 index b04089e6cb..0000000000 --- a/libsql-ffi/bundled/build_libsqlite3mc.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -set -x - -git submodule update --init SQLite3MultipleCiphers -mkdir -p SQLite3MultipleCiphers/build -cd SQLite3MultipleCiphers/build -cmake .. -DCMAKE_BUILD_TYPE=Release -DSQLITE3MC_STATIC=ON \ - -DCODEC_TYPE=AES256 -DSQLITE3MC_BUILD_SHELL=OFF \ - -DSQLITE_SHELL_IS_UTF8=OFF -DSQLITE_USER_AUTHENTICATION=OFF \ - -DSQLITE_SECURE_DELETE=OFF -DSQLITE_ENABLE_COLUMN_METADATA=ON \ - -DSQLITE_USE_URI=ON $@ -make -j12