Ch1.5: Test Installation

Create a Simple Test Program

After installing the toolchains in Ch1.4, you should verify that your compiler works correctly. Use any text editor you prefer — VS Code PWA, Vim, Notepad, or others — and create a file named hello.cpp.

Although this tutorial uses the fast_io library instead of iostream, a traditional C++ “Hello World” program is still the simplest way to test your installation:

#include <iostream>

int main()
{
    ::std::cout << "Hello World\n";
}

If this program compiles and runs, your installation is functioning correctly.

Clang Configuration Files

The installation scripts from Ch1.4 automatically generate Clang configuration files using create_cfgs.sh or create_cfgs.ps1. These files are stored in:

A Clang .cfg file simply appends compiler flags automatically. You can open them in a text editor to inspect the exact compilation options.

1. Build a Windows Binary (Cross‑Compilation)

On all operating systems except macOS, you can create Windows binaries using Clang. Wine (version 10 or newer) allows you to run these binaries on Linux, musl, or Android.

Linux / BSD / Android

clang++ -o hello.exe hello.cpp -O3 \
  --sysroot=$HOME/toolchains/windows-msvc-sysroot \
  -fuse-ld=lld -flto=thin \
  --target=x86_64-windows-msvc
wine ./hello.exe

If you are on an ARM device (Android, tablets, VR devices), use:

--target=aarch64-windows-msvc

Windows (CMD)

clang++ -o hello.exe hello.cpp -O3 ^
  --sysroot=%USERPROFILE%/toolchains/windows-msvc-sysroot ^
  -fuse-ld=lld ^
  --target=x86_64-windows-msvc
hello.exe

Windows (PowerShell)

clang++ -o hello.exe hello.cpp -O3 `
  --sysroot=$env:USERPROFILE/toolchains/windows-msvc-sysroot `
  -fuse-ld=lld -flto=thin `
  --target=x86_64-windows-msvc
./hello.exe

These commands produce a Windows binary linked against the Microsoft Visual C++ runtime. Wine provides its own implementation, so you do not need to install anything extra on Linux.

Alternative Linking Example

clang++ -o hello.exe hello.cpp -O3 \
  --sysroot=$HOME/toolchains/windows-msvc-sysroot \
  -fuse-ld=lld -D_DLL=1 -lmsvcrt
wine ./hello.exe

Using the Generated CFG Files

clang++ -o hello.exe hello.cpp -O3 \
  --config=$HOME/cfgs/x86_64-windows-msvc.cfg
wine ./hello.exe

To cross‑compile for ARM Windows:

clang++ -o hello.exe hello.cpp -O3 \
  --config=$HOME/cfgs/aarch64-windows-msvc.cfg

You can then copy the binary to your ARM device (Android, etc.) and run it with Wine.

Windows Runtime Notes

Using Wine to Run Clang Itself

The script in Ch1.4 also installs a Windows Clang toolchain on Linux. You can invoke it through Wine:

wine clang++ -o hello.exe hello.cpp -O3 \
  --config=$HOME/cfgs/aarch64-windows-msvc.cfg
wine ./hello.exe

2. Build a Native Binary

To determine your platform’s target triple, run:

clang++ -v

Example output on macOS:

Target: aarch64-apple-darwin24.4.0

The important part is the triplet: aarch64-apple-darwin24. The toolchains from llvm-releases include many common triplets:

Compile a Native Binary

clang++ -o hello hello.cpp -O3 -flto=thin \
  --config=$HOME/cfgs/aarch64-apple-darwin24.cfg
./hello

On macOS, this produces a universal binary containing both x86_64 and aarch64 slices, so it also runs on Intel Macs and Hackintosh systems.

Creating a platform‑specific binary does not necessarily make it more “native” than running a Windows binary through Wine. Wine is a compatibility layer, not an emulator, and avoids issues like glibc version mismatches.

3. Build a WebAssembly Binary

What Is Bytecode?

WebAssembly is a bytecode format — a compact, platform‑independent instruction set. Bytecode is not tied to any CPU architecture. Instead, it is executed by a virtual machine or JIT compiler.

How WebAssembly Compares to Java Bytecode

In other words: Java bytecode is a managed runtime format. WebAssembly is a portable machine‑code‑like format.

WAVM Is Not a Toolchain

WAVM is a WebAssembly virtual machine, not a compiler. Clang produces the WebAssembly binary. WAVM simply runs it.

Compile to WebAssembly

clang++ -o hello hello.cpp -O3 -flto=thin \
  --config=$HOME/cfgs/wasm64-wasip1-noeh.cfg -s

Run with WAVM

wavm run --enable memtag --mount-root . ./hello

WebAssembly Memory Tagging is based on the author’s Ph.D. research (ACM CCSW 2025). It helps detect memory safety bugs and will be used later in this tutorial.