W S L Template Stacks

A WSL C++ Template Project for GLFW-Skia applications

View project on GitHub


GLFW-Skia C++ Template - Windows Setup Instruction

MIT License Commercial Services Available

Introduction

This template is designed for use in conjunction with a WSL (Windows Subsystem for Linux) distribution running on a Windows 11 host. This section provides step-by-step instructions for setting up the native Windows build environment, including building the GLFW and Skia libraries from source.

The setup process involves:

  • Building GLFW 3.4 using Visual Studio and CMake
  • Building Skia graphics library with debug and release configurations
  • Configuring dependencies locally within your project folder for full customization

Note: This guide focuses on the Windows-native build setup. For the companion WSL/Linux setup, see the Linux Setup Guide.

Requirements for Windows

   📚 Visual Studio 2022 Community Edition (optional)
   📚 Visual Studio code (optional)
   📚 Python 3
   📚 PowerShell


Setup Instructions

This is the Windows part of a dual-platform development environment:

  • Windows Setup (This Page): Native development tools, Visual Studio, debugging
  • WSL Linux Setup: Cross-platform builds and Linux testing → Linux Setup Guide

Why both? You’ll develop primarily on Windows but can build and test Linux versions seamlessly through WSL.

💫 New experimental Setup with VSC Agent

For our New experimental Setup with VSC Agent See here This will try to use the VS Co-pilot agent to install the Windows part installation. This is experimental and may be changed.


Build GLFW library for Windows

GLFW Version 3.4 has a CMake file that generates Visual Studio projects, which can be built using Visual Studio 2022/2026 Community Edition in combination with the MSBuild tools. The dependency libraries (GLFW and Skia) are, in this project, installed within the project folder so that the entire project is self-contained in a single directory. This has the obvious disadvantage that the libraries cannot be reused across different projects (and thus must be re-installed and customized for each project). However, the advantage is that the libraries can be fully customized for the specific needs of the current project. You may choose to create a shared library installation, but this procedure assumes that the libraries are installed within the project in the folder: .\dependencies\win
We still believe this is the best approach, even for large libraries like Skia.

General procedure:

  • Launch a PowerShell terminal in the cloned GitHub project folder.
  • In your project folder, create the following folder if needed, then navigate to it: .\dependencies\win
  • Download glfw-3.4.zip into the above folder (result should be: .\dependencies\win\glfw-3.4.zip, rename to this if you have a newer sub-version)
  • For the next step, use a reliable extraction tool that does not skip hidden or system files and extracts the zip file in the correct location. After extraction, the files should be in the folder: .\dependencies\win\glfw-3.4\. I use the 7-Zip utility from here. When using the following command in a PowerShell CLI (in the mentioned folder), the zip will be extracted in the correct location: 7z x glfw-3.4.zip “-o.”

Build procedure (Dynamic DLL preferred / Static alternative)

The following procedure applies to both Dynamic (DLL) and Static library builds. Key differences are highlighted in the table below.

Differences between Dynamic and Static builds:

Aspect Dynamic (DLL) - Preferred Static
Output folder outdll outstatic
CMake flag -DBUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=OFF
Output files glfw3.dll + glfw3dll.lib(import lib) glfw3.lib
Output location ./outdll/src/Debug or ./outdll/src/Release ./outstatic/src/Debug or ./outstatic/src/Release

Build steps GLFW:

  • If not yet available make the output directory (choose based on your build type):
    mkdir project root\dependencies\win\glfw-3.4\outdll     # For Dynamic DLL
    mkdir project root\dependencies\win\glfw-3.4\outstatic  # For Static
  • Change to that directory
    project root\dependencies\win\glfw-3.4\outdll     # For Dynamic DLL
    project root\dependencies\win\glfw-3.4\outstatic  # For Static
  • Then run with Power-Shell (choose based on your build type):
    cmake .. -G "Visual Studio 17 2022" -A x64 -DBUILD_SHARED_LIBS=ON   # For Dynamic DLL
    cmake .. -G "Visual Studio 17 2022" -A x64 -DBUILD_SHARED_LIBS=OFF  # For Static
    • For Visual Studio 2026 use:
      cmake .. -G "Visual Studio 18 2026" -A x64 -DBUILD_SHARED_LIBS=ON   # For Dynamic DLL
      cmake .. -G "Visual Studio 18 2026" -A x64 -DBUILD_SHARED_LIBS=OFF  # For Static

      Note 1: Initial experimental support in cmake 4.2 (dec 2025). you can use the 2022 version to generate the VS project and compile later with 2026 Note 2: By default the latest installed SDK is use if you require and other add: -DCMAKE_SYSTEM_VERSION=10.0.19041.0

  • Next, use PowerShell to search for msbuild.exe versions (2022 and 2026) on the system, this is because we need the full path to msbuild.exe. Use this Power-shell command:
    & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
    -products * `
    -requires Microsoft.Component.MSBuild `
    -find MSBuild\**\Bin\MSBuild.exe
    
  • Now use the Full path to msbuild.exe to create the library, In the Power-Shell CLI run:
    & /path/to/msbuild GLFW.sln /p:Configuration=Debug /p:Platform=x64 

    Note: Update /p:Configuration=Debug to: /p:Configuration=Release for release builds

  • Then copy the generated library files to the project root:
    • Dynamic DLL: Copy glfw3.dll (and optionally glfw3dll.lib) from ./outdll/src/Debug or ./outdll/src/Release
    • Static: Copy glfw3.lib from ./outstatic/src/Debug or ./outstatic/src/Release>

    This ensures VS2022/VS2026 builds the selected library type in the appropriate src folder(i.e: src/debug), depending on the selected Solution Configuration in Visual Studio. For Dynamic DLL builds, make sure to copy the glfw3.dll file to your application executable folder at runtime.

Update CMake files

After building the GLFW library (as DLL or static) Update the ${PROJECT_SOURCE_DIR}/cmake/windows.cmake file, function: _SetExtraWindowsFolders() Make Sure to check and adjust the variables displayed below:

  • Check/Set the include folder variable GLFW_WIN_INCLUDE_DIR to:
    ${PROJECT_SOURCE_DIR}/dependencies/win/glfw-3.4/include
  • In case of:
    • Static linking
      • Make sure the path to the library folder GLFW_WIN_LIB_DIR is set to:
        ${PROJECT_SOURCE_DIR}/dependencies/win/glfw-3.4/outstatic/src/debug 
      • Make sure the variable GLFW_LIBS_WIN_LOCAL contains glfw3 the name of the .lib file (glfw3.lib)
    • Dynamic linking
      • Make sure the path to the library folder:GLFW_WIN_LIB_DIR is set to
        ${PROJECT_SOURCE_DIR}/dependencies/win/glfw-3.4/outdll/src/debug
      • Make sure the variable GLFW_LIBS_WIN_LOCAL contains glfw3dll the name of the import library file (glfw3dll.lib)
      • Make also sure the .dll file is available in your application’s runtime folder.

Built Skia library

  1. First Build the depot_tools. depot_tools is a collection of scripts/tools used to manage large Google Git projects
    • In your project folder Navigate, with your Power-Shell CLI, to the folder: .\dependencies\win or create it, if it does not exist
    • Clone the git repository:
      git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 
  • This creates a folder: .\dependencies\win\depot_tools add this to the system path and reopen the CLI
  • Test. Execute: gclient help → should display help information and in case of the first time opening, download it!

Built dependency Ninja if needed

  • Execute ninja --version When this returns a version Ninja is already build and you skip this and continue with the next section Build Skia Debug below. Make sure to use the correct dash!
  • If ninja is not installed Download it form here
  • Extract it in the project root under the subfolder: .\dependencies\win

    You can use and existing, more central installed ninja version, in this case

  • Make sure to add the installed folder with ninja.exe to your system PATH so that ninja.exe is available in your terminal(see warning below)

Path ninja must be before depot_tools

Ensure that the ninja path is defined before depot_tools in your PATH!
depot_tools includes a ninja.bat file that will break builds if used accidentally, this maya also result into vague build issues.

  • Test. Open a CLI and execute:
    ninja --version

Received an error?

When this command:ninja –version returns: python not found
This is because Windows is trying to run a fake python.exe from the Microsoft Store, instead of your real Python install!

Fix
Rename the python.exe and python3.exe files in the following folder to .bak or something similar. explorer “$env:LOCALAPPDATA\Microsoft\WindowsApps”

⚠️ Bonus round(when you’re extra unlucky — and you probably are): The file will be in use. Because why wouldn’t it be? Open a Power-shell in administrator mode and delete or rename the files.

Build Skia Debug

  • Check this: When you have built Skia before, especially if done in a previous project folder (i.e: ./other project/dependencies/win), check and remove the old System environment variables and paths, old system variables can impact the a new installation, so remove these:

    • Environment variable: EMSDK
    • Environment variable: EMSDK_NODE
    • Environment variable: EMSDK_PYTHON
    • Environment variable: JAVA_HOME only when points to a Skia subfolder
    • Environment Path: Remove the old paths to the Skia subfolders (usual at the top)
      📌Tip Use the following Powershell command to check the value of the variables: Get-ChildItem Env:EMSDK*
      ⚠️warning failing to do so may lead to nasty Skia build issues
  • In your project folder navigate to: .\dependencies\win
  • Clone Skia Execute command:
    git clone  --recursive https://skia.googlesource.com/skia.git 
  • Change cd to
    project root\dependencies\win\skia
  • Execute command:
    git checkout chrome/m126  # To checkout a stable build instead a the master branch (Use same as on Linux!) 
  • The following command will call a the Skia build script which uses depot_tools to get the dependencies:
  • Execute command:
    python tools\git-sync-deps 
    • Test: It should have created tools like gn and other dependencies, test type in the CLI:
      Execute command: .\bin\gn -version

Check for errors

Check for errors like: file name too long…

If you see this, your Skia build will fail. This is one of the most common causes (together the previous warning box) of strange or hard-to-diagnose build errors on Windows, especially with Skia or other large C++ projects.

Solution:
You must shorten the folder path. Try the following:
C:\libs\skia

📌 Many developers abandon deeply nested folder structures altogether for Skia and similar projects due to this issue.

  • Make sure to be in the folder:
    project root\dependencies\win\skia
  • create folder:
    mkdir out\Debug 
  • In the next steps we are going to Generate build files with GN (uses Ninja)
  • Execute this command in powershell CLI:
@"
is_debug = true
is_official_build = false
skia_use_gl = true
target_cpu = "x64"
skia_enable_fontmgr_empty = false
skia_use_angle = false
skia_use_icu = true
extra_cflags = ["/MDd", "/D_ITERATOR_DEBUG_LEVEL=2", "/GR"]
"@ | Out-File out\Debug\args.gn -Encoding ASCII
  • Execute in PowerShell CLI:
    .\bin\gn gen out\Debug

    This configures the debug build!

Alternative Manual generate build files

This give you the option to change arguments in a file that will be opened automatically, use this if you want to configure Skia manual

  • Make sure to be in the folder: project root\dependencies\win\skia
  • Execute: .\bin\gn args out\Debug
  • Paste the following into the editor that opens:

Editor opens past in this, and save & close the editor and gn will continue :
📌 Tip: use this command to display the valid options: gn args –list out/Debug</pre> </small>

  is_debug = true
  is_official_build = false
  skia_use_gl = true
  target_cpu = "x64"    
  skia_enable_fontmgr_empty = false      # Optional: enable full font manager
  skia_use_angle = false                 # Optional: disable ANGLE if using native OpenGL
  skia_use_icu = true                    # ICU required for Unicode support
  
  extra_cflags = [ "/MDd", "/D_ITERATOR_DEBUG_LEVEL=2", "/GR" ]             # Dynamic
   #extra_cflags = [ "/MTd", "/D_ITERATOR_DEBUG_LEVEL=2" ]            # Static
   #extra_ldflags = [ "/NODEFAULTLIB:LIBCMT", "/DEFAULTLIB:LIBCMTD" ] #
  
   /# DON't add these deprecated\removed options they may cause build errrors
   /# skia_enable_gpu = true               # IS Build ERROR!
  

─── ✦ ───

  • Activate the MS VC environmen, Not needed to call ‘vcvars64.bat’ gn can handled it self
  • Build it:
    ninja -C out\Debug

Build result should include files like:

  • out\Debug\skia.lib
  • out\Debug\libskia.a
  • out\Debug\obj\skia*.obj

  • Update the file ${PROJECT_SOURCE_DIR}/cmake/windows.cmake (function: _SetExtraWindowsFolders())
    make sure it contains:
    set(SKIA_WIN_CORE_INCLUDE "${PROJECT_SOURCE_DIR}/dependencies/win/skia")

    ⚠️ Don’t add the include folder! This folder is part of the include directive of the Skia files

  • Update the file ${PROJECT_SOURCE_DIR}/cmake/windows.cmake (function: _SetExtraWindowsFolders())
    make sure it contains:
    set(SKIA_WIN_LIBS "${PROJECT_SOURCE_DIR}/dependencies/win/skia/out/Debug"),
  • Ensure skiais added to the variable: SKIA_LIBS_WIN_LOCAL in the file cmake/windows.cmake

Build Skia Release

This will create the Skia release library

Install libjpeg-turbo
  • Navigate to: ./dependencies/win of the project root folder.
  • Clone the git library libjpeg-turbo from here
  • git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git 
  • Create build directory mkdir build
  • Change to the build output folder and(cd build)
  • Run ‘configure’:
     cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release 
  • Build it:
     cmake --build . --config Release 
  • Add the include and library folders manually to the Skia release build config below.
  • Make sure you return to the subfolder ./dependencies/win/skia of the project root folder!

Generate build files for Skia Release

  • Navigate to: ./dependencies/win/skia of the project root folder.
  • create folder: mkdir build if not exists
  • create folder: mkdir out\Release if not exists
  • Execute this command, from skia folder in powershell CLI:
@"
is_debug = false
is_official_build = true
skia_use_gl = true
target_cpu = "x64"
skia_use_system_zlib = false
skia_use_system_harfbuzz = false
skia_use_system_libpng = false
skia_use_system_libwebp = false
skia_use_expat = false
skia_use_icu = false  # no international text layout, no BiDi!
extra_cflags = [
"/I../../../libjpeg-turbo/src",  "/I../../../libjpeg-turbo/build"
]
"@ | Out-File out\Release\args.gn -Encoding ASCII
  • Configures the build(from skia folder):
    .\bin\gn gen out\Release

    This configures the Release build!

  • Make sure to be in the folder: project root\dependencies\win\skia
  • create the Build with:
    ninja -C out\Release

    This Creates the Release build!

This finalizes the build process for Windows

How to proceed, build Template project

Next you should be able to build the included template project for instructions see: The build project documentation

Appendix I - Common Pitfalls

⚠️ Common Pitfalls (Windows)

Setup your build environment in Windows is by definition more error sensitive then setting it up in Linux. Here a a few tips to help you avoid (build) issues:

  • 🚫 Avoid spaces or special characters in project paths
  • 🚫Make sure the official ninja.exe is first in PATH environment variable, not depot_tools\ninja.bat failing to do so will generate builds errors during build of Skia
  • 🚫Make sure Skia is not to deep nested, to avoid errors related to long path names, building Skia
  • 🚫 Avoid spaces or special characters in project paths:
  • ✅ Use full paths in gn.exe avoid relative path
  • 🔄 Always reopen the terminal after changing the environment


License
This file is part of: GLFW-Skia C++ Template Stack Copyright (c) 2025-2026 Nico Jan Eelhart.This repository is MIT licensed and free to use. For optional commercial support, customization, training, or long-term maintenance, see COMMERCIAL.md.


─── ✦ ───
















Maintained by NicoJanE. Generated by GitHub Pages.