# Compiling ArmorPaint from Source with Clang on Windows vs Linux: Common Pitfalls and Fixes

> Fix common ArmorPaint build failures compiling from source with Clang on Windows vs Linux. Learn about MSVC runtime and Vulkan SDK issues.

- Repository: [Armory 3D/armorpaint](https://github.com/armory3d/armorpaint)
- Tags: how-to-guide
- Published: 2026-09-14

---

**Compiling ArmorPaint from source requires Clang 19+ for C23 `#embed` support, but platform-specific toolchain differences—MSVC runtime dependencies on Windows and Vulkan SDK requirements on Linux—cause the most common build failures.**

The armory3d/armorpaint repository uses a custom `make` frontend to drive C/C++ compilation, supporting both Windows (via Visual Studio with LLVM/Clang) and Linux (via native Clang installations). While the build commands appear similar across platforms, the underlying toolchain expectations differ significantly, leading to distinct failure modes that trip up developers migrating between operating systems.

## Windows-Specific Pitfalls (Visual Studio Clang Tools)

### Missing MSVC Runtime Environment

The most frequent Windows failure occurs when developers install the LLVM/Clang component but neglect the MSVC runtime libraries. In `base/tools/iris/make.bat`, the build script sets `CC=clang` and expects the MSVC x64 tools to be active on the PATH. Without running `vcvars64.bat` or using the "x64 Native Tools Command Prompt," the Clang driver cannot locate `ucrt.lib` or `vcruntime.lib`.

This manifests as **"unresolved external symbol"** linker errors, even though Clang itself is correctly installed. The Windows build relies on the Clang driver being `clang-cl` compatible, meaning it reuses the MSVC linker (`link.exe`) and Windows SDK library directories.

### Clang Version Requirements for `#embed`

ArmorPaint utilizes the C23 `#embed` directive to bundle assets directly into the binary. This feature is only implemented in **Clang 19 or newer**. The repository explicitly checks for `__clang_major__ >= 19` in the build configuration—older versions (such as the Clang 16.0 bundled with some Visual Studio 2022 installations) abort with "unknown preprocessor directive" errors.

As noted in the [`readme.md`](https://github.com/armory3d/armorpaint/blob/main/readme.md), the build requires "compiler with c23 #embed support (clang 19 or newer)" to process the embedded asset files correctly.

## Linux-Specific Pitfalls (Native Clang)

### Vulkan SDK and Dependency Management

Linux builds fail most commonly due to missing graphics dependencies. The linker requires `libvulkan.so` and associated development headers. If the Vulkan SDK is not installed or the `VULKAN_SDK` environment variable is not exported, the build terminates with **"cannot find -lvulkan"** errors.

According to [`base/docs/linux_deps.md`](https://github.com/armory3d/armorpaint/blob/main/base/docs/linux_deps.md), you must install `vulkan-sdk`, `glslang-tools`, `spirv-tools`, and `zlib` development packages before invoking the build. Unlike the Windows installer, the Linux make script does not auto-detect or install these dependencies.

### GNU-Compatible Clang Driver Requirements

The generic build script (`base/make`) invokes `clang` directly and passes GCC-style flags such as `-fno-exceptions` and `-march=x86-64`. Some Linux distributions ship an LLVM-C frontend that only accepts LLVM-specific flags, causing "unrecognized command line option" errors.

Ensure your `clang` binary is the GNU-compatible driver rather than the reduced LLVM-C frontend. This distinction is critical around line 967 in [`base/tools/make.js`](https://github.com/armory3d/armorpaint/blob/main/base/tools/make.js) where the command array constructs compiler invocations.

## Cross-Platform Build Failures

### Path Spaces and Unicode Characters

Both platforms suffer from path handling issues in the make scripts. If your source root contains spaces (e.g., `C:\Users\John Doe\armorpaint`) or Unicode characters, the generated `.vcxproj` files contain malformed include paths. The batch files construct commands with quotes but do not perform robust path-escaping, leading to "file not found" errors during compilation.

Store the repository in a path without spaces to avoid these issues: use `C:\dev\armorpaint` rather than `C:\My Projects\Armor Paint`.

## Step-by-Step Build Instructions

### Windows Build Steps

1. Install **Visual Studio 2022** with the **Desktop development with C++** workload **and** the **LLVM/Clang toolset** component.
2. Open the **x64 Native Tools Command Prompt** to ensure `vcvars64.bat` has run.
3. Verify Clang version: `clang --version` must show **19.x** or higher.
4. Install the **Vulkan SDK** and ensure `VULKAN_SDK` is set (the installer configures this automatically).
5. Build the solution:

```bash
cd armorpaint\paint
..\base\make
start build\ArmorPaint.sln

```

### Linux Build Steps

1. Install Clang 19 or newer: `sudo apt install clang-19`.
2. Install dependencies per [`base/docs/linux_deps.md`](https://github.com/armory3d/armorpaint/blob/main/base/docs/linux_deps.md): `vulkan-sdk`, `glslang-tools`, `spirv-tools`, and `libvulkan-dev`.
3. Export the Vulkan SDK path: `export VULKAN_SDK=/usr/include/vulkan`.
4. Run the build:

```bash
cd armorpaint/paint
../base/make --run

```

## Summary

- **Windows requires the MSVC environment**: Always run `vcvars64.bat` before building to provide `ucrt.lib` and `vcruntime.lib` for the Clang driver.
- **Clang 19+ is mandatory**: Both platforms require Clang 19 or newer to support the C23 `#embed` directive used in [`paint/project.js`](https://github.com/armory3d/armorpaint/blob/main/paint/project.js).
- **Linux needs explicit Vulkan setup**: Install Vulkan SDK, glslang, and SPIRV tools manually and export `VULKAN_SDK` before running `../base/make`.
- **Use GNU-compatible Clang on Linux**: Ensure your `clang` binary accepts GCC-style flags (`-fno-exceptions`, `-march=x86-64`) rather than the LLVM-C frontend.
- **Avoid path spaces**: Store the repository in paths without spaces to prevent malformed project file generation in `base/tools/iris/make.bat`.

## Frequently Asked Questions

### Why does the Windows build fail with "unresolved external symbol" errors?

The Clang driver on Windows relies on the MSVC linker (`link.exe`) and cannot find the C runtime libraries (`ucrt.lib`, `vcvruntime.lib`) unless you run `vcvars64.bat` or use the "x64 Native Tools Command Prompt" before building. The `base/tools/iris/make.bat` script assumes these environment variables are already configured.

### Can I use the Clang bundled with Visual Studio 2022?

Only if it is version 19 or newer. Some Visual Studio 2022 installations include Clang 16.0, which lacks support for the C23 `#embed` directive. Verify with `clang --version`—ArmorPaint requires Clang 19+ as specified in the [`readme.md`](https://github.com/armory3d/armorpaint/blob/main/readme.md) to process embedded asset files.

### Why does the Linux build fail with "cannot find -lvulkan"?

The linker cannot locate the Vulkan library because either the Vulkan SDK is not installed or the `VULKAN_SDK` environment variable is not exported. Install `libvulkan-dev` and the Vulkan SDK, then set `export VULKAN_SDK=/usr/include/vulkan` (or your SDK installation path) before invoking `../base/make`.

### What is the difference between the GNU-compatible Clang driver and the LLVM-C frontend?

The GNU-compatible driver accepts standard GCC-style flags like `-fno-exceptions` and `-march=x86-64`, which the ArmorPaint build script ([`base/tools/make.js`](https://github.com/armory3d/armorpaint/blob/main/base/tools/make.js) around line 967) passes to the compiler. The LLVM-C frontend only accepts LLVM-specific options and will reject these flags with "unrecognized command line option" errors. Ensure your `clang` binary is the full GNU-compatible driver, not the reduced LLVM-C version.