Skip to content

Commit

Permalink
add options to allow generating statically linked binaries
Browse files Browse the repository at this point in the history
Signed-off-by: Jorge Prendes <[email protected]>
  • Loading branch information
jprendes committed Aug 2, 2023
1 parent d8e8f30 commit 48e2225
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 21 deletions.
74 changes: 59 additions & 15 deletions crates/wasmedge-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use build_paths::{Env, LibWasmEdgePaths};
mod build_standalone;
use build_standalone::*;

use crate::build_paths::AsPath;

const WASMEDGE_RELEASE_VERSION: &str = "0.13.3";
const REMOTE_ARCHIVES: phf::Map<&'static str, (&'static str, &'static str)> = phf_map! {
"macos/aarch64" => ("db03037e2678e197f9cd5f01392ee088df07e7726849626190f2d4ec1dc693c9", "darwin_arm64"),
Expand Down Expand Up @@ -87,11 +89,9 @@ fn main() {
// Tell cargo to tell rustc to link our `wasmedge` library. Cargo will
// automatically know it must look for a `libwasmedge.a` file.
println!("cargo:rustc-link-lib=static=wasmedge");
println!("cargo:rustc-link-lib=rt");
println!("cargo:rustc-link-lib=dl");
println!("cargo:rustc-link-lib=pthread");
println!("cargo:rustc-link-lib=m");
println!("cargo:rustc-link-lib=stdc++");
for dep in ["rt", "dl", "pthread", "m", "stdc++"] {
link_lib(dep);
}
} else {
println!("cargo:rustc-env=LD_LIBRARY_PATH={lib_dir}");
println!("cargo:rustc-link-search={lib_dir}");
Expand All @@ -107,16 +107,55 @@ fn main() {
let out_file = OUT_DIR.join("wasmedge.rs");

debug!("generating bindgen header {out_file:?}");
bindgen::builder()
.header(header)
.clang_arg(format!("-I{inc_dir}"))
.prepend_enum_name(false) // The API already prepends the name.
.dynamic_link_require_all(true)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("failed to generate bindings")
.write_to_file(out_file)
.expect("failed to write bindings");
if let Some(bindgen_path) = Env("WASMEDGE_RUST_BINDGEN_PATH").as_path() {
let success = std::process::Command::new(bindgen_path)
.arg("--no-prepend-enum-name") // The API already prepends the name.
.arg("--dynamic-link-require-all")
.arg("--formatter=none")
.arg("-o")
.arg(out_file)
.arg(header)
.arg("--")
.arg(format!("-I{inc_dir}"))
.status()
.expect("failed to run rust bindgen")
.success();
assert!(success, "failed to run rust bindgen");
} else {
bindgen::builder()
.header(header)
.clang_arg(format!("-I{inc_dir}"))
.prepend_enum_name(false) // The API already prepends the name.
.dynamic_link_require_all(true)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("failed to generate bindings")
.write_to_file(out_file)
.expect("failed to write bindings");
}
}

fn link_lib(dep: &str) {
// Sanitize dependency name for evn-vars, particularly `stdc++`.
let dep_slug: String = dep.replace('+', "x").to_uppercase();

let generic_link_type_var = Env!("WASMEDGE_DEPS_LINK_TYPE");
let generic_lib_path_var = Env!("WASMEDGE_DEPS_LIB_PATH");
let named_link_type_var = Env!("WASMEDGE_DEP_{dep_slug}_LINK_TYPE");
let named_lib_path_var = Env!("WASMEDGE_DEP_{dep_slug}_LIB_PATH");

let link_type = named_link_type_var
.lossy()
.or_else(|| generic_link_type_var.lossy())
.unwrap_or("dylib".to_string());

for path_var in [named_lib_path_var, generic_lib_path_var] {
if let Some(path) = path_var.lossy() {
println!("cargo:rustc-link-search={path}");
}
}

println!("cargo:rustc-link-lib={link_type}={dep}");
}

#[macro_export]
Expand All @@ -125,3 +164,8 @@ macro_rules! debug {
println!("cargo:warning=[wasmedge-sys] {}", format!($($args),+))
};
}

#[macro_export]
macro_rules! Env {
($($args:expr),+) => { Env(format!($($args),+)) };
}
12 changes: 7 additions & 5 deletions crates/wasmedge-sys/build_paths.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::debug;

pub struct Env<'a>(pub &'a str);
pub struct Env<S: AsRef<str>>(pub S);

impl Env<'_> {
impl<S: AsRef<str>> Env<S> {
pub fn read<T: From<std::ffi::OsString>>(&self) -> Option<T> {
std::env::var_os(self.0).map(T::from)
if self.0.as_ref() != "OUT_DIR" && !self.0.as_ref().starts_with("CARGO_") {
println!("cargo:rerun-if-env-changed={}", self.0.as_ref());
}
std::env::var_os(self.0.as_ref()).map(T::from)
}

pub fn expect<T: TryFrom<std::ffi::OsString>>(&self, msg: &str) -> T
Expand All @@ -31,9 +34,8 @@ pub trait AsPath {
fn as_path(&self) -> Option<std::path::PathBuf>;
}

impl AsPath for Env<'_> {
impl<S: AsRef<str>> AsPath for Env<S> {
fn as_path(&self) -> Option<std::path::PathBuf> {
println!("cargo:rerun-if-env-changed={}", self.0);
self.read()
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/wasmedge-sys/build_standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn get_remote_archive() -> Archive {

fn do_http_request(url: &str) -> impl std::io::Read {
let builder = reqwest::blocking::Client::builder();
let builder = match Env("STANDALONE_PROXY").lossy() {
let builder = match Env("WASMEDGE_STANDALONE_PROXY").lossy() {
Some(proxy) => {
debug!("using proxy to download archive: {proxy}");
let proxy = reqwest::Proxy::all(proxy).expect("failed to parse proxy");
Expand Down

0 comments on commit 48e2225

Please sign in to comment.