39

I have a collection of static libraries (.lib) files one of which may have been built with a different version of Visual Studio. This is causing the code generation of a project that links against all of them to fail. Is there any way to determine which version of Visual Studio was used to compile a static library?

Bill Carey
  • 1,395
  • 1
  • 11
  • 20
  • 4
    A better question to ask is which version of the compiler. It's possible to compile C++ static libs without the use of Visual Studio. – JaredPar Sep 11 '09 at 16:08
  • Fair enough. In my particular case they're all compiled with *some* version of Visual Studio. There is a more general question lurking though. – Bill Carey Sep 11 '09 at 16:16
  • An even better question would be about Visual C++, as Visual Studio is just an IDE. – rustyx Sep 05 '18 at 16:11

5 Answers5

30

For release libraries, it's unlikely that you could determine the version.

For debug libraries, you can use dumpbin:

dumpbin /rawdata:1 library.lib

The assembly manifest should be at the beginning of the dump and will contain the version of the CRT the library requires along with the full path to the compiler used to build the library.

For executables and DLLs you can get the linker version using dumpbin; it's under "OPTIONAL HEADER VALUES"

dumpbin /headers program.exe

Maybe someone else knows of a way to get the version for release libraries; I'm certainly interested too if they are.

Junaith
  • 3,298
  • 24
  • 34
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 1
    Can you share some details on where to find this tool or if not available by default with Visual Studio installation then from where we can get it ? – Sumit Singh Oct 25 '17 at 06:39
  • Doesn't the `dumpbin /headers program.exe`-approach also work with release binaries? I tried it and it worked. – langlauf.io Mar 08 '18 at 15:07
  • @SUMIT KUMAR SINGH About dumpbin: "You can start this tool only from the Visual Studio command prompt. You cannot start it from a system command prompt or from File Explorer." From [Microsoft Docs DUMPBIN Reference](https://learn.microsoft.com/en-us/cpp/build/reference/dumpbin-reference?view=vs-2017) – Giovanni Faglia Feb 14 '19 at 11:13
14

I've always used something like (in a cygwin window):

strings -f *.lib | grep 'Visual Studio'

The compiler sticks the path of the compiler in the library on debug builds and the Visual Studio's compiler default location is under a path that includes the text 'Visual Studio'.

So, like James McNellis' answer, this also works only for debug builds and is further restricted to builds that actually uses a compiler that sits in a directory with 'Visual Studio #' in the path.

I found this method years ago through a bit of serendipity and it has yet to fail.

This has the benefit that it is easy to remember if you are familiar with Unix command line tools.

mheyman
  • 4,211
  • 37
  • 34
11

If you have the corresponding .PDB files then you can see the version of the compiler from there with a tool like Pdb Inspector.

Or open the PDB in a hex viewer and search for the string "Microsoft (R) Optimizing Compiler". The version will be in four 2-byte hex values just before that string, like in this example:

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 ........

The version is thus HEX 13 00, 00 00, 6E 5D, 00 00, or 19.0.23918.0.

rustyx
  • 80,671
  • 25
  • 200
  • 267
0

If the static library was written in C++, and was built with MSVC 2010 or newer version, a FAILIFMISMATCH directive may have been put by compiler into the object files.

I cannot found the official document from Microsoft about the FAILIFMISMATCH directive, but it seems to be used by linker to detect incompatibilities between C++ standard library versions.

You can use the following command to print out those directives from a static library:

find "FAILIFMISMATCH" xyz.lib

(or use the way that mheyman has mentioned if you favor in cygwin or msys)

The result may be similar to this:

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"

Note the first directive: "_MSC_VER=NNNN". In my observation, the NNNN is always match to the compiler version used to create the object file. In my case, the xyz.lib was create with MSVC 2015 update 3, its C++ compiler version is 19.00.24215, so it put /FAILIFMISMATCH:"_MSC_VER=1900" in object file.

A detail mapping between Visual Studio version and Microsoft C/C++ Compiler version can be found at here.

zevoid
  • 171
  • 1
  • 7
  • For VS2017, tested some libraries built with v15.9.5 and v15.9.6, it keeps reporting /FAILIFMISMATCH:"_MSC_VER=1900", instead of 1916 (the four digit code for v15.9). Your answer can be useful in many situations in any case. – Giovanni Faglia Feb 14 '19 at 10:28
-5

You didn't specify the language, but in C# the answer for knowing the OS and .NET version (in your code at runtime) is:

System.Version osVersion = System.Environment.OSVersion;
System.Version cliVersion = System.Environment.Version;

There would be an equivalent in Managed C++/CLI

That won't tell you the verison of the compiler or of the IDE, but will tell you the verison of the .NET runtimes. You may or may not need to know the OS version.

-Jesse

Jesse Chisholm
  • 3,857
  • 1
  • 35
  • 29
  • 1
    This is not even remotely related to the question being asked. While there is no language specified in the question (which is correct, given the question), it talks about static libraries. Static libraries imply native code. The question is essentially asking, which runtime version is compiled into the binary code. The OS version is of no interest here. – IInspectable Oct 20 '17 at 16:17