Skip to content

Building

NuclearMeltdown edited this page Aug 24, 2026 · 3 revisions

Building

Requirements

  • Visual Studio 2022 with the Desktop C++ workload
  • CMake (the one that ships with Visual Studio is used automatically)

No external dependencies. Dear ImGui is vendored in third_party/; everything else is a Windows SDK library.

build.bat

The result is CapView.exe in the repository root, around 1.6 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

Three targets:

Target
CapView the program itself, WIN32 subsystem
capview_vcam the virtual camera's media source DLL
capview_probe a console tool that prints the devices, formats and inputs CapView sees

capview_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 CapView.exe as an RT_RCDATA resource:

set(VCAM_DLL_PATH "${CMAKE_BINARY_DIR}/bin/capview_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. CapView never needs elevation. The one operation that does — registering the virtual camera's media source — spawns regsvr32 through ShellExecuteEx with the runas verb rather than elevating the whole program.

Where things get written

Everything lives beside the executable:

  • CapView.json — configuration
  • shader-*.cso — the compiled shader cache
  • capview_vcam_<hash>.dll — written out when the camera is installed
  • ffmpeg\ or ffmpeg.exe — 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 CapView.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