Visual Studio 2010 C++ 用户属性设置

在 《Visual Studio 2010 C++ 工程文件解读》中提到了C++工程中可以利用 Microsoft.Cpp.$(Platform).user.props 文件进行用户自定义的属性设置,所以利用该属性文件可以做些什么呢?

1、我不喜欢输出 C++ 工程的默认输出目录风格,我想自己定义几种目录输出风格并可以自由切换;

2、我要增加自定义的输出目录风格,可以通过解决方案或者工程文件自己控制;

3、我不想在每一个工程中设置第三方开发包的 INCLUDE 路径和 LIB 路径;

没错上面这些都可以做到,关键是如何在 Microsoft.Cpp.$(Platform).user.props 中添加内容;首先来看我设置好的属性文件:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<_PropertySheetDisplayName>Cpp Common Properties</_PropertySheetDisplayName>
</PropertyGroup>

<PropertyGroup Condition="'$(SolutionDriver)' == ''" >
<SolutionDriver>$([System.IO.Path]::GetPathRoot($(SolutionDir)))</SolutionDriver>
</PropertyGroup>

<PropertyGroup Condition="'$(SolutionPrefix)' == ''">
<SolutionPrefix>$(SolutionDir)$(SolutionName)</SolutionPrefix>
</PropertyGroup>

<ImportGroup Label="PropertySheets">
<!-- import project by Project / Solution / Common properties if file exists -->
<Import Project="$(ProjectPath).props" Condition="Exists('$(ProjectPath).props')" />
<Import Project="$(SolutionPrefix).props" Condition="Exists('$(SolutionPrefix).props')" />
<Import Project="$(SolutionDir)Project\*.props" Condition="Exists('$(SolutionDir)Project')" />
<Import Project="$(SolutionDir)Properties\*.props" Condition="Exists('$(SolutionDir)Properties')" />
</ImportGroup>

<PropertyGroup>
<IncludePath>$(ProjectDir)Header;$(ProjectDir)Include;$(SolutionDir)Include;$(IncludePath)</IncludePath>
<LibraryPath>$(ProjectDir)Binary;$(ProjectDir)Library;$(SolutionDir)Library;$(LibraryPath)</LibraryPath>
</PropertyGroup>

<PropertyGroup>
<SingleFolder Condition="'$(SingleFolder)' == ''">false</SingleFolder>

<ObjectFolder Condition="'$(ObjectFolder)' == ''">$(Temp)\VC2010.IntDir\</ObjectFolder>
<ObjectFolder Condition="!HasTrailingSlash('$(ObjectFolder)')">$(ObjectFolder)\</ObjectFolder>

<OutputFolder Condition="'$(OutputFolder)' == ''">$(SolutionDir)Outputs\</OutputFolder>
<OutputFolder Condition="!HasTrailingSlash('$(OutputFolder)')">$(OutputFolder)\</OutputFolder>
</PropertyGroup>

<PropertyGroup Condition="'$(SingleFolder)' == 'false'">
<ImportFolder Condition="'$(ImportFolder)' == ''">$(OutputFolder)Library\</ImportFolder>
<SymbolFolder Condition="'$(SymbolFolder)' == ''">$(OutputFolder)Symbol\</SymbolFolder>
<BinaryFolder Condition="'$(BinaryFolder)' == ''">$(OutputFolder)Binary</BinaryFolder>
</PropertyGroup>

<PropertyGroup Condition="'$(SingleFolder)' != 'false'">
<ImportFolder Condition="'$(ImportFolder)' == ''">$(OutputFolder)</ImportFolder>
<SymbolFolder Condition="'$(SymbolFolder)' == ''">$(OutputFolder)</SymbolFolder>
<BinaryFolder Condition="'$(BinaryFolder)' == ''">$(OutputFolder)</BinaryFolder>
</PropertyGroup>

<PropertyGroup Condition="Exists('$(ImportFolder)')">
<LibraryPath>$(ImportFolder);$(LibraryPath)</LibraryPath>
</PropertyGroup>

<PropertyGroup>
<SuffixCharSet Condition="'$(CharacterSet)' == 'Unicode'">U</SuffixCharSet>
<SuffixCharSet Condition="'$(CharacterSet)' != 'Unicode'">M</SuffixCharSet>
<SuffixRelease Condition="'$(Configuration)' == 'Debug'">D</SuffixRelease>
<SuffixRelease Condition="'$(Configuration)' != 'Debug'">R</SuffixRelease>
<SuffixMachine>$(PlatformArchitecture)</SuffixMachine>
</PropertyGroup>

<PropertyGroup>
<TargetOutput Condition="'$(TargetOutput)' == ''">$(TargetName)</TargetOutput>
<TargetSuffix>$(SuffixCharSet)$(SuffixRelease)$(SuffixMachine)</TargetSuffix>
<IntDir>$(ObjectFolder)$(ProjectName).$(TargetSuffix)\</IntDir>
<OutputName>$(TargetOutput)$(TargetSuffix)</OutputName>
</PropertyGroup>

<PropertyGroup Condition="'$(ConfigurationType)' != 'StaticLibrary'">
<OutDir Condition="'$(SingleFolder)' == 'false'">$(BinaryFolder).$(TargetSuffix)\</OutDir>
<OutDir Condition="'$(SingleFolder)' != 'false'">$(BinaryFolder)</OutDir>
</PropertyGroup>

<PropertyGroup Condition="'$(ConfigurationType)' == 'StaticLibrary'">
<OutDir>$(ImportFolder)</OutDir>
</PropertyGroup>

<ItemDefinitionGroup>
<ClCompile Condition="'$(ConfigurationType)' == 'StaticLibrary'">
<ProgramDataBaseFileName>$(SymbolFolder)Compile\$(OutputName).pdb</ProgramDataBaseFileName>
</ClCompile>

<ClCompile Condition="'%(ClCompile.DebugInformationFormat)' == ''">
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>

<Link>
<ProgramDatabaseFile>$(SymbolFolder)Debuger\$(OutputName).pdb</ProgramDatabaseFile>
<ImportLibrary>$(ImportFolder)$(OutputName).lib</ImportLibrary>
</Link>

<!-- Output Public Symbols If Folder Exists -->
<Link Condition="Exists('$(SymbolFolder)Publish')">
<StripPrivateSymbols>$(SymbolFolder)Publish\$(OutputName).pdb</StripPrivateSymbols>
</Link>
</ItemDefinitionGroup>

<!-- Append $(TargetSuffix) for OutputFile's Name -->
<PropertyGroup Condition="'$(TargetName)' == '$(ProjectName)'">
<TargetName Condition="'$(TargetOutput)' != ''">$(TargetOutput)</TargetName>
<TargetName Condition="'$(SingleFolder)' != 'false'">$(OutputName)</TargetName>
<TargetName Condition="'$(ConfigurationType)' == 'StaticLibrary'">$(OutputName)</TargetName>
</PropertyGroup>

<PropertyGroup>
<OutputPath Condition="'$(OutputPath)' != '$(OutDir)'">$(OutDir)</OutputPath>
</PropertyGroup>

</Project>

该属性设置文件的目的是,通过单目录输出选项“SingleFolder”来决定目录输出方案;

对于开源的第三方库,我喜欢将所有的输出放置到一个目录中,例如 .lib .dll,同时生成的目标文件带上平台和字符集的后缀,例如 ACE 的输出为 ACEUR64.dll 就是代表 “Unicode” 字符集 “Release“ 版 “64” 位 ,(在这里 64 位指 x64 平台),而要做到这一切,只需要在包含 ACE 的解决方案处放置一个 props 并设置属性"SingleFolder"为"true"就可以了,当然你也可以设置其他属性,例如我的解决方案路径为 D:\ToolKits\ThirdParty.sln ,那么我将下面的内容保存为 D:\ToolKits\ThirdParty.props

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SingleFolder>true</SingleFolder>
<OutputFolder>$(SolutionDir)Library</OutputFolder>
</PropertyGroup>
</Project>

 

则编译出来的第三方库都在 D:\ToolKits\Library 目录下,并且所有的第三方库的输出文件都有配置项目的后缀,调试符号则存放在 D:\ToolKits\Library\Debuger 下;目录结构如下:

  • D:\ToolKits\ThirdParty.sln
  • D:\ToolKits\ThirdParty.props
  • D:\ToolKits\Include\ACE\ACE.h
  • D:\ToolKits\Include\ACE\......
  • D:\ToolKits\Include\ACE\ACE.vcxproj
  • D:\ToolKits\Library\ACEUR64.dll
  • D:\ToolKits\Library\ACEUR64.lib
  • D:\ToolKits\Library\ACEUR32.dll
  • D:\ToolKits\Library\......
  • D:\ToolKits\Library\Debuger\ACEUR64.pdb

对于自己的解决方案,则使用默认的多目录输出方案,即无需为解决方案做任何配置,输出的目标文件按照类型放置到不同目录中,可执行程序和动态库放置到 Binary 目录中,调试符号放置到 Symbols 目录中,导入库和静态库则放置到 Library 目录中;而所有的目录都放置在解决方案的 Outputs 目录中,目录结构如下:

  • D:\Programs\SvcBox.sln
  • D:\Programs\Project\MyProj\MyProj.cpp
  • D:\Programs\Project\MyProj\MyProj.vcxproj
  • D:\Programs\Project\MyProj\…………
  • D:\Programs\Outputs\Binary.UR64\MyProj.dll
  • D:\Programs\Outputs\Binary.UR64\…………
  • D:\Programs\Outputs\Binary.UR32\MyProj.dll
  • D:\Programs\Outputs\Binary.UR32\…………
  • D:\Programs\Outputs\Library\MyProjUR64.lib
  • D:\Programs\Outputs\Library\…………
  • D:\Programs\Outputs\Symbols\Debuger\MyProjUR64.pdb
  • D:\Programs\Outputs\Config\MyProj.config.xml

这样新建工程就好办多了,不用每个工程都要一个一个的配置各个输出文件的路径了;

最后的建议是,不要把最上面的props 直接保存为 Microsoft.Cpp.Win32.user.props 或者 Microsoft.Cpp.X64.user.props 文件,而是利用导入功能,例如将 上面的 props 文件保存为 Microsoft.Cpp.Common.user.props , 然后打开 Microsoft.Cpp.Win32.user.props / Microsoft.Cpp.X64.user.props ( 或者其他更多的文件,例如 Microsoft.Cpp.Itanium.user.props )将其内容修改为如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<ImportGroup Label="PropertySheets" Condition="'$(SolutionDriver)' == ''">
<Import Project="$(UserRootDir)\Microsoft.Cpp.Common.user.props" />
</ImportGroup>

</Project>

 

 呵呵,这样清爽多了,如果你提供好了所有的文件,甚至可以使用批处理制作一个“安装包”,如下所示:

@ COPY /Y *.props "%LOCALAPPDATA%\Microsoft\MSBuild\v4.0\"

当然要求该批处理所在的目录下要有配置好的属性文件,当然你可以直接使用我配置好的,点击此处下载

最后:如果你有更好的建议,请告诉我 ;)

posted @ 2010-06-27 10:46  王志科  阅读(6279)  评论(2编辑  收藏  举报