Running on Native Linux
Docker is quick to use, but is not necessary for running Lind-Wasm. Lind-Wasm can be built and run directly on Ubuntu 22.04, both in WSL2 and on native Linux, without using Docker.
This guide follows the dependency versions used by
Dockerfile.dev, but installs them directly
in the WSL2 or native Linux environment.
Tested environment
The following configuration was used to run lind-wasm on WSL2 and native Linux
Environment #1: - Windows 10 Pro - WSL2 - Ubuntu 22.04 - x86-64/AMD64 processor(Ryzen 5 3600) - 16 GB RAM - 25 GB of free space
Environment #2: - Native Linux - Ubuntu 22.04 - x86-64/AMD64 processor(AMD Ryzen™ AI 9 HX 370) - 16 GB RAM - 46 GB of free space
The exact minimum disk-space requirement has not been formally measured. The dependencies require a significant amount of storage so 15-20gb of free space is recommended to avoid any issues during installation.
step by step guide on installing without Docker
- Install Ubuntu 22.04 on WSL2(SKIP IF YOU ARE ON NATIVE LINUX)
From Windows PowerShell, install Ubuntu 22.04 if it is not already available:
wsl --install -d Ubuntu-22.04
Set it as the default WSL distribution:
wsl --set-default Ubuntu-22.04
Launch Ubuntu 22.04 before continuing.
- Install system dependencies
Update the packages:
sudo apt update
Install the development packages used by
Dockerfile.dev:
sudo apt install -y \
binutils \
bison \
cmake \
flex \
build-essential \
ca-certificates \
strace \
curl \
gawk \
git \
gnupg \
libc6-dev-i386-cross \
libxml2 \
make \
python3 \
sed \
sudo \
unzip \
zip \
autoconf \
rsync \
libtool \
automake \
vim \
wget \
openssl \
libssl-dev \
golang \
gdb \
linux-tools-common \
linux-tools-generic \
tzdata \
xz-utils
Install the pinned libtinfo5 compatibility package:
wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.2_amd64.deb
sudo apt install -y ./libtinfo5_6.3-2ubuntu0.2_amd64.deb
rm libtinfo5_6.3-2ubuntu0.2_amd64.deb
- Install Rust
Install Rust through rustup using the minimal profile:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs |
sh -s -- -y --profile minimal
Load the Rust environment:
source "$HOME/.cargo/env"
The repository pins its toolchain in
rust-toolchain.toml,
and rustup installs and selects that channel automatically the first time you
build inside the repository. Do not pin a different nightly by hand:
rust-toolchain.toml wins at build time, so a toolchain you select manually —
and any components you add to it — is silently ignored.
The rust-src component still has to be added explicitly. Because that must
happen against the pinned channel, it is done after cloning, in step 8.
- Install WABT 1.0.38
Download and build the pinned WABT release:
curl -fsSL \
https://github.com/WebAssembly/wabt/releases/download/1.0.38/wabt-1.0.38.tar.xz \
-o /tmp/wabt.tar.xz
mkdir -p /tmp/wabt-src
tar -xJf /tmp/wabt.tar.xz \
-C /tmp/wabt-src \
--strip-components=1
cmake -S /tmp/wabt-src \
-B /tmp/wabt-src/build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTS=OFF
cmake --build /tmp/wabt-src/build \
--target wasm2wat wat2wasm wasm-objdump \
--parallel "$(nproc)"
Install the required programs:
sudo install -m 0755 \
/tmp/wabt-src/build/wasm2wat \
/usr/local/bin/wasm2wat
sudo install -m 0755 \
/tmp/wabt-src/build/wat2wasm \
/usr/local/bin/wat2wasm
sudo install -m 0755 \
/tmp/wabt-src/build/wasm-objdump \
/usr/local/bin/wasm-objdump
Remove the temporary build files:
rm -rf /tmp/wabt.tar.xz /tmp/wabt-src
Verify the tools:
wasm2wat --version
wat2wasm --version
wasm-objdump --version
- Clone Lind-Wasm
Clone the repository into the Linux filesystem rather than under /mnt/c:
cd ~
git clone https://github.com/Lind-Project/lind-wasm.git
cd lind-wasm
- Install Clang/LLVM 18.1.8
Download and extract the pinned LLVM package:
cd ~/lind-wasm
curl -fsSL \
https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04.tar.xz \
-o /tmp/llvm.tar.xz
tar -xJf /tmp/llvm.tar.xz -C ~/lind-wasm
rm /tmp/llvm.tar.xz
- Install Lind's WASI files and configure the environment
Copy Lind's WASI files into the Clang resource directory:
cp -r \
~/lind-wasm/src/glibc/wasi \
~/lind-wasm/clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04/lib/clang/18/lib/
Add the Lind-Wasm root, LLVM, and Rust directories to the shell environment:
echo 'export LIND_WASM_ROOT="$HOME/lind-wasm"' >> ~/.bashrc
echo 'export CLANG="$LIND_WASM_ROOT/clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04"' >> ~/.bashrc
echo 'export PATH="$CLANG/bin:$HOME/.cargo/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Verify LLVM:
clang --version
wasm-ld --version
- Build Lind-Wasm
From the repository root, add rust-src to the pinned toolchain. Running this
inside the repository is what makes rustup resolve rust-toolchain.toml:
cd ~/lind-wasm
rustup component add rust-src
rustup show active-toolchain
Check that the machine has everything else it needs. Every FAIL comes with
the command that fixes it:
make checkenv BUILD_ONLY=1
Then build the runtime, Lind filesystem, custom glibc, and sysroot:
make build
Use make build rather than the individual targets: make lind-boot sysroot
skips the lindfs target, and make sysroot on its own fails on a clean
checkout because building the shared libc needs lind-boot to exist already.
For a debug runtime use make lind-debug instead — but do not mix the two, or
you will get unknown import: debug::lind_debug_num at run time.
See the project Makefile for the individual build
targets and build knobs.
- Install the Lind helper commands
Make the scripts executable:
chmod +x \
scripts/bin/lind_compile \
scripts/bin/lind_run \
scripts/bin/cargo-lind_compile
Create commands in /usr/local/bin:
sudo ln -sfn \
"$HOME/lind-wasm/scripts/bin/lind_compile" \
/usr/local/bin/lind_compile
sudo ln -sfn \
"$HOME/lind-wasm/scripts/bin/lind_run" \
/usr/local/bin/lind_run
sudo ln -sfn \
"$HOME/lind-wasm/scripts/bin/cargo-lind_compile" \
/usr/local/bin/cargo-lind_compile
Add the alternate command names used by the development image:
sudo ln -sfn /usr/local/bin/lind_compile /usr/local/bin/lind-clang
sudo ln -sfn /usr/local/bin/lind_run /usr/local/bin/lind-wasm
sudo ln -sfn \
/usr/local/bin/cargo-lind_compile \
/usr/local/bin/lind-cargo-build
Verify the commands:
command -v lind_compile
command -v lind_run
command -v cargo-lind_compile
-
Create the Lind filesystem compatibility link
The runtime
chroots into a path that is compiled in as a constant —LINDFS_ROOTinsrc/sysdefs/src/constants/lind_platform_const.rs, currently/home/lind/lind-wasm/lindfs. It is not read from the environment, so a checkout anywhere else panics at startup withThe configured lindfs does not exist. Unless your home directory is literally/home/lind, create a compatibility symbolic link:sudo mkdir -p /home/lind sudo ln -sfnT "$HOME/lind-wasm" /home/lind/lind-wasmVerify the path:
ls -ld /home/lind/lind-wasm/lindfs -
Compile and run a test program
Create
hello.cin the repository root:#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }Compile it:
cd ~/lind-wasm lind_compile hello.cRun the compiled program using its path inside
lindfs:lind_run /hello.cwasmThe expected output is:
Hello, World!Two things to expect the first time:
lind_runprompts for a password. It re-executes itself undersudo -Ebecause the runtime needs root tochroot.- The path is
/hello.cwasm, not./hello.cwasm.lind_compilecopies its output intolindfs/, and the runtimechroots there, so paths are relative tolindfsrather than to your shell's working directory.
lind_compilebuilds dynamically by default, resolving lind-glibc fromlindfs/lib/libc.cwasmat run time. Pass-sfor a statically linked binary, which does not need the shared libc to be present. -
Run the full test suite
From the repository root, run the full test suite. It can take a while, so wait for it to finish:
cd ~/lind-wasm make test