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

Add options to allow generating statically linked binaries #46

Closed
wants to merge 1 commit into from
Closed
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
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