This repository is a Nix flake for building and packaging software for WASIX
(wasm32-wasix), including:
- plain WASIX build outputs (for example
nano.wasm) - Wasmer package outputs (for example
pkg/nano/{wasmer.toml,bin/nano.wasmer})
-
provide a clean, maintainable package layout for WASIX cross-compilation
-
Wrap existing nixpkgs packages with WASIX cross-compilation
-
Expose plain cross-compiled packages as individual nix packages
-
Expose Wasmer packages, which include wasm binaries and wasmer.toml package definitions
- Build all plain WASM binaries:
nix build- same as
nix build .#wasixAll
- Build one plain package:
nix build .#wasix.nanonix build .#wasix.ncursesnix build .#wasix.ncursesLib
- Build one Wasmer package:
nix build .#wasmer.nanonix build .#wasmer.ncurses
- Build all Wasmer packages:
nix build .#wasmerAll
- Enter development shell:
nix developThe shell has the wasixcc toolchain available
flake.nix exposes:
- top-level namespaced package sets (build with
nix build .#...):wasix.<name>(for examplewasix.nano,wasix.ncurses,wasix.ncursesLib,wasix.wasixcc)wasmer.<name>(for examplewasmer.nano,wasmer.crabsay)
- system-scoped aggregate bundles:
packages.<system>.wasixAll(all plain.wasmbinaries inresult/bin)packages.<system>.wasmerAll(all Wasmer packages inresult/pkg)packages.<system>.default(alias towasixAll)
.
├── flake.nix
├── pkgs
│ ├── default.nix # central wiring: toolchain, indexes, aggregates
│ ├── toolchain
│ │ ├── default.nix # local WASIX toolchain index
│ │ ├── wasix-llvm.nix # pinned WASIX LLVM bundle
│ │ ├── wasixcc.nix # local wasixcc wrapper package
│ │ ├── binaryen.nix # pinned Binaryen bundle
│ │ └── wasix-sysroot.nix # pinned WASIX sysroot artifacts
│ ├── libraries
│ │ ├── default.nix # library index
│ │ └── ncurses/default.nix # ncurses WASIX definition
│ ├── programs
│ │ ├── default.nix # program index
│ │ └── nano
│ │ ├── nano.nix # plain WASIX package definition
│ │ ├── nanoWasmer.nix # Wasmer package definition
│ │ └── patches/... # package-local patches
│ └── wasmer
│ ├── default.nix # Wasmer package index + aggregate bundle
│ └── make-wasmer-package.nix # reusable Wasmer package builder function
└── README.md
pkgs/default.nix defines:
- WASIX toolchain components from local
pkgs/toolchaindefinitions - cross configuration (
wasm32-unknown-wasiwith WASIX-specific flags) - shared env snippets used by package overrides (
toolchainEnv,ccEnv,commonPreConfigure)
pkgs/libraries/default.nixcollects library packagespkgs/programs/default.nixcollects binary/program packagespkgs/wasmer/default.nixcollects Wasmer package outputs
This mirrors nixpkgs indexing style while keeping directory depth reasonable.
wasixAllscans all plain packages forbin/*.wasmand copies them intoresult/binwasmerAllmerges all Wasmer package directories intoresult/pkg
Wasmer packages are generated via pkgs/wasmer/make-wasmer-package.nix.
Defaults:
owner = "wasmer"(overrideable)- package name in
wasmer.tomlbecomes"{owner}/{name}" - description defaults to
package.meta.descriptionwhen available (overrideable) - commands auto-discover from
bin/*.wasmwhencommands = null
Per-package overrides are implemented in package-specific files such as:
pkgs/programs/nano/nanoWasmer.nix
This keeps custom behavior close to each package.
This section describes the recommended flow for adding a new program package (for example foo) and its Wasmer package.
- Create
pkgs/programs/foo/foo.nix- start from nixpkgs package via
callPackage - apply WASIX cross tweaks in
overrideAttrs - ensure output binary is named
*.wasmin$out/bin(for aggregate discovery)
- start from nixpkgs package via
- Add any patches under
pkgs/programs/foo/patches/ - Export package from
pkgs/programs/default.nix:- add
foo = pkgsCross.callPackage ./foo/foo.nix { ... };
- add
- Create
pkgs/programs/foo/fooWasmer.nixusingmakeWasmerPackage - In
pkgs/default.nix, instantiate it with:foo = programs.foomakeWasmerPackage
- In
pkgs/wasmer/default.nix, add a package mapping likefoo = fooWasmer; - In
flake.nix, it is exposed underwasmer.<name>(already wired)
nix build .#wasix.foonix build .#wasmer.foonix build .#wasixAllnix build .#wasmerAll
Check expected output locations:
- plain:
result/bin/*.wasm - Wasmer:
result/pkg/foo/wasmer.toml,result/pkg/foo/bin/*.wasmer
{ makeWasmerPackage, foo }:
makeWasmerPackage {
package = foo;
name = "foo";
# Optional overrides:
# owner = "your-org";
# description = "Custom package description";
# Optional explicit command mapping:
# commands = [
# {
# name = "foo";
# module = "foo";
# wasm = "foo.wasm";
# output = "foo.wasmer";
# }
# ];
}{ nixpkgs, pkgsCross, toolchain, libs }:
{
nano = pkgsCross.callPackage ./nano/nano.nix {
inherit nixpkgs toolchain;
ncurses = libs.ncursesLib;
};
# foo = pkgsCross.callPackage ./foo/foo.nix {
# inherit nixpkgs toolchain;
# # add dependencies here
# };
}nix build .#...uses the git-tracked flake source. If a new file is untracked, Nix may report that the path does not exist.- fix by staging/tracking the file (
git add ...) before using.#..., or usepath:$PWDwhile iterating.
- fix by staging/tracking the file (
- keep patches close to the package that consumes them (
pkgs/programs/<name>/patches/) - prefer explicit package-local Wasmer definitions when behavior might diverge later