有没有办法确定使用哪个版本的 Visual Studio 来编译静态库?
Posted
技术标签:
【中文标题】有没有办法确定使用哪个版本的 Visual Studio 来编译静态库?【英文标题】:Is there a way to determine which version of Visual Studio was used to compile a static library? 【发布时间】:2009-09-11 16:07:44 【问题描述】:我有一组静态库 (.lib) 文件,其中一个文件可能是使用不同版本的 Visual Studio 构建的。这导致链接所有项目的代码生成失败。有什么方法可以确定编译静态库使用的是哪个版本的 Visual Studio?
【问题讨论】:
一个更好的问题是编译器的版本。不使用 Visual Studio 也可以编译 C++ 静态库。 很公平。在我的特殊情况下,它们都是用 some 版本的 Visual Studio 编译的。不过,还有一个更普遍的问题。 一个更好的问题是关于 Visual C++,因为 Visual Studio 只是一个 IDE。 【参考方案1】:对于发布库,您不太可能确定版本。
对于调试库,可以使用dumpbin:
dumpbin /rawdata:1 library.lib
程序集清单应位于转储的开头,并将包含库所需的 CRT 版本以及用于构建库的编译器的完整路径。
对于可执行文件和 DLL,您可以使用 dumpbin 获取链接器版本;它在“可选标题值”下
dumpbin /headers program.exe
也许其他人知道获取发布库版本的方法;如果他们有兴趣,我当然也很感兴趣。
【讨论】:
您能否分享一些关于在哪里可以找到此工具的详细信息,或者如果 Visual Studio 安装默认不可用,那么我们可以从哪里获得它?dumpbin /headers program.exe
-方法是否也适用于发布二进制文件?我试过了,效果很好。
@SUMIT KUMAR SINGH 关于 dumpbin:“您只能从 Visual Studio 命令提示符启动此工具。您不能从系统命令提示符或文件资源管理器启动它。”来自Microsoft Docs DUMPBIN Reference【参考方案2】:
我一直使用类似的东西(在 cygwin 窗口中):
strings -f *.lib | grep 'Visual Studio'
编译器在调试构建时将编译器的路径粘贴在库中,并且 Visual Studio 的编译器默认位置位于包含文本“Visual Studio”的路径下。
因此,就像 James McNellis 的回答一样,这也仅适用于调试构建,并且进一步限于实际使用编译器的构建,该编译器位于路径中包含“Visual Studio #”的目录中.
几年前我偶然发现了这种方法,但它还没有失败。
如果您熟悉 Unix 命令行工具,那么它的好处是很容易记住。
【讨论】:
我知道不鼓励“+1”-esque cmets 但这应该是 IMO 答案列表的顶部 - 因为它适用于发布库。谢谢。 实际上这甚至适用于发布库:)【参考方案3】:如果您有相应的 .PDB 文件,那么您可以使用 Pdb Inspector 之类的工具从那里查看编译器的版本。
或者在十六进制查看器中打开 PDB 并搜索字符串“Microsoft (R) Optimizing Compiler”。版本将在该字符串之前的四个 2 字节十六进制值中,如下例所示:
000000A060: .. .. .. .. .. .. . ... .. .. .. .. .. .. 13 00 ..
000000A070: 00 00 6E 5D 00 00 4D 69 63 72 6F 73 6F 66 74 20 ......Microsoft
000000A080: 28 52 29 20 4F 70 74 69 6D 69 7A 69 6E 67 20 43 (R) Optimizing C
000000A090: 6F 6D 70 69 6C 65 72 00 .. .. .. .. .. .. .. .. ompiler ........
因此版本是 HEX 13 00、00 00、6E 5D、00 00 或 19.0.23918.0。
【讨论】:
也适用于非调试静态库 (.lib) 文件。【参考方案4】:如果静态库是用 C++ 编写的,并且是使用 MSVC 2010 或更高版本构建的,则编译器可能已将 FAILIFMISMATCH 指令放入目标文件中。
我找不到微软关于 FAILIFMISMATCH 指令的官方文档,但它似乎被链接器用来检测 C++ 标准库版本之间的不兼容性。
您可以使用以下命令从静态库中打印出这些指令:
find "FAILIFMISMATCH" xyz.lib
(如果你喜欢cygwin或msys,或者使用mheyman提到的方式)
结果可能是这样的:
0@ /FAILIFMISMATCH:"_MSC_VER=1900" /FAILIFMISMATCH:"_ITERATOR_DEBUG_LEVEL=0" /FAILIFMISMATCH:"RuntimeLibrary=MD_DynamicRelease" /DEFAULTLIB:"msvcprt" /FAILIFMISMATCH:"_CRT_STDIO_ISO_WIDE_SPECIFIERS=0" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"MSVCRT" /DEFAULTLIB:"OLDNAMES"
注意第一个指令:“_MSC_VER=NNNN”。在我的观察中,NNNN 始终与用于创建目标文件的编译器版本匹配。在我的例子中,xyz.lib 是使用 MSVC 2015 update 3 创建的,它的 C++ 编译器版本是 19.00.24215,所以它把 /FAILIFMISMATCH:"_MSC_VER=1900" 放在目标文件中。
Visual Studio 版本和 Microsoft C/C++ Compiler 版本之间的详细映射可以找到at here。
【讨论】:
对于 VS2017,测试了一些使用 v15.9.5 和 v15.9.6 构建的库,它一直报告 /FAILIFMISMATCH:"_MSC_VER=1900",而不是 1916(v15.9 的四位代码)。在任何情况下,您的答案在许多情况下都会很有用。【参考方案5】:您没有指定语言,但在 C# 中了解操作系统和 .NET 版本(在运行时的代码中)的答案是:
System.Version osVersion = System.Environment.OSVersion;
System.Version cliVersion = System.Environment.Version;
在托管 C++/CLI 中会有一个等价物
这不会告诉您 编译器 或 IDE 的版本,但会告诉您 .NET 运行时的版本。您可能需要也可能不需要知道操作系统版本。
-杰西
【讨论】:
这甚至与被问到的问题无关。虽然问题中没有指定语言(考虑到问题,这是正确的),但它谈到了静态库。静态库意味着本机代码。问题本质上是问,哪个运行时版本被编译成二进制代码。操作系统版本在这里不重要。以上是关于有没有办法确定使用哪个版本的 Visual Studio 来编译静态库?的主要内容,如果未能解决你的问题,请参考以下文章
visual studio除了6还有哪个版本用得多而又不占内存?如何实现多visual studi
在 ColdFusion 中,有没有办法确定代码在哪个服务器上运行?
有没有办法确定用户选择了哪个 google play 排行榜 api 隐私设置?