Vs2012工具集兼容性
vs2012 toolset compatibility
在我的VS2012中,我有4个工具集可用:v90, v100, v110和v110_xp。我用两个项目testlib(静态库)和testexe(控制台应用程序)做了一个简单的测试。接口只有一个函数,签名为void test()
。结果:
- testlib(v90), testexe(v90以外的任何)->不链接 testlib(v100), testexe(v110或v110_xp) ->链接
然而,v100和v110会连接在一起对我来说似乎有点奇怪,所以我试着把这个场景复杂化一点。现在我的方法是这样的:std::map<std::string, std::string> test(const std::string& arg)
。如预期的那样,testlib(v100)和testexe(v110)不能链接(mismatch detected for '_MSC_VER'
)。
但是testlib(v110)和testexe(v110_xp)仍然可以链接,并且生成的exe可以在Windows XP上工作。这是偶然的还是有可能的?如果这只是偶然,那么一个示例代码只使用v110_xp中可用的特性并破坏这种兼容性将是受欢迎的。我想知道我是否应该将我的库的两个版本部署到我的客户端,或者只是用v110编译的一个。
用"toolset"这个词来描述v110和v110_xp之间的区别有点用词不当。您仍然在使用相同的构建工具。你仍然有相同版本的CRT。您可以通过比较在两个构建之间加载的DLL的Debug + Windows + Module列表中看到的内容来看到一些东西。请注意msvcr110.dll的名称和位置。
CRT实际上是由Update 1更新的,它现在支持XP和更新的Windows版本。这是通过它在运行时动态绑定到后来的winapi函数来工作的,使用GetProcAddress(),如果在XP上运行时找不到它们,它就会一瘸一拐地前进。
不同的是你有另一个版本的Windows SDK。最后一个仍然与XP兼容的版本是7.1。您可以在C:Program Files (x86)Microsoft sdk Windowsv7.1A中找到它。当您使用v110工具集构建时,您将使用存储在C:Program Files (x86)Windows Kits8.0
中的SDK包含和库文件。当您在c:program files (x86)msbuild目录中搜索该字符串时,可以看到使用v110_xp时的具体更改:
- 包含和lib文件等的目录被更改为Windows 7.1 SDK路径
- 添加了_USING_V110_SDK71_预处理器符号,否则不会在重要的地方使用
- 链接器的/SUBSYSTEM选项被更改为只需要Windows版本5.02,XP版本号。
长话短说,混合使用v110和v110_xp工具集构建的模块不是问题。
混合v110_xp
可执行文件和v110
库是正式不支持的。
在与微软单独升级此问题后,他们回答了以下问题:
Q1:使用这些库(v110)并使用工具集v110_xp构建的应用程序可以在Windows XP机器上正常运行吗?
只有使用v110_xp工具集构建的可执行文件才能在Windows XP机器上正常运行。因此,如果应用程序需要在Windows XP机器上正常运行,您将需要确保您的项目从默认的v110工具集切换到项目属性页中新引入的v110_xp工具集,包括可执行文件和dll(如果有的话)。
Q2:我们是否需要发布使用工具集v110_xp构建的这些库的另一个版本?
我认为这取决于你需要在哪种平台上部署你的应用程序。如果您的部署计划包括Windows XP机器,则有必要发布使用v110_xp工具集构建的可执行文件/dll的新版本。然而,考虑到用v110_xp工具集构建的相同的可执行文件/dll也可以在Vista和更高版本上运行,我建议你可以只保留一个用v110_xp工具集构建的可执行文件/dll的单一版本,这样就可以在所有其他平台上运行。当Windows XP不再在您的部署计划中时,您可以将整个可执行文件/dll转换为使用v110工具集重新构建。如果你想分别针对Windows XP和其他系统,如果你能同时维护两个版本的可执行文件/dll当然是很好的。
Q3: Microsoft是否支持在Windows XP上使用toolset v110构建的库?
答案是NO。如果你想在Windows XP上正常运行应用程序,一切都需要在v110_xp模式下构建。
请不要将拥有/导出类的DLL与不同版本的Visual Studio混合(即使是较小的版本差异)。STL和MFC有构建在模板之上的类(类本身可能没有为用户模板化),这可以防止不同版本之间的链接和/或编译。
一个简单的例子是CString
:与MFC的静态和动态链接将有不同的CString
实现。Unicode和ANSI CString
也是不同的。另一个例子是STL本身:调试版本vector
不同于发布版本vector
。此外,在STL集合的情况下,编译器设置也会改变容器的大小/实现(如vector
, list
)。
因此,最好不要导入具有这些类型的类作为参数的导出类/函数。甚至不要以不透明的方式传递它们(比如在空指针的顶部)。
- NPM 安装:找不到平台工具集 = v141
- 构建在VS 2013中找不到平台工具集= 'v141'
- C++ VS 工具集 141 - 142 铸造的差异
- 如果使用平台工具集构建应用,则 CCheckListBox 项在选择时会重叠'Visual Studio 2017 (v141)'
- Visual Studio Platform 工具集和运行时库
- 使用自定义工具集获取动态退出析构函数链接错误 - eh 矢量析构函数
- 在一个VS项目中使用多个工具集 - 是否存在风险
- 为什么在链接时搜索使用错误工具集的提升库?
- C2064 从 MSVC v100 更新到 v140 平台工具集时出现编译错误
- 使用类型参数专用化部分模板参数(VC++ v140 工具集)
- C V100平台工具集
- 提升链接器错误工具集
- 如何获取Visual Studio C++工具集标记
- 我已安装的GCC版本是我已安装的RedHat开发人员工具集的背后
- 找不到 Visual Studio 2008 的生成工具(平台工具集 = 'v90')
- 如何使用 CMake 设置 VS 平台工具集属性
- 始终使用 Visual Studio 中提供的最新工具集
- 使用不同工具集使用Cl.EXE编译
- 我可以将使用v120_xp工具集构建的静态库链接到使用VS2013中的v120工具集创建的EXE/DLL中吗
- Vs2012工具集兼容性