Skip to content

WASM Build Fails in Nix Environment #2579

Description

@nobucc

Summary

When building the ring crate for WASM in a Nix environment, the resulting WASM binary does not function correctly.

Steps to Reproduce

git clone https://github.com/nobucc/ring-wasm-experiment.git
cd ring-wasm-experiment

# enable the Nix environment (you can toggle with `direnv allow` and `direnv disallow`)
direnv allow

# build and run
cargo build --release --target wasm32-wasip1
wasmtime target/wasm32-wasip1/release/ring-wasm-experiment.wasm

The contents of the ring-wasm-experiment repository are as follows:

expand to view

Cargo.toml

[package]
name = "ring-wasm-experiment"
version = "0.1.0"
edition = "2024"

[dependencies]
hex = "0.4.3"
ring = "0.17.14"

src/main.rs

use ring::digest::{Context, SHA256};

fn main() {
    let data = b"Hello, world!";

    let mut context = Context::new(&SHA256);
    context.update(data);
    let hash = context.finish();

    let hex_hash = hex::encode(hash);
    println!("SHA256 hash: {}", hex_hash);
}

flake.nix

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, rust-overlay, flake-utils, ... }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        overlays = [ (import rust-overlay) ];
        pkgs = import nixpkgs { inherit system overlays; };

        rust = pkgs.rust-bin.stable.latest.default.override {
          targets = [ "wasm32-wasip1" ];
        };
      in
      {
        devShells.default = pkgs.mkShell {
          buildInputs = [
            rust
            pkgs.wasmtime
            pkgs.wasm-tools
          ];

          # shellHook = ''
          #   export CC=clang
          # '';
        };
      }
    );
}

Expected Behavior

The binary should run successfully, just as it does when built outside the Nix environment.

Actual Behavior

$ wasmtime target/wasm32-wasip1/release/ring-wasm-experiment.wasm 
Error: failed to run main module `target/wasm32-wasip1/release/ring-wasm-experiment.wasm`

Caused by:
    0: failed to instantiate "target/wasm32-wasip1/release/ring-wasm-experiment.wasm"
    1: unknown import: `env::ring_core_0_17_14__bn_from_montgomery_in_place` has not been defined

$ wasm-tools print target/wasm32-wasip1/release/ring-wasm-experiment.wasm | grep import | grep ring
  (import "env" "ring_core_0_17_14__bn_from_montgomery_in_place" (func $ring_core_0_17_14__bn_from_montgomery_in_place (;0;) (type 8)))
  (import "env" "ring_core_0_17_14__limbs_mul_add_limb" (func $ring_core_0_17_14__limbs_mul_add_limb (;1;) (type 9)))

What I’ve Tried

On a Debian host, uncommenting the shellHook (export CC=clang) in flake.nix and rebuilding results in a valid binary. In other words, using the host’s Clang (rather than the nix-wrapped compiler) allows the compilation to succeed. So I suspected that adding clang-unwrapped to flake.nix might resolve the issue, but that did not work.

I also tried enabling the wasm32_unknown_unknown_js feature of ring, but it had no effect.

Note: The export CC=clang workaround is not a real solution. Depending on tools outside the Nix environment undermines its goal of isolated and reproducible builds, and on NixOS, even the host Clang is nix-wrapped, meaning the build still fails.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions