In the SKSE ecosystem, your plugin must be built as a shared library (a Windows DLL), not a static library. Here’s why and how:

  1. SKSE loads your plugin as a DLL
    SKSE discovers and loads every plugin by looking for *.dll files in its SKSE/plugins folder. If you try to build a static library (.lib), SKSE will never load it.

  2. CMake configuration
    In your CMakeLists.txt you should declare:

    add_library(MyPlugin SHARED src/Plugin.cpp src/ScreenCapture.cpp # …etc. ) # Export all symbols so SKSE can find your registration functions if(MSVC) set_target_properties(MyPlugin PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) endif()

    • SHARED tells CMake to produce a DLL.

    • WINDOWS_EXPORT_ALL_SYMBOLS makes every non-static symbol available, which saves you from writing __declspec(dllexport) on each registration function.

  3. Use the Dynamic CRT
    Because you’re injecting into Skyrim’s process (which itself is built with the dynamic CRT), you should also use the DLL version of the C runtime:

    # For CMake ≥3.15 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")

    This ensures your plugin links against MSVCRT.dll (or the correct MSVC runtime DLL) rather than pulling in its own static CRT, which can lead to heap‐corruption and duplicate runtime state.

  4. Linking against static or import libs
    You will typically link against:

    • SKSE’s import library (e.g. skse64.lib)

    • CommonLibSSE-NG’s static library (CommonLibSSE-NG.lib)

    • Any other static libs you need (DirectXTK, WIC helpers, etc.)

    But your output remains a DLL.

Quick checklist

  • add_library(… SHARED …) in CMake

  • WINDOWS_EXPORT_ALL_SYMBOLS (or decorate symbols manually)

  • CMAKE_MSVC_RUNTIME_LIBRARY = MultiThreadedDLL (i.e. /MD or /MDd)

  • ✅ Link against SKSE’s import .lib and your other dependencies

With that setup, CMake will produce a plugin DLL that SKSE can load at runtime.