Search code examples
clangwebassemblynix

Nix's clang won't build wasm


I'm have a C Wasm module with the following import:

__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);

I'm compiling with Clang 12.0.0 on Linux:

clang --target=wasm32 --no-standard-libraries \
      -c -Ofast -o out.o in.c

With the package from my package manager (xbps), this works fine. In Nix (see below for the derivation), however (Clang 12.0.1), I get the following warning on nix-build:

tests/test.h:1:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
               ^~~~~~~~~~~~~~~~~~~~

tests/test.h:1:38: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);

This is just a warning, but linking later fails: in fact, clang is attempting to link with ld, not wasm-ld or even lld.

My default.nix specifies:

{ pkgs ? import <nixpkgs> {} }:

let
  stdenv = pkgs.llvmPackages_12.stdenv;
  src = ./.; # etc, etc
in
  stdenv.mkDerivation {
    # --- snip ---
    buildPhase = ''
      clang --target=wasm32 --no-standard-libraries \
            -c -Ofast -o $out/out.o in.c
    '';
    
    # --- snip ---

    buildInputs = [ pkgs.clang_12 pkgs.lld_12 ];
  }

I don't see why this shouldn't work, but all the different variations of packages I've tried using seem to suggest that I'm getting at the LLVM toolchain incorrectly.

If this isn't enough information, please let me know. Thanks!

Edit

It looks like Nix isn't respecting the --target argument:

$ nix-shell
[nix-shell:~/...]$ clang -target wasm32 --print-target-triple
x86_64-unknown-linux-gnu
[nix-shell:~/...]$ exit
$ clang --target=wasm32 --print-target-triple
wasm32

Despite the above, clang wasm32 as an available target.


Solution

  • The clang wrapper script given by Nix seems to do something. The compiler should be called with clang-[VERSION] instead of clang, for example as:

    clang-12 --target=wasm32 --no-standard-libraries   \
             -c -std=c99 -Ofast -Wall -Werror -pedantic \
             input.c -o output.o