Skip to content

Commit

Permalink
Fix sqlite3mc build (#1024)
Browse files Browse the repository at this point in the history
* libsql-ffi: Enable PIC for sqlite3mc build

I am seeing the following build error when building the libsql-ffi crate
on Linux/x86-64:

```
/usr/bin/ld:
/tmp/rustcYVhHYo/liblibsql_ffi-20adf4ca11d8e922.rlib(sqlite3mc.c.o):
relocation R_X86_64_32S against `.rodata' can not be used when making a
shared object; recompile with -fPIC
```

Let's turn on PIC for sqlite3mc to fix the problem.

* libsql-ffi: Fix sqlite3mc build under `cross`

We need to use the C compiler configured by `cross` with sqlite3mc;
otherwise we end up building with the host compiler, resulting in errors
like this:

```
  = note: /usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: /tmp/rustcJ70WRo/liblibsql_ffi-5d7e6e8037dbda37.rlib(sqlite3mc.c.o): Relocations in generic ELF (EM: 62)
```

* libsql-ffi: Rewrite build_libsqlite3mc.sh in Rust

The bash shell script is turning out to be painful to run on Windows so
let's just rewrite the logic in Rust and place it in `build.rs`.
  • Loading branch information
penberg authored Feb 14, 2024
1 parent 63a7077 commit 86172b5
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 21 deletions.
93 changes: 85 additions & 8 deletions libsql-ffi/build.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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<OsString> {
Expand Down
13 changes: 0 additions & 13 deletions libsql-ffi/bundled/build_libsqlite3mc.sh

This file was deleted.

0 comments on commit 86172b5

Please sign in to comment.