Skip to content

Add script for preparing the wasm libraries for building without Nix#1194

Open
jasagredo wants to merge 1 commit intomasterfrom
js/without-nix
Open

Add script for preparing the wasm libraries for building without Nix#1194
jasagredo wants to merge 1 commit intomasterfrom
js/without-nix

Conversation

@jasagredo
Copy link
Copy Markdown
Contributor

Context

Additional context for the PR goes here. If the PR fixes a particular issue please provide a link to the issue.

How to trust this PR

Highlight important bits of the PR that will make the review faster. If there are commands the reviewer can run to observe the new behavior, describe them.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a helper script intended to build the native crypto dependencies needed for WASM builds (libsodium, secp256k1, blst) without relying on Nix, and to generate a Cabal project fragment for wiring the resulting headers/libs into the build.

Changes:

  • Introduces build-wasm-libs.sh to clone/build/install libsodium, secp256k1, and blst for wasm32-wasi.
  • Generates a wasm-libs-without-nix.cabal fragment with extra-lib-dirs / extra-include-dirs.
  • Optionally appends an if arch(wasm32) import block to cabal.project.

Comment on lines +108 to +117
clone_if_missing "$SECP256K1_REPO" "$dir"
cd "$dir"
[ -x ./configure ] || ./autogen.sh
./configure \
--host=wasm32-wasi \
--enable-module-schnorrsig \
--prefix="$ABS_PREFIX" \
SECP_CFLAGS=-fPIC
make -j"$(nproc)"
make install
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build_secp256k1 doesn’t explicitly set CC=wasm32-wasi-clang (only --host=wasm32-wasi). To reduce reliance on ambient toolchain configuration, consider setting CC (and related binutils) for the configure/make step, similar to how build_blst sets CC.

Suggested change
clone_if_missing "$SECP256K1_REPO" "$dir"
cd "$dir"
[ -x ./configure ] || ./autogen.sh
./configure \
--host=wasm32-wasi \
--enable-module-schnorrsig \
--prefix="$ABS_PREFIX" \
SECP_CFLAGS=-fPIC
make -j"$(nproc)"
make install
local cc="wasm32-wasi-clang"
local ar="llvm-ar"
local ranlib="llvm-ranlib"
clone_if_missing "$SECP256K1_REPO" "$dir"
cd "$dir"
[ -x ./configure ] || ./autogen.sh
CC="$cc" AR="$ar" RANLIB="$ranlib" ./configure \
--host=wasm32-wasi \
--enable-module-schnorrsig \
--prefix="$ABS_PREFIX" \
SECP_CFLAGS=-fPIC
make -j"$(nproc)" CC="$cc" AR="$ar" RANLIB="$ranlib"
make install CC="$cc" AR="$ar" RANLIB="$ranlib"

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +58
# Toolchain check: wasm32-wasi-clang must be on PATH (drives both compile and
# link). The other wasm32-wasi-* tools come along with it via the wasi-sdk /
# ghc-wasm env.
toolchain_missing=()
for t in wasm32-wasi-clang wasm-ld; do
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script checks for wasm32-wasi-clang/wasm-ld, but later also depends on tools like ar and file (used in verify_wasm) and nproc. Consider extending the prerequisite checks (or the header docs) so failures are detected early with a clear message.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script checks for wasm32-wasi-clang/wasm-ld, but later also depends on tools like ar and file (used in verify_wasm) and nproc. Consider extending the prerequisite checks (or the header docs) so failures are detected early with a clear message.

I was going to say this too, the comment at the beginning says it needs: autoreconf, automake, libtool, make, git, pkg-config. All these could be checked here

Comment on lines +181 to +183
FRAGMENT="$PROJECT_DIR/wasm-libs-without-nix.cabal"
cat > "$FRAGMENT" <<EOF
shared: True
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated wasm-libs-without-nix.cabal is written into the repo root and uses absolute paths ($ABS_PREFIX). This can clutter the working tree and makes the fragment non-portable if the checkout moves; consider writing it under scripts/wasm-without-nix/ (or similar) and using relative paths when possible.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +4
#!/usr/bin/env bash
# Build libsodium, libsecp256k1, and libblst for wasm32-wasi and install them
# into a single prefix that cabal.project can point at via extra-lib-dirs /
# extra-include-dirs. Mirrors ./nix/{libsodium,secp256k1,blst}.nix but uses
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR appears to be missing the required Herald changelog fragment in .changes/ (CI enforces this). Please add a new .changes/*.yml entry for this change (pick the appropriate project: and kind:).

Copilot uses AI. Check for mistakes.
}

ABS_PREFIX="$(resolve_rel "$PREFIX")"
ABS_SRC_ROOT="$(resolve_rel "$SRC_ROOT")"
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SRC_ROOT is documented as a directory the script will clone into, but the script never creates $ABS_SRC_ROOT. If the parent directory doesn’t exist, git clone will fail; consider mkdir -p "$ABS_SRC_ROOT" before any clones.

Suggested change
ABS_SRC_ROOT="$(resolve_rel "$SRC_ROOT")"
ABS_SRC_ROOT="$(resolve_rel "$SRC_ROOT")"
mkdir -p "$ABS_SRC_ROOT"

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +86

mkdir -p "$ABS_PREFIX/lib" "$ABS_PREFIX/include" "$ABS_PREFIX/lib/pkgconfig"

clone_if_missing() {
local repo="$1" dir="$2" rev="${3:-}"
if [ ! -d "$dir/.git" ]; then
git clone "$repo" "$dir"
fi
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SECP256K1_REPO and BLST_REPO are cloned without a pinned revision/tag, so running this script at different times can produce different binaries (and potentially break builds). Consider pinning these to the same revisions used by the Nix build (from the repo’s pinned nixpkgs/flake.lock) and passing those revs into clone_if_missing.

Suggested change
mkdir -p "$ABS_PREFIX/lib" "$ABS_PREFIX/include" "$ABS_PREFIX/lib/pkgconfig"
clone_if_missing() {
local repo="$1" dir="$2" rev="${3:-}"
if [ ! -d "$dir/.git" ]; then
git clone "$repo" "$dir"
fi
# Pin these to the same revisions used by the Nix build. They may also be
# overridden from the environment when invoking this script.
SECP256K1_REV="${SECP256K1_REV:-}"
BLST_REV="${BLST_REV:-}"
mkdir -p "$ABS_PREFIX/lib" "$ABS_PREFIX/include" "$ABS_PREFIX/lib/pkgconfig"
pinned_rev_for_repo() {
local repo="$1"
case "$repo" in
"$LIBSODIUM_REPO") printf '%s\n' "$LIBSODIUM_REV" ;;
"$SECP256K1_REPO") printf '%s\n' "$SECP256K1_REV" ;;
"$BLST_REPO") printf '%s\n' "$BLST_REV" ;;
*) printf '%s\n' "" ;;
esac
}
clone_if_missing() {
local repo="$1" dir="$2" rev="${3:-}"
if [ -z "$rev" ]; then
rev="$(pinned_rev_for_repo "$repo")"
fi
if [ ! -d "$dir/.git" ]; then
if [ -z "$rev" ]; then
echo "Error: refusing to clone $repo without a pinned revision. Configure the matching *_REV to the revision used by the Nix build." >&2
exit 1
fi
git clone "$repo" "$dir"
fi

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +99
[ -x ./configure ] || ./autogen.sh -s
./configure --host=wasm32-wasi --prefix="$ABS_PREFIX"
make -j"$(nproc)"
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build_libsodium relies on ./configure --host=wasm32-wasi to pick the right compiler, but doesn’t explicitly set CC=wasm32-wasi-clang (or related tools). If the environment isn’t set up as expected, this can silently compile for the wrong target and only fail late; consider exporting CC (and possibly AR, RANLIB) for this build step.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@palas palas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thank you. I was able to run it on Ubuntu 24.04 to compile cardano-wasm to wasm successfully. I suggest a few changes to make this script a bit more robust and straightforward to use.

Error: wasm toolchain not on PATH (missing: ${toolchain_missing[*]}).

The ghc-wasm / wasi-sdk environment doesn't appear to be active. Activate it
with:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra-lib-dirs: $ABS_PREFIX/lib
extra-include-dirs: $ABS_PREFIX/include
EOF
echo "Wrote project fragment: $FRAGMENT"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe would be good to mention adding the pkg-config path to PKG_CONFIG_PATH if it is not standard, and print which it is

# wasm32-wasi-clang directly (no Nix).
#
# Requirements on PATH: wasm32-wasi-clang (from wasi-sdk), autoreconf,
# automake, libtool, make, git, pkg-config.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to say this in the help message too

Comment on lines +54 to +58
# Toolchain check: wasm32-wasi-clang must be on PATH (drives both compile and
# link). The other wasm32-wasi-* tools come along with it via the wasi-sdk /
# ghc-wasm env.
toolchain_missing=()
for t in wasm32-wasi-clang wasm-ld; do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script checks for wasm32-wasi-clang/wasm-ld, but later also depends on tools like ar and file (used in verify_wasm) and nproc. Consider extending the prerequisite checks (or the header docs) so failures are detected early with a clear message.

I was going to say this too, the comment at the beginning says it needs: autoreconf, automake, libtool, make, git, pkg-config. All these could be checked here

wasm32-wasi-clang -shared -Wl,--whole-archive \
"$ABS_PREFIX/lib/libsodium.a" \
-o "$ABS_PREFIX/lib/libsodium.so"
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
cd -
}

I would suggest returning to the previous folder to make this function more self-contained. Currently this does not make a difference but if we move the call to the function to somewhere else it could break things

make install
wasm32-wasi-clang -shared -Wl,--whole-archive \
"$ABS_PREFIX/lib/libsecp256k1.a" \
-o "$ABS_PREFIX/lib/libsecp256k1.so"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
-o "$ABS_PREFIX/lib/libsecp256k1.so"
-o "$ABS_PREFIX/lib/libsecp256k1.so"
cd -

Same here

Cflags: -I\${includedir}
Libs: -L\${libdir} -lblst
Libs.private:
EOF
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
EOF
EOF
cd -

And here

Name: libblst
Description: blst BLS12-381 signature library
URL: https://github.com/supranational/blst
Version: $version
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing the script I found an issue with the version of libblst in the pkg-config file (libblst.pc), which was Version: v0.3.16-36-gdece82e and the "v" at the beginning was tripping cabal. Not sure why that happens. Did you get that too?

Maybe it would be fixed by fixing a revision?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants