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?
问题:
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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.
回答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