Skip to content

Commit

Permalink
Make the min-platform build script work when run from other directori…
Browse files Browse the repository at this point in the history
…es (#8584)

Annoying to have to `cd` to the directory first before running the build
scripts.
  • Loading branch information
fitzgen authored May 8, 2024
1 parent 46b7f1f commit 16068f0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
21 changes: 14 additions & 7 deletions examples/min-platform/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ if [ "$target" = "" ]; then
exit 1
fi

REPO_DIR=$(dirname $0)/../..
HOST_DIR=$REPO_DIR/examples/min-platform
EMBEDDING_DIR=$HOST_DIR/embedding

set -ex

# First compile the C implementation of the platform symbols that will be
Expand All @@ -25,9 +29,9 @@ set -ex
# cargo install cbindgen
#
# which ensures that Rust & C agree on types and such.
cbindgen ../../crates/wasmtime/src/runtime/vm/sys/custom/capi.rs \
--config embedding/cbindgen.toml > embedding/wasmtime-platform.h
clang -shared -O2 -o libwasmtime-platform.so ./embedding/wasmtime-platform.c \
cbindgen "$REPO_DIR/crates/wasmtime/src/runtime/vm/sys/custom/capi.rs" \
--config "$EMBEDDING_DIR/cbindgen.toml" > "$EMBEDDING_DIR/wasmtime-platform.h"
clang -shared -O2 -o "$HOST_DIR/libwasmtime-platform.so" "$EMBEDDING_DIR/wasmtime-platform.c" \
-D_GNU_SOURCE

# Next the embedding itself is built.
Expand All @@ -38,17 +42,20 @@ clang -shared -O2 -o libwasmtime-platform.so ./embedding/wasmtime-platform.c \
# don't support dynamic libraries so this is a bit of a dance to get around the
# fact that we're pretending this examples in't being compiled for linux.
cargo build \
--manifest-path embedding/Cargo.toml \
--manifest-path $EMBEDDING_DIR/Cargo.toml \
--target $target \
--release
cc \
-Wl,--gc-sections \
-Wl,--whole-archive \
../../target/$target/release/libembedding.a \
"$REPO_DIR/target/$target/release/libembedding.a" \
-Wl,--no-whole-archive \
-shared \
-o libembedding.so
-o "$HOST_DIR/libembedding.so"

# The final step here is running the host, in the current directory, which will
# load the embedding and execute it.
cargo run --release -- $target
cargo run --manifest-path "$HOST_DIR/Cargo.toml" --release -- \
"$target" \
"$HOST_DIR/libembedding.so" \
"$HOST_DIR/libwasmtime-platform.so"
38 changes: 28 additions & 10 deletions examples/min-platform/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,30 @@ fn main() -> Result<()> {

#[cfg(target_os = "linux")]
fn main() -> Result<()> {
use anyhow::{anyhow, Context};
use libloading::os::unix::{Library, Symbol, RTLD_GLOBAL, RTLD_NOW};
use object::{Object, ObjectSymbol, SymbolKind};
use std::io::Write;
use wasmtime::{Config, Engine};

let target = std::env::args().nth(1).unwrap();
let mut args = std::env::args();
let _current_exe = args.next();
let triple = args
.next()
.ok_or_else(|| anyhow!("missing argument 1: triple"))?;
let embedding_so_path = args
.next()
.ok_or_else(|| anyhow!("missing argument 2: path to libembedding.so"))?;
let platform_so_path = args
.next()
.ok_or_else(|| anyhow!("missing argument 3: path to libwasmtime-platform.so"))?;

// Path to the artifact which is the build of the embedding.
//
// In this example this is a dynamic library intended to be run on Linux.
// Note that this is just an example of an artifact and custom build
// processes can produce different kinds of artifacts.
let lib = format!("./libembedding.so");
let binary = std::fs::read(&lib)?;
let binary = std::fs::read(&embedding_so_path)?;
let object = object::File::parse(&binary[..])?;

// Showcase verification that the dynamic library in question doesn't depend
Expand All @@ -29,8 +40,8 @@ fn main() -> Result<()> {
// symbol must be prefixed by `wasmtime_*` and be documented in
// `crates/wasmtime/src/runtime/vm/sys/custom/capi.rs`.
//
// This is effectively a double-check of the above assesrtion and showing
// how running `libembedding.so` in this case requires only minimal
// This is effectively a double-check of the above assertion and showing how
// running `libembedding.so` in this case requires only minimal
// dependencies.
for sym in object.symbols() {
if !sym.is_undefined() || sym.is_weak() || sym.kind() == SymbolKind::Null {
Expand All @@ -53,7 +64,7 @@ fn main() -> Result<()> {
//
// Note that `Config::target` is used here to enable cross-compilation.
let mut config = Config::new();
config.target(&target)?;
config.target(&triple)?;
let engine = Engine::new(&config)?;
let smoke = engine.precompile_module(b"(module)")?;
let simple_add = engine.precompile_module(
Expand Down Expand Up @@ -93,10 +104,15 @@ fn main() -> Result<()> {
// The embedding is then run to showcase an example and then an error, if
// any, is written to stderr.
unsafe {
let _platform_symbols =
Library::open(Some("./libwasmtime-platform.so"), RTLD_NOW | RTLD_GLOBAL)?;
let _platform_symbols = Library::open(Some(&platform_so_path), RTLD_NOW | RTLD_GLOBAL)
.with_context(|| {
format!(
"failed to open {platform_so_path:?}; cwd = {:?}",
std::env::current_dir()
)
})?;

let lib = Library::new(&lib)?;
let lib = Library::new(&embedding_so_path).context("failed to create new library")?;
let run: Symbol<
extern "C" fn(
*mut u8,
Expand All @@ -108,7 +124,9 @@ fn main() -> Result<()> {
*const u8,
usize,
) -> usize,
> = lib.get(b"run")?;
> = lib
.get(b"run")
.context("failed to find the `run` symbol in the library")?;

let mut error_buf = Vec::with_capacity(1024);
let len = run(
Expand Down

0 comments on commit 16068f0

Please sign in to comment.