fix: statically link MSVC CRT to remove VC++ Redistributable dependency#427
Merged
DennisDyallo merged 6 commits intomainfrom Mar 17, 2026
Merged
fix: statically link MSVC CRT to remove VC++ Redistributable dependency#427DennisDyallo merged 6 commits intomainfrom
DennisDyallo merged 6 commits intomainfrom
Conversation
…cy (#391) NativeShims on Windows dynamically linked VCRUNTIME140.dll and api-ms-win-crt-* DLLs, causing DllNotFoundException on machines without the VC++ Redistributable. Sets CMAKE_MSVC_RUNTIME_LIBRARY to /MT (static) and adds CI verification via dumpbin to prevent regression. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… readme Improves readability of CMakeLists.txt with section banners, inline comments explaining compiler/linker flags, and descriptive annotations on source files and link libraries. Adds static CRT note to NativeShims readme. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The GitHub Actions windows-2022 runner doesn't have dumpbin on PATH by default. Switched to cmd shell and call vcvars64.bat to set up the VS developer environment before running the import check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CMAKE_MSVC_RUNTIME_LIBRARY requires CMake policy CMP0091 (introduced in 3.15). With cmake_minimum_required at 3.13, the policy defaulted to OLD and the /MT flag was silently ignored, leaving the dynamic CRT linkage in place. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When findstr finds no matches (the success case), it returns exit code 1 which cmd.exe propagates as the script exit code. Adding explicit exit /b 0 after the success path ensures the step passes when no CRT deps are found. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dainnilsson
approved these changes
Mar 17, 2026
DennisDyallo
added a commit
that referenced
this pull request
Mar 30, 2026
Brings PR #427 (static CRT linking, CMake fixes) and 1.15.2 release bookkeeping into develop. Resolved conflict in build-nativeshims.yml by keeping both the CRT verification step (from main) and the updated upload-artifact v7.0.0 (from develop). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #391 —
Yubico.NativeShims.dllon Windows dynamically linkedVCRUNTIME140.dlland 9api-ms-win-crt-*UCRT forwarding DLLs, causingDllNotFoundExceptionon machines without the VC++ Redistributable installed (e.g., bare Windows 11 Home on new Dell hardware).Changes
CMAKE_MSVC_RUNTIME_LIBRARYtoMultiThreaded(/MT) in the WIN32 block ofCMakeLists.txt, statically linking the C runtime into the DLL. This is consistent with the existingx64-windows-staticvcpkg triplet which already statically links OpenSSL.cmake_minimum_requiredfrom 3.13 to 3.15 — required for CMake policy CMP0091 which enables theCMAKE_MSVC_RUNTIME_LIBRARYvariable. Without this, the/MTflag was silently ignored.dumpbin /importsthat inspects all three Windows architecture builds (x64, x86, arm64) and fails the build if any VC++ Redistributable dependencies are detected.CMakeLists.txtfor improved readability.Yubico.NativeShims/readme.md.Passing build
https://github.com/Yubico/Yubico.NET.SDK/actions/runs/23155104306/job/67267560977
Licensing review
Does static CRT linking require special licensing?
No. Static linking with
/MTis not governed by the REDIST list. The REDIST list exclusively covers redistribution of separate files (DLLs, merge modules, vcredist installers). With/MT, the CRT code is embedded into the binary — no separate CRT files are distributed.What does Microsoft's own documentation say?
Microsoft's CRT library features documentation explicitly lists the static CRT libraries as standard build options:
libucrt.lib/MTlibvcruntime.lib/MTlibcmt.lib/MTKey observations:
libucrt.lib,libvcruntime.lib,libcmt.lib) carry no "Not redistributable" markerlibucrtd.lib,libvcruntimed.lib,libcmtd.lib) are explicitly marked "Not redistributable"Our build satisfies all requirements
windows-2022runners with VS 2022 Enterprisebuild-windows.ps1builds--config Releaseexclusively/MTin Release,/MTdonly hypothetically in DebugWhy full static (
/MT) over hybrid linking?Microsoft supports a hybrid approach (static
vcruntime, dynamic UCRT). We chose full static because:VCRUNTIME140.dlland UCRT forwardersTrade-offs
/MT) — this PR/MD) — beforeThe security patching trade-off is minimal — NativeShims uses CRT for basic operations (
malloc,memcpy), and the SDK ships regular releases that incorporate updated static CRT at build time.Test plan
build-nativeshimsworkflow passes on Windows (all 3 architectures)VCRUNTIMEorapi-ms-win-crt-*imports in built DLLsWIN32block)🤖 Generated with Claude Code