有没有办法确定使用哪个版本的 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 隐私设置?

Visual Studio 2017 使用哪个版本的 SignTool?

确定使用了哪个共享扩展

visual studio哪个版本好