1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#!/bin/sh
# This script is taken from https://raw.githubusercontent.com/bytecodealliance/wit-bindgen/refs/tags/v0.45.0/ci/rebuild-libwit-bindgen-cabi.sh
# and adapted for usage during the package build, since the pre-built artifacts
# it generates are removed from the upstream tarball, but this script is not
# shipped in the vendored crate.
#
# See https://github.com/bytecodealliance/wit-bindgen/issues/1288
#
# Diff to upstream's version:
# - adapt paths
# - add versions to called LLVM tools
# - add explicit --target to clang-21 invocations
# - skip stripping, we don't care about Linux/MacOS differences
# This script, and various infrastructure, is a hack to work around the lack of
# stable support in Rust to generate a weak symbol.
#
# The basic problem here is that the Rust `wit-bindgen` crate wants to export
# the `cabi_realloc` symbol from the final binary. This library, however,
# is not stable which means that we're publishing new versions of `wit-bindgen`
# over its development. This means that if `wit-bindgen`-the-crate were to
# export a `#[unsafe(no_mangle)]` symbol of `cabi_realloc` then it wouldn't
# work to have two versions of `wit-bindgen` in the same project. This can
# arise relatively quickly, however, so this is something we want to solve.
#
# The general idea of the solution here is to ensure that the `cabi_realloc`
# symbol itself is declared as a weak symbol. A weakly-defined symbol means
# that if the linker sees multiple copies it can discard all but one. This is
# the semantics we want where some `wit-bindgen` needs to define `cabi_realloc`
# but it doesn't matter much which one.
#
# Stable Rust can't define weak symbols as of the time of this writing. C,
# however, can. Unfortunately users of this crate do not always have a C
# compiler on-hand for wasm, nor do we want to require one. That's where all
# these hacks come into play. With that intro, the purpose of this script is to:
#
# * Generate a `cabi_realloc.rs` file with a "mangled" Rust symbol that's
# unique per-major-version of the crate.
# * Generate a `cabi_realloc.c` file that defines a weak `cabi_realloc` symbol
# that calls the above Rust symbol
# * Compile `cabi_realloc.c` into an object and place it into an archive and
# check that archive into this repo.
#
# This all leads up to the point where we're distributing binary artifacts with
# this crate. These artifacts are verified in CI to ensure what this script
# generates.
#
# Overall this is intended to provide `cabi_realloc` as a weak symbol,
# everything works on stable Rust, and users don't need a C compiler when they
# use this crate.
set -ex
version=0.45.0
realloc=cabi_realloc_wit_bindgen_0_45_0
rm -f vendor/wit-bindgen-$version/src/rt/wit_bindgen_*.{rs,o,c}
rm -f vendor/wit-bindgen-$version/src/rt/libwit_bindgen_cabi.a
cat >vendor/wit-bindgen-$version/src/rt/wit_bindgen_cabi_realloc.rs <<-EOF
// This file is generated by $0
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $realloc(
old_ptr: *mut u8,
old_len: usize,
align: usize,
new_len: usize,
) -> *mut u8 {
crate::rt::cabi_realloc(old_ptr, old_len, align, new_len)
}
EOF
cat >vendor/wit-bindgen-$version/src/rt/wit_bindgen_cabi_realloc.c <<-EOF
// This file is generated by $0
#include <stdint.h>
extern void *$realloc(void *ptr, size_t old_size, size_t align, size_t new_size);
__attribute__((__weak__, __export_name__("cabi_realloc")))
void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
return $realloc(ptr, old_size, align, new_size);
}
EOF
cat >vendor/wit-bindgen-$version/src/rt/wit_bindgen_cabi_wasip3.c <<-EOF
// This file is generated by $0
#include <stdlib.h>
static void *WASIP3_TASK = NULL;
__attribute__((__weak__))
void *wasip3_task_set(void *ptr) {
void *ret = WASIP3_TASK;
WASIP3_TASK = ptr;
return ret;
}
EOF
build() {
file=$1
target=$2
clang-21 vendor/wit-bindgen-$version/src/rt/$1.c \
-O -c -o vendor/wit-bindgen-$version/src/rt/$1.o -mcpu=mvp --target=$target
# Remove the `producers` section. This appears to differ whether the host for
# clang is either macOS or Linux. Not needed here anyway, so discard it to help
# either host produce the same object.
#strip -d producers vendor/wit-bindgen-$version/src/rt/$1.o \
# -o vendor/wit-bindgen-$version/src/rt/$1.o
}
build wit_bindgen_cabi_realloc wasm32-wasip2
build wit_bindgen_cabi_wasip3 wasm32-wasip2
llvm-ar-21 crus vendor/wit-bindgen-$version/src/rt/libwit_bindgen_cabi.a \
vendor/wit-bindgen-$version/src/rt/wit_bindgen_cabi_realloc.o \
vendor/wit-bindgen-$version/src/rt/wit_bindgen_cabi_wasip3.o
|