🛠️

2023の Windows の c ランタイムライブラリ

2023/08/27に公開

Windows をクリーンにして開発環境を再整備。
clang + ucrt がよさそうなので関連して調査中。

各種ランタイム

コンパイラやビルド設定でリンクされるライブラリが変わる。
リンクされるライブラリが実行環境に含まれない場合に、配布物に含める必要が出てきてややこしい。

Cランタイム

msvcrt vs ucrt

msvcrt

VisualC 開発環境に含まれる感じ。
msvcrt は、VCのバージョンごとに違うので、
Microsoft Visual C++ Redistributable をインストーラーに含めてやるなど
対応が必要かもしれない。

ucrt

WindowsSdk(WindowsKits) に含まれる感じ。
ucrt の runtime は、Windows10 以降?のWindows に含まれるので配布物に含める必要がない

cygwin 系

cygwin, msys, msys2 などがある。
dll にリンクした場合パスを通す必要が。

MinGW

分類しづらいのでここに。

  • x86_64-pc-windows 向けのgcc
  • Windows.h などコンパイルできるようにする
  • gdi32.lib などリンクできるようにする

などの諸々のセット。
llvm-clang は Vc/WindowsKits 向けと MinGW 向けは別の環境であるようだ。
Vc/WindowsKits に msvcrt / ucrt の2バージョンがある。
つまり、

  • clang-vc-msvcrt
  • clang-vc-ucrt
  • clang-mingw-msvcrt
  • clang-mingw-ucrt

全部違うぽい。
この違いを本記事はメモしている。

C++ランタイム

libstdc++(gcc) vs libc++(llvm)。
dll にリンクした場合パスを通す必要が。

例外ランタイム?

libgcc_s(gcc) vs libunwind(llvm)。
dll にリンクした場合パスを通す必要が。

一覧

ucrt 用の triplet x86_64-pc-windows-ucrt あるのか確認中・・・

toolchain target c runtime c++ runtime 例外
msvc x86_64-pc-windows-msvc msvcrt msvcp?
msvc(ucrt) x86_64-pc-windows-ucrt? ucrt + vcruntime msvcp
msys2 x86_64-pc-windows-msys msys2 libstdc++ libgcc_s
msys2-mingw64 x86_64-pc-windows-gnu msvcrt libstdc++ libgcc_s
msys2-ucrt64 x86_64-pc-windows-ucrt? ucrt libstdc++ libgcc_s
llvm(公式 prebuilt) x86_64-pc-windows-msvc ucrt + vcruntime msvcp
llvm-mingw-ucrt x86_64-pc-windows-ucrt? ucrt libc++ libunwind
zig-0.11(clang-16) x86_64-pc-windows-msvc msvcrt static link ? static link ?

msvcrt と ucrt と vcruntime

https://learn.microsoft.com/ja-jp/cpp/c-runtime-library/crt-library-features?view=msvc-170

msvcrt

https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170

vcruntime

https://learn.microsoft.com/ja-jp/cpp/build/run-time-library-behavior?view=msvc-170

ucrt

https://developer.microsoft.com/ja-jp/windows/downloads/sdk-archive/

> D:/msys64/usr/bin/ldd build/hello.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffc22390000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffc20cf0000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffc1faa0000)
        MSVCP140D.dll => /c/WINDOWS/SYSTEM32/MSVCP140D.dll (0x7ffbd2b40000)
        VCRUNTIME140D.dll => /c/WINDOWS/SYSTEM32/VCRUNTIME140D.dll (0x7ffc05070000)
        VCRUNTIME140_1D.dll => /c/WINDOWS/SYSTEM32/VCRUNTIME140_1D.dll (0x7ffc0fda0000)
        ucrtbased.dll => /c/WINDOWS/SYSTEM32/ucrtbased.dll (0x7ffbc7f50000)
        ucrtbased.dll => /c/Windows/System32/ucrtbased.dll (0x19020710000)

msys2

MSYSTEM=MSYS

https://zenn.dev/ousttrue/articles/d64d9e31e57913

MSYSTEM=MINGW64

git for windows がこれぽい。

https://github.com/git-for-windows/git-sdk-64

MSYSTEM=UCRT64

地味に pthread も。

> D:/msys64/usr/bin/ldd build\hello.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffc58bf0000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffc57b80000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffc56070000)
        ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ffc56600000)
        libgcc_s_seh-1.dll => /ucrt64/bin/libgcc_s_seh-1.dll (0x7ffc452d0000)
        libwinpthread-1.dll => /ucrt64/bin/libwinpthread-1.dll (0x7ffc451d0000)
        libstdc++-6.dll => /ucrt64/bin/libstdc++-6.dll (0x7ffc1f000000)

llvm clang

  • clang-vc-msvcrt
  • clang-vc-ucrt
  • clang-mingw-msvcrt
  • clang-mingw-ucrt

公式 prebuilt

clnag-vc
vc をインストールしないと msvcrt へのリンクができなくて実験できない様子。

> D:/msys64/usr/bin/ldd build/hello.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffc22390000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffc20cf0000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffc1faa0000)
        MSVCP140D.dll => /c/WINDOWS/SYSTEM32/MSVCP140D.dll (0x7ffbd2e30000)
        VCRUNTIME140D.dll => /c/WINDOWS/SYSTEM32/VCRUNTIME140D.dll (0x7ffbed400000)
        ucrtbased.dll => /c/WINDOWS/SYSTEM32/ucrtbased.dll (0x7ffbc3690000)
        VCRUNTIME140_1D.dll => /c/WINDOWS/SYSTEM32/VCRUNTIME140_1D.dll (0x7ffc1c280000)

llvm-mingw

https://github.com/mstorsjo/llvm-mingw

release に msvcrt 向けと ucrt 向け両方のビルドがある。
ということは、コマンドラインで msvcrt / ucrt をスイッチするのではなく
開発環境にどっちを使うのかを組み込んでしまうということなのかもしれない。

https://qiita.com/syoyo/items/ad14912c983da94ad16e

:::message info
llvm-mingw の ucrt ビルドがよさそうな気がする。
:::

zig

zig-0.11

c++ 関連が static link ?
libstdc++ と libc++ のどちらなのか要調査。

> CC="zig cc" CXX="zig c++" cmake -S . -B build -G Ninja
> cmake --build build
> D:/msys64/usr/bin/ldd build\hello.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffc58bf0000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffc57b80000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffc56070000)
        msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffc57df0000)

cmake と meson のコンパイラ探索

どうも環境変数 PATH から、cccl をサーチして見つかったものを
デフォルトのツールチェインとしているぽい。

CC="zig cc" CXX="zig c++" cmake -S . -B build のように
環境変数 CCCXX から別名を指定できる。
PATH が通っていることが必用。

prebuit 配布物では どれがいいのか

target debug memo
clang-vc-msvcrt elf 本家prebuilt版?
clang-vc-ucrt - 未発見
clang-mingw-msvcrt elf llvm-mingw配布 / msys2-clang64
clang-mingw-ucrt elf llvm-mingw配布 これがよさそう?
gcc-mingw-msvcrt elf msys2-mingw64
gcc-mingw-ucrt elf msys2-ucrt
clang-mingw-msvcrt pdb zig-0.11

msvcrt / ucrt や libgcc_s / libunwind の切り替えは、
コマンドライン制御よりも開発環境にデフォルト値として埋め込んだ方がよさそうである。
llvm-mingw を研究すればやり方はわかるかも。

Discussion