From 389dab49bdd5889d36e4c34e5c9c22951fef492a Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Sat, 23 Nov 2024 01:21:13 +0100 Subject: [PATCH] Static build --- .gitmodules | 3 ++ Cargo.lock | 45 +++++++++++++++--- Cargo.toml | 4 +- raugeas/Cargo.toml | 4 ++ raugeas_src/Cargo.toml | 13 ++++++ raugeas_src/augeas | 1 + raugeas_src/src/lib.rs | 79 ++++++++++++++++++++++++++++++++ raugeas_src/testcrate/Cargo.toml | 9 ++++ raugeas_src/testcrate/build.rs | 6 +++ raugeas_src/testcrate/src/lib.rs | 7 +++ raugeas_sys/Cargo.toml | 11 ++++- raugeas_sys/build.rs | 27 +++++++++-- 12 files changed, 197 insertions(+), 12 deletions(-) create mode 100644 .gitmodules create mode 100644 raugeas_src/Cargo.toml create mode 160000 raugeas_src/augeas create mode 100644 raugeas_src/src/lib.rs create mode 100644 raugeas_src/testcrate/Cargo.toml create mode 100644 raugeas_src/testcrate/build.rs create mode 100644 raugeas_src/testcrate/src/lib.rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0537bb0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "raugeas_src/augeas"] + path = raugeas_src/augeas + url = https://github.com/hercules-team/augeas diff --git a/Cargo.lock b/Cargo.lock index e63de63..8365296 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "autotools" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941527c41b0fc0dd48511a8154cd5fc7e29200a0ff8b7203c5d777dbc795cf" +dependencies = [ + "cc", +] + [[package]] name = "bindgen" version = "0.70.1" @@ -37,6 +46,15 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "cc" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +dependencies = [ + "shlex", +] + [[package]] name = "cexpr" version = "0.6.0" @@ -86,15 +104,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.166" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets", @@ -171,12 +189,20 @@ dependencies = [ "raugeas_sys", ] +[[package]] +name = "raugeas_src" +version = "0.2.0+augeas-1.14.1" +dependencies = [ + "autotools", +] + [[package]] name = "raugeas_sys" version = "0.2.0" dependencies = [ "bindgen", "pkg-config", + "raugeas_src", ] [[package]] @@ -222,15 +248,22 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "syn" -version = "2.0.89" +version = "2.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "testcrate" +version = "0.1.0" +dependencies = [ + "raugeas_src", +] + [[package]] name = "unicode-ident" version = "1.0.14" diff --git a/Cargo.toml b/Cargo.toml index f2debc6..939f051 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,6 @@ resolver = "2" members = [ "raugeas", "raugeas_sys", -] \ No newline at end of file + "raugeas_src", + "raugeas_src/testcrate", +] diff --git a/raugeas/Cargo.toml b/raugeas/Cargo.toml index 66b3474..3f46c9d 100644 --- a/raugeas/Cargo.toml +++ b/raugeas/Cargo.toml @@ -13,3 +13,7 @@ rust-version = "1.77" raugeas_sys = { path = "../raugeas_sys", version = "0.2.0" } bitflags = "2.6.0" libc = "0.2.43" + +[features] +bundled = ["raugeas_sys/bundled"] +default = [] \ No newline at end of file diff --git a/raugeas_src/Cargo.toml b/raugeas_src/Cargo.toml new file mode 100644 index 0000000..bd9afd6 --- /dev/null +++ b/raugeas_src/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "raugeas_src" +version = "0.2.0+augeas-1.14.1" +authors = ["panicbit ", "Alexis Mousset "] +description = "Low level bindings for augeas" +license = "MIT" +keywords = ["augeas", "bindings"] +repository = "https://github.com/amousset/rust-augeas" +edition = "2021" +rust-version = "1.77" + +[dependencies] +autotools = "0.2" \ No newline at end of file diff --git a/raugeas_src/augeas b/raugeas_src/augeas new file mode 160000 index 0000000..cd37b09 --- /dev/null +++ b/raugeas_src/augeas @@ -0,0 +1 @@ +Subproject commit cd37b0945385705afb936caa9d2fd9a7388bb441 diff --git a/raugeas_src/src/lib.rs b/raugeas_src/src/lib.rs new file mode 100644 index 0000000..8c2dfd7 --- /dev/null +++ b/raugeas_src/src/lib.rs @@ -0,0 +1,79 @@ +//! This crate aims to encapsulate the logic required for building `augeas` +//! from source (so that `augeas-sys` can use it). + +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; + +/// Information about the locations of files generated by `build()`. +/// +/// After the jq sources have been compiled, the fields in this struct +/// represent where the various files ended up, and what sort of build was +/// done (ie, static or dynamic). +pub struct Artifacts { + include_dir: PathBuf, + lib_dir: PathBuf, +} + +impl Artifacts { + /// Prints cargo instructions for linking to the bundled `augeas` lib. + pub fn print_cargo_metadata(&self) { + println!("cargo:include={}", self.include_dir.display()); + println!("cargo:rustc-link-search=native={}", self.lib_dir.display()); + println!("cargo:rustc-link-lib=static={}", "augeas"); + } + pub fn include_dir(&self) -> &Path { + &self.include_dir + } + pub fn lib_dir(&self) -> &Path { + &self.lib_dir + } +} + +/// Entry point for callers to run the build. +pub fn build() -> Result { + let out_dir = env::var_os("OUT_DIR") + .map(PathBuf::from) + .expect("OUT_DIR not set"); + + let augeas_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("augeas"); + + autotools::Config::new(&augeas_dir) + .reconf("-iv") + .out_dir(&out_dir) + .enable_static() + .disable_shared() + .try_build()?; + + Ok(Artifacts { + lib_dir: out_dir.join("lib"), + include_dir: out_dir.join("include"), + }) +} + +/// Recursive file copy +fn cp_r(src: &Path, dst: &Path) { + for f in fs::read_dir(src).unwrap() { + let f = f.unwrap(); + let path = f.path(); + let name = path.file_name().unwrap(); + let dst = dst.join(name); + if f.file_type().unwrap().is_dir() { + fs::create_dir_all(&dst).unwrap(); + cp_r(&path, &dst); + } else { + let _ = fs::remove_file(&dst); + fs::copy(&path, &dst).unwrap(); + } + } +} + +/// Cleanup old sources (left from a previous build attempt) then copy from +/// the git submodule into the location where the build will happen. +fn prepare_sources(src: &Path, dst: &Path) { + if dst.exists() { + fs::remove_dir_all(dst).unwrap(); + } + fs::create_dir_all(dst).unwrap(); + cp_r(src, dst); +} diff --git a/raugeas_src/testcrate/Cargo.toml b/raugeas_src/testcrate/Cargo.toml new file mode 100644 index 0000000..083fa4a --- /dev/null +++ b/raugeas_src/testcrate/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "testcrate" +version = "0.1.0" +authors = ["Alexis Mousset "] +links = "augeas" +build = "build.rs" + +[build-dependencies] +raugeas_src = { path = ".." } \ No newline at end of file diff --git a/raugeas_src/testcrate/build.rs b/raugeas_src/testcrate/build.rs new file mode 100644 index 0000000..38cec10 --- /dev/null +++ b/raugeas_src/testcrate/build.rs @@ -0,0 +1,6 @@ +extern crate raugeas_src; + +fn main() { + let artifacts = raugeas_src::build().unwrap(); + artifacts.print_cargo_metadata(); +} diff --git a/raugeas_src/testcrate/src/lib.rs b/raugeas_src/testcrate/src/lib.rs new file mode 100644 index 0000000..31e1bb2 --- /dev/null +++ b/raugeas_src/testcrate/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/raugeas_sys/Cargo.toml b/raugeas_sys/Cargo.toml index a06bd8a..10ba355 100644 --- a/raugeas_sys/Cargo.toml +++ b/raugeas_sys/Cargo.toml @@ -13,4 +13,13 @@ rust-version = "1.77" [build-dependencies] bindgen = "0.70.1" -pkg-config = "0.3.14" +pkg-config = { version = "0.3.14", optional = true } +raugeas_src = { path = "../raugeas_src", optional = true } + +[features] +default = ["pkg-config"] +bundled = ["raugeas_src"] + +[package.metadata.docs.rs] +no-default-features = true +features = ["bundled"] diff --git a/raugeas_sys/build.rs b/raugeas_sys/build.rs index f337a0d..4322298 100644 --- a/raugeas_sys/build.rs +++ b/raugeas_sys/build.rs @@ -1,19 +1,38 @@ +#[cfg(feature = "bundled")] +extern crate augeas_src; extern crate bindgen; +#[cfg(feature = "pkg-config")] extern crate pkg_config; use std::env; -use std::path::PathBuf; +use std::path::{PathBuf}; -fn main() { +#[cfg(feature = "bundled")] +fn build_bundled() -> Vec { + let artifacts = augeas_src::build().expect("autotools build"); + artifacts.print_cargo_metadata(); + vec![artifacts.include_dir().to_str().unwrap().to_string()] +} + +#[cfg(feature = "pkg-config")] +fn build_shared() -> Vec { let augeas = pkg_config::Config::new() .atleast_version("1.13.0") .probe("augeas") .unwrap(); - let include_paths = augeas + augeas .include_paths .iter() - .map(|path| format!("-I{}", path.display())); + .map(|path| format!("-I{}", path.display())).collect() +} + +fn main() { + #[cfg(feature = "bundled")] + let include_paths = build_bundled(); + + #[cfg(feature = "pkg-config")] + let include_paths = build_shared(); let bindings = bindgen::Builder::default() .header("wrapper.h")