Skip to content

Building

NuclearMeltdown edited this page Oct 19, 2026 · 7 revisions

Building

Requirements

  • Visual Studio 2022 with the Desktop C++ workload

  • CMake (the one that ships with Visual Studio is used automatically)

  • Vulkan SDK, optional, for the Vulkan renderer: its headers, the loader's import library and dxc for SPIR-V

Dear ImGui is vendored in third_party/; everything else is a Windows SDK library. The Direct3D 11 shaders are compiled during the build with the SDK's fxc and carried in the executable, so the program never compiles at startup.

build.bat takes the SDK from VULKAN_SDK, or else from a VulkanSDK\<version> folder next to the repository, which the installer can be pointed at without touching the environment. Without one the build warns and makes a Direct3D 11 only program; -DQBLANK_VULKAN=OFF does the same on purpose. The released executable has both.

build.bat

The result is qBlank.exe in the repository root, about 2.4 MB, linked against the static CRT so it runs without redistributables.

Command
build.bat Release, then removes the build tree — only the executable is left
build.bat keep Release, keeps the build tree for incremental rebuilds
build.bat debug Debug configuration, keeps the build tree

findvs.bat locates the Visual Studio installation and its bundled CMake and Ninja.

Prebuilt executables are attached to each release.

What the build produces

Four targets:

Target
qBlank the program itself, WIN32 subsystem
qblank_vcam the virtual camera's DirectShow filter DLL
qblank_probe a console tool that prints the devices, formats and inputs qBlank sees
CapViewMigrator the bridge out of the old name, output name CapView.exe

The migrator goes to build\bin\migrator\ rather than next to the program, so that nothing which copies "the build" out of bin\ picks up an executable under the old name by accident. A release is the two files together — see Updates.

qblank_probe is a diagnostic and is not shipped. It is the fastest way to find out what a card is actually advertising without opening the program.

The media source rides inside the executable

The DLL is built first, then baked into qBlank.exe as an RT_RCDATA resource:

set(VCAM_DLL_PATH "${CMAKE_BINARY_DIR}/bin/qblank_vcam.dll")
configure_file("res/vcam_resource.rc.in" "${CMAKE_BINARY_DIR}/vcam_resource.rc" @ONLY)
# So the resource is rebuilt when the source changes rather than when the path does.
set_source_files_properties("${CMAKE_BINARY_DIR}/vcam_resource.rc"
                            PROPERTIES OBJECT_DEPENDS "${VCAM_DLL_PATH}")

That OBJECT_DEPENDS line matters. Without it the resource compiler only reruns when the generated .rc changes — and the .rc only contains a path, which does not change when the DLL behind it does. The resource would then quietly hold a stale DLL.

Shipping the DLL as a loose second file meant the two halves could be from different builds, which happened: Windows locks the file while the camera is in use, and replacing it failed silently. See Virtual camera.

A release is therefore one file.

Compiler and linker settings

/W3 /permissive- /Zc:__cplusplus /utf-8 /MP
$<$<CONFIG:Release>:/O2 /Oi /GL>
$<$<CONFIG:Release>:/LTCG /OPT:REF /OPT:ICF>
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
"/MANIFESTUAC:level='asInvoker' uiAccess='false'"

C++17. /utf-8 is not optional — the source carries German strings directly, and without it MSVC reads them in the system code page.

asInvoker in the manifest is deliberate. qBlank never needs elevation. The one operation that does — registering the virtual camera's filter — spawns regsvr32 through ShellExecuteEx with the runas verb rather than elevating the whole program.

Where things get written

Everything lives beside the executable:

  • qBlank.json — configuration
  • qblank_vcam_<hash>.dll — written out when the camera is installed
  • ffmpeg\ — ffmpeg's four libraries, if the download button was used

Nothing is written to the registry, except the virtual camera's machine-wide COM registration.

build.bat rescues ffmpeg and qBlank.json out of the build tree before deleting it, since the download button and the settings both land next to whichever executable was running.

Clone this wiki locally