Repository navigation
Building
-
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
dxcfor 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.batThe 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.
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 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.
/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.
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.