使用 MSVC 编译时 msdpb* 文件的正确用法是什么
What is the proper usage of msdpb* files when compiling with MSVC
网上有很多关于 "missing mspdb140.dll" 的问题,还有其他类似的关于缺少 "mspdb*" DLL 的问题。有一些关于它的不同解决方案,包括:
- 重新安装Visual Studio
- 删除mspdb140.dll,它应该包含在 PATH 变量中
- 将 mspdb140.dll(和其他文件)添加到
<msvc-install-dir>\<subpath>
就我而言,我在 docker 容器中使用了 msvc 2019 安装程序的构建工具,然后安装了 msvc 2017 和 2019 的构建工具。如果我然后转到 C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64
,有两个文件夹:x64
和 x86
。如果我编写 powershell 命令 ls -Recurse -Filter "*mspdb*"
,我会得到以下输出:
Directory: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x64
mspdb140.dll
mspdbcmf.exe
mspdbcore.dll
mspdbsrv.exe
mspdbst.dll
Directory: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x6433
mspdbcmfui.dll
不过 HostX64\x86
目录中有 none 个这些文件。如果我以 x64 作为目标构建一切正常,但以 x86 作为目标,发布和调试构建都会出错。发布版本有:
ERROR: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x86\cl.exe
...
c1xx: fatal error C1356: unable to find mspdbcore.dll
调试版本有:
ERROR: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x86\cl.exe
...
c1xx: fatal error C1356: unable to find mspdb140.dll
这些构建使用 Qt 和 Qbs,Qbs 使用 vcvarsall.bat 来查找所需的环境变量。当安装了多个 msvc 工具链时,Qbs 中存在一个错误,这使得 Qbs 始终选择最新的一个。为了解决这个问题,我在每个构建作业中手动移动 vcvarsall.bat 并将其替换为:
call %~dp0vcvarsall_real.bat %1 store 10.0.17134.0 -vcvars_ver=14.16.27023 || exit /b 1
这会强制 vcvarsall 选择我想要的工具链 14.16.27023。
我通过简单地复制存在于 x64 目标的 DLL 和 EXE 文件(mspdbcmfui.dll
除外)设法修复了这两个编译错误。没有理由不复制最后一个 DLL,因为我只是在试验。即使程序可以编译,我也不知道我在做什么,这些文件在哪里使用,或者为什么某些目标缺少它们!在我的构建环境中不必手动复制文件会感觉更好。
我还检查了 Visual Studio 2017 Professional 的本地安装,然后 HostX64\x64 的文件名称相同,但是 HostX64\x86 我得到以下输出:
C:\Program Files (x86)\Microsoft Visual Studio17\WDProfesional\VC\Tools\MSVC.16.27023\bin\Hostx64\x86
...
mspdb140.dll
mspdbcore.dll
只有两个 DLL!
在 docker 图像中,我还有 MSVC 2019 的构建工具,所有主机和目标组合都包含所有 DLL 和 EXE。
总结一下:
- 为什么在某些情况下会丢失 DLL
- 解决这个问题的正确方法是什么?
- Visual Studio 编译与使用 vcvarsall.bat 和外部工具有何不同,因为它显然无需复制即可编译 DLLs/EXEs!
我仍然希望有人能解释更多关于为什么这些文件存在,如何正确使用它们,为什么它们在某些地方丢失,以及 Visual Studio 如何即使丢失也能编译文件。与此同时,我发现了这个:
我已经安装了 MSVC 2019 的构建工具,所以我转到文件夹 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64
和 运行 以下 powershell 命令:
(ls -Recurse "mspdb*").FullName | % { Get-FileHash $_ } | Sort-Object -Property Hash
得到这个输出:
Hash Path
--------------------------------------------------------------------------------------------------------------------------------------------
658D21DF98781D7C137FA213C3F3C2222C5D20A0F75BEB4929703406241379FA C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbcmf.exe
658D21DF98781D7C137FA213C3F3C2222C5D20A0F75BEB4929703406241379FA C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbcmf.exe
9664EE9A457B444E0D5A2F6A73A896375966BCF3864BBCD6B76AFEF496EC954C C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbcore.dll
9664EE9A457B444E0D5A2F6A73A896375966BCF3864BBCD6B76AFEF496EC954C C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbcore.dll
A056C5CC109CB6BFABBA3982E5739B57C2C6AEBEBDF41FB6DD17586ED4FA7F13 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbsrv.exe
A056C5CC109CB6BFABBA3982E5739B57C2C6AEBEBDF41FB6DD17586ED4FA7F13 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbsrv.exe
C48FC0A0BE36C70974CD180DD0DB22BB1EA84585BBE0B23583C6FEDCAEA0C76F C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x8633\mspdbcmfui.dll
C48FC0A0BE36C70974CD180DD0DB22BB1EA84585BBE0B23583C6FEDCAEA0C76F C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x6433\mspdbcmfui.dll
E6F6DF7DAD04699078D14D02BA57A19E332367507B860E03356AF2EEA86C3D68 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdb140.dll
E6F6DF7DAD04699078D14D02BA57A19E332367507B860E03356AF2EEA86C3D68 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdb140.dll
ECC40C0574AC6B93E3ACFC3EB95882D5391A2AC10E9ACC4444D418E5D5014135 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbst.dll
ECC40C0574AC6B93E3ACFC3EB95882D5391A2AC10E9ACC4444D418E5D5014135 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbst.dll
所有以mspdb
开头的文件在x86
和x64
之间完全相同作为目标。如果我在 Hostx86
文件夹中尝试相同的操作,目标之间的文件也完全相同,但与其他主机相比有所不同。
我认为将这些文件重新用于 MSVC 2017 同一主机的不同目标应该是安全的。我复制这些文件后编译成功,所以不会完全错!
网上有很多关于 "missing mspdb140.dll" 的问题,还有其他类似的关于缺少 "mspdb*" DLL 的问题。有一些关于它的不同解决方案,包括:
- 重新安装Visual Studio
- 删除mspdb140.dll,它应该包含在 PATH 变量中
- 将 mspdb140.dll(和其他文件)添加到
<msvc-install-dir>\<subpath>
就我而言,我在 docker 容器中使用了 msvc 2019 安装程序的构建工具,然后安装了 msvc 2017 和 2019 的构建工具。如果我然后转到 C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64
,有两个文件夹:x64
和 x86
。如果我编写 powershell 命令 ls -Recurse -Filter "*mspdb*"
,我会得到以下输出:
Directory: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x64
mspdb140.dll
mspdbcmf.exe
mspdbcore.dll
mspdbsrv.exe
mspdbst.dll
Directory: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x6433
mspdbcmfui.dll
不过 HostX64\x86
目录中有 none 个这些文件。如果我以 x64 作为目标构建一切正常,但以 x86 作为目标,发布和调试构建都会出错。发布版本有:
ERROR: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x86\cl.exe
...
c1xx: fatal error C1356: unable to find mspdbcore.dll
调试版本有:
ERROR: C:\BuildTools\VC\Tools\MSVC.16.27023\bin\HostX64\x86\cl.exe
...
c1xx: fatal error C1356: unable to find mspdb140.dll
这些构建使用 Qt 和 Qbs,Qbs 使用 vcvarsall.bat 来查找所需的环境变量。当安装了多个 msvc 工具链时,Qbs 中存在一个错误,这使得 Qbs 始终选择最新的一个。为了解决这个问题,我在每个构建作业中手动移动 vcvarsall.bat 并将其替换为:
call %~dp0vcvarsall_real.bat %1 store 10.0.17134.0 -vcvars_ver=14.16.27023 || exit /b 1
这会强制 vcvarsall 选择我想要的工具链 14.16.27023。
我通过简单地复制存在于 x64 目标的 DLL 和 EXE 文件(mspdbcmfui.dll
除外)设法修复了这两个编译错误。没有理由不复制最后一个 DLL,因为我只是在试验。即使程序可以编译,我也不知道我在做什么,这些文件在哪里使用,或者为什么某些目标缺少它们!在我的构建环境中不必手动复制文件会感觉更好。
我还检查了 Visual Studio 2017 Professional 的本地安装,然后 HostX64\x64 的文件名称相同,但是 HostX64\x86 我得到以下输出:
C:\Program Files (x86)\Microsoft Visual Studio17\WDProfesional\VC\Tools\MSVC.16.27023\bin\Hostx64\x86
...
mspdb140.dll
mspdbcore.dll
只有两个 DLL!
在 docker 图像中,我还有 MSVC 2019 的构建工具,所有主机和目标组合都包含所有 DLL 和 EXE。
总结一下:
- 为什么在某些情况下会丢失 DLL
- 解决这个问题的正确方法是什么?
- Visual Studio 编译与使用 vcvarsall.bat 和外部工具有何不同,因为它显然无需复制即可编译 DLLs/EXEs!
我仍然希望有人能解释更多关于为什么这些文件存在,如何正确使用它们,为什么它们在某些地方丢失,以及 Visual Studio 如何即使丢失也能编译文件。与此同时,我发现了这个:
我已经安装了 MSVC 2019 的构建工具,所以我转到文件夹 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64
和 运行 以下 powershell 命令:
(ls -Recurse "mspdb*").FullName | % { Get-FileHash $_ } | Sort-Object -Property Hash
得到这个输出:
Hash Path
--------------------------------------------------------------------------------------------------------------------------------------------
658D21DF98781D7C137FA213C3F3C2222C5D20A0F75BEB4929703406241379FA C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbcmf.exe
658D21DF98781D7C137FA213C3F3C2222C5D20A0F75BEB4929703406241379FA C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbcmf.exe
9664EE9A457B444E0D5A2F6A73A896375966BCF3864BBCD6B76AFEF496EC954C C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbcore.dll
9664EE9A457B444E0D5A2F6A73A896375966BCF3864BBCD6B76AFEF496EC954C C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbcore.dll
A056C5CC109CB6BFABBA3982E5739B57C2C6AEBEBDF41FB6DD17586ED4FA7F13 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbsrv.exe
A056C5CC109CB6BFABBA3982E5739B57C2C6AEBEBDF41FB6DD17586ED4FA7F13 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbsrv.exe
C48FC0A0BE36C70974CD180DD0DB22BB1EA84585BBE0B23583C6FEDCAEA0C76F C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x8633\mspdbcmfui.dll
C48FC0A0BE36C70974CD180DD0DB22BB1EA84585BBE0B23583C6FEDCAEA0C76F C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x6433\mspdbcmfui.dll
E6F6DF7DAD04699078D14D02BA57A19E332367507B860E03356AF2EEA86C3D68 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdb140.dll
E6F6DF7DAD04699078D14D02BA57A19E332367507B860E03356AF2EEA86C3D68 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdb140.dll
ECC40C0574AC6B93E3ACFC3EB95882D5391A2AC10E9ACC4444D418E5D5014135 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x86\mspdbst.dll
ECC40C0574AC6B93E3ACFC3EB95882D5391A2AC10E9ACC4444D418E5D5014135 C:\BuildTools\VC\Tools\MSVC.22.27905\bin\Hostx64\x64\mspdbst.dll
所有以mspdb
开头的文件在x86
和x64
之间完全相同作为目标。如果我在 Hostx86
文件夹中尝试相同的操作,目标之间的文件也完全相同,但与其他主机相比有所不同。
我认为将这些文件重新用于 MSVC 2017 同一主机的不同目标应该是安全的。我复制这些文件后编译成功,所以不会完全错!