Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Depend on libsqlite3-sys for bundled builds #190

Merged
merged 5 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions proj-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ links = "proj"
rust-version = "1.70"

[dependencies]
libsqlite3-sys = "0.28"
link-cplusplus = "1.0"

[build-dependencies]
bindgen = "0.68.1"
Expand Down
27 changes: 15 additions & 12 deletions proj-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// returns the path of "include" for the built proj
fn build_from_source() -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
eprintln!("building libproj from source");
println!("cargo:rustc-cfg=bundled_build");
if let Ok(val) = &env::var("_PROJ_SYS_TEST_EXPECT_BUILD_FROM_SRC") {
if val == "0" {
panic!(
Expand All @@ -80,7 +81,6 @@ fn build_from_source() -> Result<std::path::PathBuf, Box<dyn std::error::Error>>
}
}

// NOTE: The PROJ build expects Sqlite3 to be present on the system.
let path = "PROJSRC/proj-9.4.0.tar.gz";
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let tar_gz = File::open(path)?;
Expand All @@ -99,6 +99,20 @@ fn build_from_source() -> Result<std::path::PathBuf, Box<dyn std::error::Error>>
config.define("BUILD_PROJSYNC", "OFF");
config.define("ENABLE_CURL", "OFF");

// we check here whether or not these variables are set by cargo
// if they are set, `libsqlite3-sys` was built with the bundled feature
// enabled, which in turn allows us to rely on the built libsqlite3 version
// and link it statically
//
// If these are not set, it's necessary that libsqlite3 exists on the build system
// in a location accessible by cmake
if let Ok(sqlite_include) = std::env::var("DEP_SQLITE3_INCLUDE") {
config.define("SQLITE3_INCLUDE_DIR", sqlite_include);
}
if let Ok(sqlite_lib_dir) = std::env::var("DEP_SQLITE3_LIB_DIR") {
config.define("SQLITE3_LIBRARY", format!("{sqlite_lib_dir}/libsqlite3.a",));
}

if cfg!(feature = "tiff") {
eprintln!("enabling tiff support");
config.define("ENABLE_TIFF", "ON");
Expand Down Expand Up @@ -132,9 +146,6 @@ fn build_from_source() -> Result<std::path::PathBuf, Box<dyn std::error::Error>>
&out_path.join("build/lib").display()
);

// The PROJ library needs SQLite and the C++ standard library.
println!("cargo:rustc-link-lib=dylib=sqlite3");

if cfg!(feature = "tiff") {
// On platforms like apples aarch64, users are likely to have installed libtiff with homebrew,
// which isn't in the default search path, so try to determine path from pkg-config
Expand All @@ -159,13 +170,5 @@ fn build_from_source() -> Result<std::path::PathBuf, Box<dyn std::error::Error>>
println!("cargo:rustc-link-lib=dylib=tiff");
}

if cfg!(target_os = "linux") {
println!("cargo:rustc-link-lib=dylib=stdc++");
} else if cfg!(target_os = "macos") {
println!("cargo:rustc-link-lib=dylib=c++");
} else {
println!("cargo:warning=proj-sys: Not configuring an explicit C++ standard library on this target.");
}

Ok(proj.join("include"))
}
5 changes: 5 additions & 0 deletions proj-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
//! implement your own set of callbacks if you wish to make use of them (see the
//! [`proj`](https://crates.io/crates/proj) crate for an example).

#[cfg(bundled_build)]
extern crate libsqlite3_sys;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need these extern crate declarations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rustc only links crates that are explictly used somewhere, either by actually use items from that crate or by having an explicit extern crate … statement somewhere. So this essentially ensures that we actually link libsqlite3 (the c library) for the bundled build case. We set the cfg flag from the build script if we actually build libproj from source and statically link it. Only then we need to also link libsqlite3.

#[cfg(bundled_build)]
extern crate link_cplusplus;

#[cfg(not(feature = "nobuild"))]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

Expand Down