[PATCH 07/13] cargo: create crate link-with-c
From: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
---
rust/link-with-c/Cargo.toml | 9 +++++
rust/link-with-c/src/lib.rs | 77 +++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 rust/link-with-c/Cargo.toml
create mode 100644 rust/link-with-c/src/lib.rs
diff --git a/rust/link-with-c/Cargo.toml b/rust/link-with-c/Cargo.toml
new file mode 100644
index 0000000000..adb38fdc9c
--- /dev/null
+++ b/rust/link-with-c/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "link-with-c"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+crate-type = ["staticlib", "rlib"]
+
+[dependencies]
diff --git a/rust/link-with-c/src/lib.rs b/rust/link-with-c/src/lib.rs
new file mode 100644
index 0000000000..f6faaf774d
--- /dev/null
+++ b/rust/link-with-c/src/lib.rs
@@ -0,0 +1,77 @@
+use std::collections::HashMap;
+use std::path::PathBuf;
+
+
+fn parse_bool_from_str(value: &str) -> bool {
+ match value {
+ "1" | "true" | "yes" | "on" => true,
+ "0" | "false" | "no" | "off" => false,
+ _ => false
+ }
+}
+
+fn parse_bool_from_option(value: Option<&String>, default: bool) -> bool {
+ match value {
+ Some(v) => {
+ parse_bool_from_str(v.as_str())
+ },
+ None => default,
+ }
+}
+
+/// To build without linking against C libraries run `USE_LINKING=false cargo build`
+/// To run tests set GIT_BUILD_DIR and run `USE_LINKING=true cargo test`
+pub struct BuildHelper {
+ crate_env: HashMap<String, String>,
+}
+
+
+impl BuildHelper {
+ pub fn new(crate_env: HashMap<String, String>) -> Self {
+ Self {
+ crate_env,
+ }
+ }
+
+ pub fn crate_name(&self) -> String {
+ self.crate_env["CARGO_PKG_NAME"].clone()
+ }
+
+ pub fn dir_crate(&self) -> PathBuf {
+ PathBuf::from(self.crate_env["CARGO_MANIFEST_DIR"].clone())
+ }
+
+ pub fn build(self) {
+ let use_linking = parse_bool_from_option(self.crate_env.get("USE_LINKING"), self.crate_env.get("CARGO_TARGET_DIR").is_none());
+ let dir_crate = self.dir_crate();
+ let dir_git = dir_crate.parent().unwrap().parent().unwrap();
+
+ println!("cargo:rerun-if-changed={}", dir_git.display());
+
+ if use_linking {
+ if let Some(git_build_dir) = self.crate_env.get("GIT_BUILD_DIR") {
+ let path_git_build_dir = PathBuf::from(git_build_dir);
+ let is_abs = path_git_build_dir.is_absolute();
+ if !is_abs {
+ panic!("GIT_BUILD_DIR must be an absolute path: {}'", path_git_build_dir.display());
+ }
+ if !path_git_build_dir.is_dir() {
+ panic!("'GIT_BUILD_DIR' is not a directory: {}", path_git_build_dir.display());
+ }
+ println!("cargo:rustc-link-search=native={}", git_build_dir);
+ } else {
+ panic!("environment variable 'GIT_BUILD_DIR' is not set");
+ }
+
+ println!("cargo:rustc-link-lib=static=git");
+ println!("cargo:rustc-link-lib=pcre2-8");
+ if self.crate_env.get("ZLIB_NG").is_some() {
+ println!("cargo:rustc-link-lib=z-ng");
+ } else {
+ println!("cargo:rustc-link-lib=z");
+ }
+ } else {
+ println!("cargo:warning={} is not linking against C objects, `USE_LINKING=true cargo test`", self.crate_env["CARGO_PKG_NAME"]);
+ }
+ }
+}
--
gitgitgadget