Building Slang From Source

TLDR

cmake --workflow --preset release to configure, build, and package a release version of Slang.

Prerequisites:

Please install:

  • CMake (3.26 preferred, but 3.22 works[^1])

  • A C++ compiler with support for C++17. GCC, Clang and MSVC are supported

  • A CMake compatible backend, for example Visual Studio or Ninja

  • Python3 (a dependency for building spirv-tools)

Optional dependencies for tests include

  • CUDA

  • OptiX

  • NVAPI

  • Aftermath

  • X11

Other dependencies are sourced from submodules in the ./external directory.

Get the Source Code

Clone this repository. Make sure to fetch the submodules also.

git clone https://github.com/shader-slang/slang --recursive

You will need the git tags from this repository, otherwise versioning information (including the Slang modules directory name and the library filenames on macOS and Linux) will be incorrect. The above command should fetch them for you, but if you’re fetching from a fork you may need to explicitly fetch the latest tags from the shader-slang repository with:

git fetch https://github.com/shader-slang/slang.git 'refs/tags/*:refs/tags/*'

Configure and build

This section assumes cmake 3.25 or greater, if you’re on a lower version please see building with an older cmake

For a Ninja based build system (all platforms) run:

cmake --preset default
cmake --build --preset releaseWithDebugInfo # or --preset debug, or --preset release

Note: when using Ninja (default preset) on Windows, you need to make sure the cmake command is run from the Visual Studio Developer Command Prompt. If you are a coding agent trying to build Slang in a Windows sandbox, run extras/win-sandbox-build.bat [debug|release|releaseWithDebugInfo|minSizeRel] [x64|arm64|Win32] [target...] instead. It configures with the vs2022-dev preset, reuses locally cached dependencies to avoid network fetches, and defaults to building slangc, slang-test, and slangi.

For Visual Studio run:

cmake --preset vs2022 # or 'vs2019' or 'vs2026'
start devenv ./build/slang.sln # to optionally open the project in Visual Studio
cmake --build --preset releaseWithDebugInfo # to build from the CLI, could also use --preset release or --preset debug

There are also *-dev variants like vs2022-dev and vs2026-dev which turn on features to aid debugging. The vs2022-dev preset writes to build/windows-vs2022-dev.

WebAssembly build

In order to build WebAssembly build of Slang, Slang needs to be compiled with Emscripten SDK. You can find more information about Emscripten.

You need to clone the EMSDK repo. And you need to install and activate the latest.

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk

For non-Windows platforms

./emsdk install latest
./emsdk activate latest

For Windows

emsdk.bat install latest
emsdk.bat activate latest

After EMSDK is activated, Slang needs to be built in a cross compiling setup:

  • build the generators target for the build platform

  • configure the build with emcmake for the host platform

  • build for the host platform.

Note: For more details on cross compiling please refer to the cross-compiling section.

# Build generators.
cmake --workflow --preset generators --fresh
mkdir generators
cmake --install build --config Release --prefix generators --component generators

# Configure the build with emcmake.
# emcmake is available only when emsdk_env setup the environment correctly.
pushd ../emsdk
source ./emsdk_env # For Windows, emsdk_env.bat
popd
emcmake cmake -DSLANG_GENERATORS_PATH=generators/bin --preset emscripten -G "Ninja"

# Build slang-wasm.js and slang-wasm.wasm in build.em/Release/bin
cmake --build --preset emscripten --target slang-wasm

Note: If the last build step fails, try running the command that emcmake outputs, directly.

Android build

In order to build Slang for Android, you need the Android NDK installed and the ANDROID_NDK_HOME environment variable set to point to your NDK installation.

Android builds are a cross compiling setup, so build the generators for the build platform first:

# Build generators.
cmake --workflow --preset generators --fresh
mkdir generators
cmake --install build --prefix generators --component generators

Then configure and build for the desired architecture:

# ARM64 (arm64-v8a)
cmake --preset android-arm64 --fresh -DSLANG_GENERATORS_PATH=generators/bin
cmake --build --preset android-arm64-release

# x86_64
cmake --preset android-x86_64 --fresh -DSLANG_GENERATORS_PATH=generators/bin
cmake --build --preset android-x86_64-release

Other build presets are also provided for both architectures:

  • android-arm64-debug

  • android-arm64-releaseWithDebugInfo

  • android-x86_64-debug

  • android-x86_64-releaseWithDebugInfo

Note: Android presets disable some features to reduce dependencies, including GFX, tests, slangd, replayer, LLVM, examples, xlib, CUDA, OptiX, NVAPI, and Aftermath.

Installing

Build targets may be installed using cmake:

cmake --build . --target install

This should install SlangConfig.cmake that should allow find_package to work. SlangConfig.cmake defines SLANG_EXECUTABLE variable that will point to slangc executable and also define slang::slang target to be linked to.

For now, slang::slang is the only exported target defined in the config which can be linked to.

Example usage

find_package(slang REQUIRED PATHS ${your_cmake_install_prefix_path} NO_DEFAULT_PATH)
# slang_FOUND should be automatically set
target_link_libraries(yourLib PUBLIC
  slang::slang
)

Testing

build/Debug/bin/slang-test

See the documentation on testing for more information.

Using sccache for faster rebuilds

sccache caches compilation results so that subsequent builds are significantly faster. To enable it, either set the CMake option or the environment variable:

# Via CMake option
cmake --preset default -DSLANG_USE_SCCACHE=ON

# Via environment variable
SLANG_USE_SCCACHE=1 cmake --preset default

When sccache is enabled, precompiled headers are automatically disabled because of a known incompatibility that causes linker errors. If CMAKE_C_COMPILER_LAUNCHER or CMAKE_CXX_COMPILER_LAUNCHER is already set (e.g. to ccache), the SLANG_USE_SCCACHE option is ignored to avoid conflicts.

Debugging

See the documentation on debugging.

Distributing

Versioned Libraries

As of v2025.21, the Slang libraries on Mac and Linux use versioned filenames. The public ABI for Slang libraries in general is not currently stable, so in accordance with semantic versioning conventions, the major version number for dynamically linkable libraries is currently 0. Due to the unstable ABI, releases are designed so that downstream users will be linked against the fully versioned library filenames (e.g., libslang-compiler.so.0.2025.21 instead of libslang-compiler.so).

Slang libraries for Windows do not have an explicit version in the library filename, but the the same guidance about stability of the ABI applies.

Downstream users of Slang distributing their products as binaries should therefor on all platforms, including Windows redistribute the Slang libraries they linked against, or otherwise communicate the specific version dependency to their users. It is not the case that a user of your product can just install any recent Slang release and have an installation of Slang that works for any given binary.

More niche topics

CMake options

Option

Default

Description

SLANG_VERSION

Latest v* tag

The project version, detected using git if available

SLANG_DXC_BINARY_URL

Stable DXC release URL

URL of the prebuilt DXC binary archive to download; overrides the default release URL and skips GLIBC auto-detection on Linux

SLANG_DXC_BUILD_FROM_SOURCE

Unset

ON: build DXC from source on Windows, Linux, and macOS; OFF: use prebuilt when available; unset: build from source on macOS and auto-select on native Linux x86_64 (see DXC GLIBC auto-detection)

SLANG_EMBED_CORE_MODULE

TRUE

Build slang with an embedded version of the core module

SLANG_EMBED_CORE_MODULE_SOURCE

TRUE

Embed the core module source in the binary

SLANG_ENABLE_DXIL

TRUE

Enable generating DXIL using DXC

SLANG_ENABLE_ASAN

FALSE

Enable ASAN (address sanitizer)

SLANG_ENABLE_COVERAGE

FALSE

Enable code coverage instrumentation

SLANG_ENABLE_FULL_IR_VALIDATION

FALSE

Enable full IR validation (SLOW!)

SLANG_ENABLE_VALIDATION_VM_BYTECODE

TRUE

Enable VM bytecode validation in the bytecode interpreter. Disabling skips runtime safety checks for malformed bytecode.

SLANG_ENABLE_IR_BREAK_ALLOC

OFF (Release), ON (Debug)

Enable IR BreakAlloc functionality for debugging.

SLANG_ENABLE_GFX

TRUE

Enable gfx targets (deprecated)

SLANG_ENABLE_SLANGD

TRUE

Enable language server target

SLANG_ENABLE_SLANGC

TRUE

Enable standalone compiler target

SLANG_ENABLE_SLANGI

TRUE

Enable Slang interpreter target

SLANG_ENABLE_SLANGRT

TRUE

Enable runtime target

SLANG_ENABLE_SLANG_GLSLANG

TRUE

Enable glslang dependency and slang-glslang wrapper target

SLANG_ENABLE_TESTS

TRUE

Enable test targets, requires SLANG_ENABLE_SLANG_RHI; some tests require other CMake options

SLANG_ENABLE_EXAMPLES

TRUE

Enable example targets, requires SLANG_ENABLE_SLANG_RHI

SLANG_ENABLE_REPLAYER

TRUE

Enable slang-replay tool

SLANG_ENABLE_PCH

TRUE

Enable precompiled headers for faster builds (auto-disabled when using sccache)

SLANG_STANDARD_MODULE_DEVELOP_BUILD

TRUE

Enable development build for standard modules (enables UNIT_TEST macro); disable for release builds

SLANG_LIB_TYPE

SHARED

How to build the slang library

SLANG_ENABLE_RELEASE_DEBUG_INFO

TRUE

Enable generating debug info for Release configs

SLANG_ENABLE_RELEASE_LTO

FALSE

Enable LTO for Release builds

SLANG_ENABLE_SPLIT_DEBUG_INFO

TRUE

Enable generating split debug info for Debug and RelWithDebInfo configs

SLANG_SLANG_LLVM_FLAVOR

FETCH_BINARY_IF_POSSIBLE

How to set up llvm support

SLANG_SLANG_LLVM_BINARY_URL

System dependent

URL specifying the location of the slang-llvm prebuilt library

SLANG_USE_SCCACHE

FALSE

Use sccache as compiler launcher (auto-disables PCH)

SLANG_GENERATORS_PATH

``

Path to an installed all-generators target for cross compilation

SLANG_IGNORE_ABORT_MSG

FALSE

Suppress the Windows modal abort dialog at compile time (baked into all built executables; recommended for unattended/LLM-driven builds)

DXC GLIBC auto-detection

When SLANG_DXC_BUILD_FROM_SOURCE is unset on native Linux x86_64 (and SLANG_DXC_BINARY_URL is not set), CMake downloads the prebuilt DXC binary at configure time and inspects the GLIBC requirements of both libdxcompiler.so and libdxil.so. If either library requires a newer GLIBC than the system provides, or if the requirement or system GLIBC version cannot be detected, DXC is built from source instead. Successful detection results are cached in stamp files so subsequent reconfigures are fast. For example, if a DXC Linux prebuilt requires GLIBC 2.38 and the host provides an older GLIBC, CMake selects the source-build path. On macOS, Microsoft does not publish a prebuilt DXC package, so the default configuration builds DXC from source unless SLANG_DXC_BINARY_URL is set to a custom archive.

flowchart TD
    Start["Configure DXC support"] --> BuildFromSource{"SLANG_DXC_BUILD_FROM_SOURCE"}
    BuildFromSource -->|ON| Source["Build DXC from source"]
    BuildFromSource -->|OFF| Prebuilt["Use a prebuilt binary when available"]
    BuildFromSource -->|unset| CustomUrl{"SLANG_DXC_BINARY_URL set?"}
    CustomUrl -->|yes| CustomPrebuilt["Use custom prebuilt URL and skip GLIBC detection"]
    CustomUrl -->|no| MacOS{"macOS?"}
    MacOS -->|yes| Source
    MacOS -->|no| NativeLinux{"Native Linux x86_64?"}
    NativeLinux -->|yes| Probe["Download Linux prebuilt and inspect GLIBC requirements"]
    Probe --> Compatible{"Detected requirements are compatible with host GLIBC?"}
    Compatible -->|yes| LinuxPrebuilt["Use Linux prebuilt binary"]
    Compatible -->|no or unknown| Source
    NativeLinux -->|no| OfficialPrebuilt{"Official prebuilt exists for platform?"}
    OfficialPrebuilt -->|yes| Prebuilt
    OfficialPrebuilt -->|no| Unavailable["DXC unavailable unless built from source"]
  • ON: build DXC from source on Windows, Linux, and macOS; on other platforms, DXC is unavailable.

  • OFF: use the prebuilt binary when one is available and skip the GLIBC check; on non-x86_64 Linux and macOS, DXC is unavailable unless SLANG_DXC_BINARY_URL is set to a custom prebuilt for that architecture/platform.

  • unset on native non-x86_64 Linux (e.g. ARM64): DXC is unavailable because no official prebuilt binary exists; set ON to build DXC from source.

  • unset on macOS: build DXC from source unless SLANG_DXC_BINARY_URL is set to a custom prebuilt.

  • unset while cross-compiling for Linux x86_64: skip GLIBC detection because the target system cannot be probed at configure time.

The source-build path clones DXC plus LLVM/Clang submodules on the first run and can take tens of minutes to configure and build; later reconfigures and incremental builds use stamp files and build outputs to skip repeated work.

Optional backend and test dependencies

The following options relate to optional dependencies for additional backends and running additional tests. Left unchanged they are auto detected, however they can be set to OFF to prevent their usage, or set to ON to make it an error if they can’t be found.

Option

CMake hints

Notes

SLANG_ENABLE_CUDA

CUDAToolkit_ROOT CUDA_PATH

Enable running tests with the CUDA backend, doesn’t affect the targets Slang itself supports

SLANG_ENABLE_OPTIX

Optix_ROOT_DIR

Requires CUDA

SLANG_ENABLE_NVAPI

NVAPI_ROOT_DIR

Only available for builds targeting Windows

SLANG_ENABLE_AFTERMATH

Aftermath_ROOT_DIR

Enable Aftermath in GFX, and add aftermath crash example to project

SLANG_ENABLE_XLIB

Build gfx and platform with Xlib to support windowed apps on Linux

Advanced options

Option

Default

Description

SLANG_ENABLE_DX_ON_VK

FALSE

Enable running the DX11 and DX12 tests on non-WARP Windows platforms via vkd3d-proton, requires system-provided d3d headers

SLANG_ENABLE_SLANG_RHI

TRUE

Enable building and using slang-rhi for tests

SLANG_USE_SYSTEM_MINIZ

FALSE

Build using system Miniz library instead of the bundled version in ./external

SLANG_USE_SYSTEM_LZ4

FALSE

Build using system LZ4 library instead of the bundled version in ./external

SLANG_USE_SYSTEM_VULKAN_HEADERS

FALSE

Build using system Vulkan headers instead of the bundled version in ./external

SLANG_USE_SYSTEM_SPIRV_HEADERS

FALSE

Build using system SPIR-V headers instead of the bundled version in ./external

SLANG_USE_SYSTEM_UNORDERED_DENSE

FALSE

Build using system unordered dense instead of the bundled version in ./external

SLANG_USE_SYSTEM_SPIRV_TOOLS

FALSE

Build using system SPIR-V tools library instead of the bundled version in ./external

SLANG_USE_SYSTEM_GLSLANG

FALSE

Build using system glslang library instead of the bundled version in ./external

SLANG_SPIRV_HEADERS_INCLUDE_DIR

``

Use this specific path to SPIR-V headers instead of the bundled version in ./external

SLANG_ENABLE_SPIRV_TOOLS_MIMALLOC

FALSE (TRUE on Windows)

Enable mimalloc allocator for SPIRV-Tools to improve compilation performance

SLANG_ENABLE_SPIRV_OPT_MERGE_RETURN

TRUE

Will be removed. Register the paired SPIRV-Tools MergeReturnPass + InlineExhaustivePass sequence in the slang-glslang SPIR-V optimizer pipeline; the TRUE default preserves existing SPIR-V output, and FALSE opts into the temporary workaround for SPIRV-Tools#6711

SLANG_EXCLUDE_DAWN

FALSE on Windows, TRUE elsewhere

Exclude Dawn WebGPU support from the build

SLANG_EXCLUDE_TINT

FALSE

Exclude slang-tint from the build (only relevant on Windows x64)

SLANG_ENABLE_TIME_TRACE

FALSE

Enable Clang time trace profiling for build analysis (Clang only)

LLVM Support

There are several options for getting llvm-support:

  • Use a prebuilt binary slang-llvm library: -DSLANG_SLANG_LLVM_FLAVOR=FETCH_BINARY or -DSLANG_SLANG_LLVM_FLAVOR=FETCH_BINARY_IF_POSSIBLE (this is the default)

    • You can set SLANG_SLANG_LLVM_BINARY_URL to point to a local libslang-llvm.so/slang-llvm.dll or set it to a URL of an zip/archive containing such a file

    • If this isn’t set then the build system constructs the download URL from the current git tag (e.g. v2025.21). Git tags must be available locally; if they are missing the build will warn and skip slang-llvm. Fetch them with git fetch --tags (or git fetch https://github.com/shader-slang/slang.git 'refs/tags/*:refs/tags/*' when cloning from a fork).

    • If SLANG_SLANG_LLVM_BINARY_URL is FETCH_BINARY_IF_POSSIBLE then in the case that a prebuilt binary can’t be found then the build will proceed as though DISABLE was chosen

  • Use a system supplied LLVM: -DSLANG_SLANG_LLVM_FLAVOR=USE_SYSTEM_LLVM, you must have llvm-21.1 and a matching libclang installed. It’s important that either:

    • You don’t end up linking to a dynamic libllvm.so, this will almost certainly cause multiple versions of LLVM to be loaded at runtime, leading to errors like opt: CommandLine Error: Option 'asm-macro-max-nesting-depth' registered more than once!. Avoid this by compiling LLVM without the dynamic library.

    • Anything else which may be linked in (for example Mesa, also dynamically loads the same llvm object)

  • Do not enable LLVM support: -DSLANG_SLANG_LLVM_FLAVOR=DISABLE

To build only a standalone slang-llvm, you can run:

cmake --workflow --preset slang-llvm

This will generate build/dist-release/slang-slang-llvm.zip containing the library. This, of course, uses the system LLVM to build slang-llvm, otherwise it would just be a convoluted way to download a prebuilt binary.

Cross compiling

Slang generates some code at build time, using generators build from this codebase. Due to this, for cross compilation one must already have built these generators for the build platform. Build them with the generators preset, and pass the install path to the cross building CMake invocation using SLANG_GENERATORS_PATH

Non-Windows platforms:

# build the generators
cmake --workflow --preset generators --fresh
mkdir build-platform-generators
cmake --install build --config Release --prefix build-platform-generators --component generators
# reconfigure, pointing to these generators
# Here is also where you should set up any cross compiling environment
cmake \
  --preset default \
  --fresh \
  -DSLANG_GENERATORS_PATH=build-platform-generators/bin \
  -Dwhatever-other-necessary-options-for-your-cross-build \
  # for example \
  -DCMAKE_C_COMPILER=my-arch-gcc \
  -DCMAKE_CXX_COMPILER=my-arch-g++
# perform the final build
cmake --workflow --preset release

Windows

# build the generators
cmake --workflow --preset generators --fresh
mkdir build-platform-generators
cmake --install build --config Release --prefix build-platform-generators --component generators
# reconfigure, pointing to these generators
# Here is also where you should set up any cross compiling environment
# For example
./vcvarsamd64_arm64.bat
cmake \
  --preset default \
  --fresh \
  -DSLANG_GENERATORS_PATH=build-platform-generators/bin \
  -Dwhatever-other-necessary-options-for-your-cross-build
# perform the final build
cmake --workflow --preset release

Example cross compiling with MSVC to windows-aarch64

One option is to build using the ninja generator, which requires providing the native and cross environments via vcvarsall.bat

vcvarsall.bat
cmake --workflow --preset generators --fresh
mkdir generators
cmake --install build --prefix generators --component generators
vsvarsall.bat x64_arm64
cmake --preset default --fresh -DSLANG_GENERATORS_PATH=generators/bin
cmake --workflow --preset release

Another option is to build using the Visual Studio generator which can find this automatically

cmake --preset vs2022 # or --preset vs2019, vs2026
cmake --build --preset generators # to build from the CLI
cmake --install build --prefix generators --component generators
rm -rf build # The Visual Studio generator will complain if this is left over from a previous build
cmake --preset vs2022 --fresh -A arm64 -DSLANG_GENERATORS_PATH=generators/bin
cmake --build --preset release

Nix

This repository contains a Nix flake (not officially supported or tested), which provides the necessary prerequisites for local development. Also, if you use direnv, you can run the following commands to have the Nix environment automatically activate when you enter your clone of this repository:

echo 'use flake' > .envrc
direnv allow

Building with an older CMake

Because older CMake versions don’t support all the features we want to use in CMakePresets, you’ll have to do without the presets. Something like the following

cmake -B build -G Ninja
cmake --build build -j

Specific supported compiler versions

GCC 11.4 and 13.3 are tested in CI and is the recommended minimum version. GCC 10 is supported on a best-effort basis, i.e. PRs supporting this version are encouraged but it isn’t a continuously maintained setup.

MSVC 19 is tested in CI and is the recommended minimum version.

Clang 17.0 is tested in CI and is the recommended minimum version.

Static linking against libslang-compiler

To build statically, set the SLANG_LIB_TYPE flag in CMake to STATIC.

If linking against a static libslang-compiler.a you will need to link against some dependencies also if you’re not already incorporating them into your project.

${SLANG_DIR}/build/Release/lib/libslang-compiler.a
${SLANG_DIR}/build/Release/lib/libcompiler-core.a
${SLANG_DIR}/build/Release/lib/libcore.a
${SLANG_DIR}/build/external/miniz/libminiz.a
${SLANG_DIR}/build/external/lz4/build/cmake/liblz4.a

Deprecation of libslang and slang.dll filenames

In Slang v2025.21, the primary library for Slang was renamed, from libslang.so and slang.dll to libslang-compiler.so and slang-compiler.dll. (A similar change was made for macOS.) The reason behind this change was to address a conflict on the Linux target, where the S-Lang library of the same name is commonly preinstalled on Linux distributions. The same issue affected macOS, to a lesser extent, where the S-Lang library could be installed via brew. To make the Slang library name predictable and simplify downstream build logic, the Slang library name was changed on all platforms.

A change like this requires a period of transition, so on a temporary basis: Linux and macOS packages now include symlinks from the old filename to the new one. For Windows, a proxy library is provided with the old name, that redirects all functions to the new slang-compiler.dll. The rationale here is that applications with a complex dependency graph may have some components still temporarily using slang.dll, while others have been updated to use slang-compiler.dll. Using a proxy library for slang.dll ensures that all components are using the same library, and avoids any potential state or heap-related issues from an executable sharing data structures between the two libraries.

These backwards compatability affordances, namely the proxy slang.dll and slang.lib (for Windows) and the libslang.so and libslang.dylib symlinks (for Linux and macOS), will be removed at the end of 2026. Until that time, they will be present in the github release packages for downstream use. Downstream packaging may or may not choose to distribute them, at their discretion. We strongly encourage downstream users of Slang to move to the new library names as soon as they are able.

Notes

[^1] below 3.25, CMake lacks the ability to mark directories as being system directories (https://cmake.org/cmake/help/latest/prop_tgt/SYSTEM.html#prop_tgt:SYSTEM), this leads to an inability to suppress warnings originating in the dependencies in ./external, so be prepared for some additional warnings.