obs-windows-building
npx skills add https://github.com/meriley/claude-code-skills --skill obs-windows-building
Agent 安装分布
Skill 文档
OBS Windows Building
Purpose
Build OBS Studio plugins for Windows using MSVC (Visual Studio) or MinGW. Covers symbol exports, Windows-specific linking, platform source files, and DLL verification.
When NOT to Use
- Cross-compiling from Linux â Use obs-cross-compiling
- Qt/C++ frontend development â Use obs-cpp-qt-patterns
- Audio plugin implementation â Use obs-audio-plugin-writing
- Code review â Use obs-plugin-reviewing
Quick Start: Windows Build in 4 Steps
Step 1: Install Prerequisites
Visual Studio 2022:
- Workload: “Desktop development with C++”
- Individual components: CMake, Windows SDK
Or MinGW (via MSYS2):
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake
Step 2: Create Windows CMake Preset
{
"name": "windows-x64",
"displayName": "Windows x64",
"description": "Build for Windows x64 with Visual Studio",
"binaryDir": "${sourceDir}/build_x64",
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"cacheVariables": {
"OBS_SOURCE_DIR": "${sourceDir}/.deps/windows-x64/obs-studio-32.0.4"
}
}
Step 3: Create .def Export File
Create src/plugin.def:
LIBRARY my-plugin
EXPORTS
obs_module_load
obs_module_unload
obs_module_post_load
obs_module_ver
obs_module_set_pointer
obs_current_module
obs_module_description
obs_module_set_locale
obs_module_free_locale
obs_module_get_string
obs_module_text
Step 4: Configure CMakeLists.txt
if(WIN32)
# Windows system libraries
target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 comctl32)
# Export module functions via .def file
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
# MinGW
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/src/plugin.def -Wl,--unresolved-symbols=ignore-all"
)
else()
# MSVC
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/src/plugin.def"
)
endif()
endif()
MSVC vs MinGW Comparison
| Aspect | MSVC | MinGW |
|---|---|---|
| IDE | Visual Studio | VS Code, CLion |
| Debugging | Full VS debugger | GDB |
| Build speed | Slower | Faster |
| ABI | Native Windows | GCC-based |
| Qt compat | Requires MSVC Qt | Works with MinGW Qt |
| CI/CD | Windows runner | Linux cross-compile |
Recommendation: Use MSVC for native Windows development, MinGW for CI cross-compilation.
Symbol Export with .def Files
Why .def Files?
OBS loads plugins at runtime and looks up functions by name. Without explicit exports:
- MSVC may not export functions without
__declspec(dllexport) - MinGW may export by ordinal only (numbers, not names)
.def File Format
; Comments start with semicolon
LIBRARY my-plugin ; DLL name
EXPORTS
obs_module_load ; Function to export
obs_module_unload
; Add all OBS_DECLARE_MODULE() and OBS_MODULE_USE_DEFAULT_LOCALE() functions
MSVC Linker Flag
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/src/plugin.def"
)
MinGW Linker Flag
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/src/plugin.def -Wl,--unresolved-symbols=ignore-all"
)
Windows System Libraries
Common Libraries
| Library | Purpose | Header |
|---|---|---|
ws2_32 |
Windows Sockets 2 (networking) | <winsock2.h> |
comctl32 |
Common controls (UI widgets) | <commctrl.h> |
user32 |
Windows API (windows, messages) | <windows.h> |
kernel32 |
Core Windows API | <windows.h> |
ole32 |
COM support | <objbase.h> |
uuid |
GUID/UUID support | <guiddef.h> |
CMake Linking
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE
ws2_32 # Sockets
comctl32 # UI controls
)
endif()
Include Order (CRITICAL)
/* WRONG - will cause compile errors */
#include <windows.h>
#include <winsock2.h>
/* CORRECT - winsock2.h must come first */
#include <winsock2.h>
#include <windows.h>
Platform-Specific Source Files
Directory Structure
src/
âââ plugin-main.c # Cross-platform
âââ my-source.c # Cross-platform
âââ platform/
âââ socket-posix.c # Linux/macOS
âââ socket-win32.c # Windows
CMakeLists.txt Pattern
# Common sources
target_sources(${PROJECT_NAME} PRIVATE
src/plugin-main.c
src/my-source.c
)
# Platform-specific sources
if(WIN32)
target_sources(${PROJECT_NAME} PRIVATE
src/platform/socket-win32.c
)
else()
target_sources(${PROJECT_NAME} PRIVATE
src/platform/socket-posix.c
)
endif()
Platform Header Pattern
/* platform.h - Platform abstraction */
#pragma once
#ifdef _WIN32
#include "platform/socket-win32.h"
#else
#include "platform/socket-posix.h"
#endif
/* Common interface */
int platform_socket_init(void);
void platform_socket_cleanup(void);
int platform_socket_send(const char *host, int port, const void *data, size_t len);
Windows-Specific Code Patterns
Winsock Initialization
/* socket-win32.c */
#include <winsock2.h>
#include <ws2tcpip.h>
static bool winsock_initialized = false;
int platform_socket_init(void)
{
WSADATA wsa_data;
int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (result != 0) {
return -1;
}
winsock_initialized = true;
return 0;
}
void platform_socket_cleanup(void)
{
if (winsock_initialized) {
WSACleanup();
winsock_initialized = false;
}
}
Windows API Loader Pattern
For optional Windows APIs (not always available):
/* api-loader.c */
#include <windows.h>
typedef BOOL (WINAPI *SetProcessDpiAwarenessContext_t)(DPI_AWARENESS_CONTEXT);
static SetProcessDpiAwarenessContext_t pSetProcessDpiAwarenessContext = NULL;
void load_optional_apis(void)
{
HMODULE user32 = GetModuleHandleW(L"user32.dll");
if (user32) {
pSetProcessDpiAwarenessContext = (SetProcessDpiAwarenessContext_t)
GetProcAddress(user32, "SetProcessDpiAwarenessContext");
}
}
void set_dpi_awareness(void)
{
if (pSetProcessDpiAwarenessContext) {
pSetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
}
OBS Plugin Installation Paths
User Installation (Recommended)
%APPDATA%\obs-studio\plugins\my-plugin\
âââ bin\
â âââ 64bit\
â âââ my-plugin.dll
âââ data\
âââ locale\
âââ en-US.ini
System Installation
C:\ProgramData\obs-studio\plugins\my-plugin\
âââ bin\
â âââ 64bit\
â âââ my-plugin.dll
âââ data\
âââ locale\
âââ en-US.ini
CMake Install Target
if(WIN32)
set(OBS_PLUGIN_DIR "$ENV{APPDATA}/obs-studio/plugins/${PROJECT_NAME}")
endif()
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${OBS_PLUGIN_DIR}/bin/64bit
)
install(DIRECTORY data/locale
DESTINATION ${OBS_PLUGIN_DIR}/data
)
DLL Verification
Check File Type
:: PowerShell
Get-Item my-plugin.dll | Select-Object Name, Length
Check Exports with dumpbin (MSVC)
dumpbin /exports my-plugin.dll
Expected output:
ordinal hint RVA name
1 0 00001000 obs_current_module
2 1 00001010 obs_module_description
3 2 00001020 obs_module_load
...
Check Exports with objdump (MinGW)
x86_64-w64-mingw32-objdump -p my-plugin.dll | grep -A 50 "Export Table"
FORBIDDEN Patterns
| Pattern | Problem | Solution |
|---|---|---|
| Missing .def file | Functions not exported by name | Create plugin.def |
| Wrong include order | winsock2 errors | Include winsock2.h before windows.h |
| Missing WSAStartup | Socket functions fail | Call platform_socket_init() |
| Hardcoded paths | Breaks on other machines | Use %APPDATA% or relative paths |
| ANSI APIs | Unicode issues | Use wide (W) APIs or UTF-8 |
| Missing /DEF linker flag | No exports in DLL | Add LINK_FLAGS in CMake |
Troubleshooting
Plugin Not Visible in OBS
Check:
- DLL is in
bin/64bit/subdirectory - Path is correct:
%APPDATA%\obs-studio\plugins\{name}\bin\64bit\ - DLL exports are present:
dumpbin /exports my-plugin.dll
“Entry Point Not Found” Error
Cause: Missing obs_module_load export
Fix: Ensure .def file includes obs_module_load and linker flag is set.
Winsock Errors
Symptom: Socket functions return -1 or WSANOTINITIALISED
Fix: Call WSAStartup() before any socket operations.
Unicode/ANSI Mismatch
Symptom: String corruption, “???” characters
Fix:
/* Use wide APIs or define UNICODE */
#define UNICODE
#define _UNICODE
#include <windows.h>
Build Commands
Visual Studio
:: Configure
cmake --preset windows-x64
:: Build
cmake --build --preset windows-x64 --config RelWithDebInfo
:: Install
cmake --install build_x64 --config RelWithDebInfo
MinGW (MSYS2)
# Configure
cmake -G "Ninja" -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
# Build
cmake --build build
# Install
cmake --install build
External Documentation
Context7
mcp__context7__query-docs
libraryId: "/obsproject/obs-studio"
query: "Windows plugin build Visual Studio MSVC"
Official References
- OBS Windows Build: https://obsproject.com/wiki/Building-OBS-Studio
- Visual Studio Docs: https://docs.microsoft.com/en-us/visualstudio/
- Windows SDK: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
Related Skills
- obs-cross-compiling – Cross-compile from Linux to Windows
- obs-cpp-qt-patterns – Qt frontend integration
- obs-plugin-developing – Plugin architecture overview
- obs-audio-plugin-writing – Audio plugin implementation
Related Agent
Use obs-plugin-expert for coordinated guidance across all OBS plugin skills.