有关VS2017中本机多目标的说明,请参见: https://blogs.msdn.microsoft.com/vcblog/2016/02/24/stuck-on-an-older-toolset-version-move-to-visual-studio-2015-without-upgrading-your-toolset/
你好,我叫李绍。我是一名测试软件设计工程师 上 C++团队。在过去的两年中,我一直是团队的一部分,致力于将C++构建系统从VCuBube迁移到MSBug,以及新的项目系统,该系统也构建在MSBug之上。你可以看到 一 我以前写的关于我们所做的工作的博客。在这个博客中,我将对本地多目标特性进行概述。我希望你会觉得它有用。
多目标是使用 现在的 用于使用 不同的 一套已安装的工具或框架。在VS2010中,C++应用支持两种类型的多目标:本地多目标和托管多目标。有关托管多目标的更多详细信息,请访问 此博客帖子 我的一个同事,Pavan Adharapurapu。
本机多目标
如果VS2008安装在同一台机器上,那么VS2010可以支持针对VS2008工具集进行构建。索玛提到 这个特征在他的 博客 不久前。这个特性使C++客户在VS2010环境中工作时使用VS2008工具集。请注意,使用早期版本的VisualStudio创建的应用程序需要转换为VS2010版本。
为什么选择本机多目标?
C++客户的一个重要场景(我们称之为“大型C++商店”)是他们在VisualStudio中开发和构建应用程序,然后将应用程序传送给各自的客户。但是,这些客户可能使用不同版本的visualstudio进行开发。鉴于此,“大型C++商店”必须保留VisualStudio的多个版本和项目文件的多个版本,以便它们可以构建针对工具集不同版本的二进制文件。
利用本地多目标特征,一旦“大型C++商店”将其应用迁移到VS2010,它们就有能力使用VS2010理论上针对任何版本的工具集。这样就不需要维护多个版本的项目文件,只要目标工具集安装在同一台机器上,开发工作就可以在VS2010中完成。
如何启用本机多目标?
从IDE构建和在命令行构建时,多目标特性都可用。下面是属性页上本机多目标设置的屏幕截图:平台工具集控制要针对哪个版本的工具集:v100针对VS2010,v90针对VS2008级工具集和库。
对于新创建的项目和转换为VS2010的项目,平台工具集版本默认为v100。在这两种情况下,“PlatformToolset”属性都不会写入项目文件。有几种方法可以重新定位到不同的平台工具集(下面以v90为例):
对于单个项目,您可以在属性页中选择目标平台工具集为v90,“PlatformToolset”属性将写入项目文件,如下所示:
< 属性组 条件 = “ ‘$(配置)|$(平台)’==’调试| Win32’ “ 标签 = “ 配置 “ >
< 配置类型 > 应用 配置类型 >
< 使用调试库 > 是的 使用调试库 >
< 字符集 > Unicode码 字符集 >
< 平台工具集 > v90型 平台工具集 >
属性组 >
为了一次重新确定多个项目的目标,您可以在解决方案资源管理器中多选这些项目,然后打开属性页。要使更改适用于所有配置,还可以从配置下拉列表“所有配置”条目和平台下拉列表“所有平台”条目中选择。请注意,只有当所有项目都是同一类型时,multi-select才起作用。
一旦 “PlatformToolset”设置为v90,将使用VS2008中的编译器、链接器、头文件和库。下面是在VS2010 IDE或命令行提示符下根据v90工具集生成时生成日志的快照。您可以看到使用了VS2008编译器而不是VS2010编译器。
c:程序文件(x86)Microsoft Visual Studio 9.0vcinl.exe/c/ZI/nologo/W3/WX-/Od/Oy-/D WIN32/DU WINDOWS/DU DEBUG/DU UNICODE/D UNICODE/DU AFXDLL/Gm/EHsc/RTC1/MDd/GS/fp:precise/Zc:wcharU t/Zc:forScope/Yc“StdAfx.h”/fp“DebugMFC.pch”/Fo“DEBUG”/Fd“Debugvc90.pdb”/Gd/TP/analyze-/erroreport:prompt stdafx.cpp
请注意,更改“平台工具集”属性的值将导致项目的完全重建。
它是如何工作的?
在VS2010中,上的%%ProgramFiles%%MSBuildMicrosoft.Cppv4.0Platforms
Microsoft.Cpp.
< VCInstallDir公司 > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftVisualStudio9.0SetupVC@ProductDir) VCInstallDir公司 >
< VCInstallDir公司
条件 = “ “$(VCInstallDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftVisualStudio9.0SetupVC@ProductDir) VCInstallDir公司 >
< VCInstallDir公司
条件 = “ “$(VCInstallDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftVCExpress9.0SetupVC@ProductDir) VCInstallDir公司 >
< VCInstallDir公司
条件 = “ “$(VCInstallDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftVCExpress9.0SetupVC@ProductDir) VCInstallDir公司 >
< WindowsSDK数据库
条件 = “ ‘$(useev)’= ‘正确’ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SDKsWindows@CurrentInstallFolder) WindowsSDK数据库 >
< WindowsSDK数据库
条件 = “ “$(WindowsSdkDir)”=“ “ > $(Registry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftMicrosoftSDKsWindows@CurrentInstallFolder) WindowsSDK数据库 >
< 可执行路径
条件 = “ “$(ExecutablePath)”=“ “ > $(VCInstallDir)bin$(WindowsSDKDir)bin$(VSInstallDir)通用7工具$(VSInstallDir)Common7工具$(VSInstallDir)公共7ide$(程序文件)HTML帮助研讨会$(框架(dkdir)bin$(frameworkir)$(框架版本)$(VSInstallDir)$(系统根)SysWow64$(FxCopDir公司)$(路径); 可执行路径 >
< 包含路径
条件 = “ ‘$(IncludePath)’=“ “ > $(VCInstallDir)包括:$(VCInstallDir)atlmfcinclude$(WindowsSdkDir)包括:$(框架dkdir)包括:; 包含路径 >
< 引用路径
条件 = “ “$(ReferencePath)”=“ “ > $(VCInstallDir)atlmfclib$(VCInstallDir)库 引用路径 >
< 库路径
条件 = “ ‘$(库路径)’==“ “ > $(VCInstallDir)库$(VCInstallDir)atlmfclib$(WindowsSdkDir)库$(FrameworkSDKDir)库 库路径 >
< 源路径
条件 = “ ‘$(源路径)’=“ “ > $(VCInstallDir)atlmfcsrcmfc$(安装目录)atlmfcsrcmfcm$(安装目录)atlmfcsrcatl$((1)crtsrc; 源路径 >
< 排除路径
条件 = “ ‘$(ExcludePath)’=“ “ > $(VCInstallDir)包括:$(VCInstallDir)atlmfcinclude$(WindowsSdkDir)包括:$(框架dkdir)包括:$(frameworkir)$(框架版本)$(VCInstallDir)atlmfclib$(VCInstallDir)库; 排除路径 >
MSBuild可以基于您在特定平台工具集的props文件中设置的信息生成生成环境。在命令行构建场景中,这意味着构建系统正在使用的路径LIBPATH LIB可以来自PlatformToolsets本身,这样就不需要使用其他批处理文件(如vcvars32.bat)来设置构建环境。这是旧VCBuild系统没有的功能。下面是Microsoft.cpp.Targets中启用该功能的代码段。当UseEnv未设置为true时,将从平台工具集中的相应属性值设置PATH、LIB、INCLUDE、LIBPATH。 当UseEnv设置为true时,就像在旧的构建系统中一样,将使用PATH、INCLUDE、LIB、LIBPATH的环境变量中的值。
< 目标 姓名 = “ SetBuildDefaultEnvironmentVariables设置 “
条件 = “ ‘$(UseEnv)’!=’是的’ “ >
< 塞滕夫 条件 = “ ‘$(u IsNativeEnvironment)’!=’是的’ “
姓名 = “ 路径 “
价值 = “ $(可执行路径) “
前缀 = “ 假 “ >
< 输出 任务参数 = “ outputEnvironment变量 “ 属性名 = “ 路径 “ />
塞滕夫 >
< 塞滕夫 条件 = “ “$(u IsNativeEnvironment)”==“真” “
姓名 = “ 路径 “
价值 = “ $(NativeExecutablePath) “
前缀 = “ 假 “ >
< 输出 任务参数 = “ outputEnvironment变量 “ 属性名 = “ 路径 “ />
塞滕夫 >
< 塞滕夫 姓名 = “ 库 “
价值 = “ $(库路径) “
前缀 = “ 假 “ >
< 输出 任务参数 = “ outputEnvironment变量 “ 属性名 = “ 库 “ />
塞滕夫 >
< 塞滕夫 姓名 = “ 库路径 “
价值 = “ $(引用路径) “
前缀 = “ 假 “ >
< 输出 任务参数 = “ outputEnvironment变量 “ 属性名 = “ 库路径 “ />
塞滕夫 >
< 塞滕夫 姓名 = “ 包括 “
价值 = “ $(包括路径) “
前缀 = “ 假 “ >
< 输出 任务参数 = “ outputEnvironment变量 “ 属性名 = “ 包括 “ />
塞滕夫 >
目标 >
对于托管应用程序,因为 VS2008编译器只能针对CLR 2.0,针对v90平台工具集它只允许.NET Framework的以下版本之一:v2.0、v3.0或v3.5。默认情况下,v90平台工具集以v3.5框架为目标。
如何扩展?
使用这个模型,如果您有一个特定的SDK,您可以创建您的定制平台工具集。下面是针对VS2005的Microsoft.cpp.Win32.v80.props文件的示例。请注意,对于VS2005,WindowsSDKDir不可用,我们使用的是PlatformSDK。 在为每个平台创建了v80目录以及相应的道具和目标文件之后,您就可以立即根据v80进行构建了。
< 项目 xmlns公司 = “ http://schemas.microsoft.com/developer/msbuild/2003 “ >
< 导入 项目 = “ $(VCTargetsPath)PlatformsWin32 PlatformToolsetsv80ImportBefore*.props “ 条件 = “ 存在(’$(VCTargetsPath)PlatformsWin32PlatformToolsetsv80ImportBefore’) “ />
< 属性组 >
< 平台工具集版本 > 80 平台工具集版本 >
< VCInstallDir公司 > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftVisualStudio8.0SetupVC@ProductDir) VCInstallDir公司 >
< VCInstallDir公司
条件 = “ “$(VCInstallDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftVisualStudio8.0SetupVC@ProductDir) VCInstallDir公司 >
< VSInstallDir > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftVisualStudio8.0SetupVS@ProductDir) VSInstallDir >
< VSInstallDir
条件 = “ “$(VSInstallDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftVisualStudio8.0SetupVS@ProductDir) VSInstallDir >
< 框架IR
条件 = “ ‘$(UseEnv)’!=’是的’ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFramework@InstallRoot) 框架IR >
< 框架IR
条件 = “ “$(FrameworkDir)”=“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoft.NETFramework@InstallRoot) 框架IR >
< 框架DKDIR
条件 = “ ‘$(UseEnv)’!=’是的’ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SDKs.NETFrameWorkv2。0@InstallationFolder) 框架DKDIR >
< 框架DKDIR
条件 = “ “$(FrameworkSdkDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SDKs.NETFrameWorkv2。0@InstallationFolder) 框架DKDIR >
< 框架DKDIR
条件 = “ “$(FrameworkSdkDir)”==“ “ > 美元(R)egistry:HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftMicrosoft SDKs.NETFrameWorkv2。0@InstallationFolder) 框架DKDIR >
< 框架版本
条件 = “ ‘$(UseEnv)’!=’是的’ “ > 版本2.0.50727 框架版本 >
< 框架35版本
条件 = “ ‘$(UseEnv)’!=’是的’ “ > 版本3.5 框架35版本 >
< 可执行路径
条件 = “ “$(ExecutablePath)”=“ “ > $(VCInstallDir)bin$(VCInstallDir)平台皮肤$(VCInstallDir)平台dkCommonin$(VSInstallDir)通用7工具$(VSInstallDir)Common7工具$(VSInstallDir)公共7ide$(程序文件)HTML帮助研讨会$(框架(dkdir)bin$(frameworkir)$(框架版本)$(VSInstallDir)$(系统根)SysWow64$(FxCopDir公司)$(路径); 可执行路径 >
< 包含路径
条件 = “ ‘$(IncludePath)’=“ “ > $(VCInstallDir)包括:$(VCInstallDir)atlmfcinclude$(VCInstallDir)平台包括:$(VCInstallDir)平台dkCommonInclude$(框架dkdir)包括:; 包含路径 >
< 引用路径
条件 = “ “$(ReferencePath)”=“ “ > $(frameworkir)$(框架版本)$(VCInstallDir)atlmfclib; 引用路径 >
< 库路径
条件 = “ ‘$(库路径)’==“ “ > $(VCInstallDir)库$(VCInstallDir)atlmfclib$(VCInstallDir)atlmfclibi386$(VCInstallDir)平台dklib$(VCInstallDir)平台dkCommonLib$(FrameworkSDKDir)库$(VSInstallDir)$(VSInstallDir)库; 库路径 >
< 源路径
条件 = “ ‘$(源路径)’=“ “ > $(VCInstallDir)atlmfcsrcmfc$(安装目录)atlmfcsrcatl$((1)crtsrc; 源路径 >
< 排除路径
条件 = “ ‘$(ExcludePath)’=“ “ > $(VCInstallDir)包括:$(VCInstallDir)atlmfcinclude$(VCInstallDir)平台包括:$(VCInstallDir)平台dkCommonInclude$(框架dkdir)包括:$(frameworkir)$(框架版本)$(VCInstallDir)atlmfclib; 排除路径 >
< NativeExecutable路径
条件 = “ ‘$(NativeExecutablePath)’=“ “ > $(可执行路径) NativeExecutable路径 >
属性组 >
< 导入 项目 = “ $(VCTargetsPath)PlatformsWin32 PlatformToolsetsv80ImportAfter*.props “ 条件 = “ 存在(’$(VCTargetsPath)PlatformsWin32 PlatformToolsetsv80ImportAfter’) “ />
项目 >
下面是IDE生成设置和生成日志的快照:
平台工具集特性还提供了扩展点。在Microsoft.Cpp.Win32.
< 导入 项目 = “ $(VCTargetsPath)PlatformsWin32PlatformToolsetsv100ImportBefore*.props “
条件 = “ 存在(’$(VCTargetsPath)PlatformsWin32PlatformToolsetsv100ImportBefore’) “ />
< 导入 项目 = “ $(VCTargetsPath)PlatformsWin32PlatformToolsetsv100ImportAfter*.props “
条件 = “ 存在(’$(VCTargetsPath)PlatformsWin32PlatformToolsetsv100ImportAfter’) “ />
通过这种设计,您可以创建特定于某个平台工具集的特殊道具文件。例如,您可以创建一个名为DirectX.props的自定义props文件(可以称为任何名称),然后将其放入以下文件夹:win32PlatformToolsetsv100ImportAfter。DirectX.props(下面)中定义的属性 之后导入 导入Microsoft.Cpp.Win32.
< 项目 xmlns公司 = “ http://schemas.microsoft.com/developer/msbuild/2003 “ >
< 项目定义组 >
< CLC编译 >
< 其他包括目录 > $(DirectXSDK)最新包含;%%(其他(包括目录) 其他包括目录 >
CLC编译 >
< 链接 >
< 其他库目录 > $(DirectXSDK)LatestLibx86%%(附加库目录); 其他库目录 >
链接 >
项目定义组 >
项目 >
编译时,当编译针对Win3