有效地为多个项目和配置使用Visual Studio项目属性

Fir*_*cer 70 c++ projects-and-solutions build visual-studio-2010 visual-studio

我一直使用Visual Studio内置的Visual Studio来配置我的项目,通常使用属性表,以便多个项目将使用一个公共集.

我最关心的一个问题是管理多个项目,配置和平台.如果您只使用主GUI(右键单击项目 - >属性)执行所有操作,它很快就会变得混乱,难以维护并容易出现错误(例如无法正确定义某些宏,或使用错误的运行时库等).处理不同的人在不同的地方放置依赖库的事实(例如我的所有人都住在"C:\ Libs\[C,C++]\[lib-name] \"),然后经常管理这些库的不同版本不同的(发布,调试,x86,x64等)也是一个大问题,因为它使在新系统上设置它的时间大大复杂化,然后版本控制存在问题并且将每个人的路径分开. .

属性表使这更好一点,但我不能让一张表有不同的配置和平台的单独设置(下拉框显示为灰色),导致我有许多表,如果以正确的顺序继承做我想要的( "x86","x64","debug","release","common","目录"(通过定义BoostX86LibDir等用户宏来处理前面提到的依赖性问题)等,如果以错误的顺序继承(例如"x64"和"debug"之前的"common"会导致尝试链接不正确的库版本或错误地命名输出等问题...

我想要的是一种处理所有这些分散的依赖关系并设置一组"规则"的方法,这些规则被解决方案中的所有项目使用,例如将输出库命名为"mylib- [vc90,vc100] - [x86 ,x64] [ - d] .lib",无需为每个单独的项目,配置和平台组合执行所有这些操作,然后使它们保持正确同步.

我知道转移到完全不同的系统,如CMake创建所需的文件,然而这使其他地方的事情变得复杂,因为即使是简单的任务,如在项目中添加新文件,然后需要在其他地方进行其他更改,这不是我的事情.除非有一些VS2010集成可以跟踪这些变化,否则完全满意.

Fir*_*cer 79

我刚刚发现了我认为不可能的事情(它没有被GUI公开),这有助于使属性表更有用.项目属性文件中许多标记的"Condition"属性,也可以在.props文件中使用!

我只是将以下内容放在一起作为测试,它运行良好,并完成了5个(常见的,x64,x86,调试,发布)单独的属性表的任务!

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="UserMacros">
    <!--debug suffix-->
    <DebugSuffix Condition="'$(Configuration)'=='Debug'">-d</DebugSuffix>
    <DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
    <!--platform-->
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform>
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform>
    <!--toolset-->
    <Toolset Condition="'$(PlatformToolset)' == 'v90'">vc90</Toolset>
    <Toolset Condition="'$(PlatformToolset)' == 'v100'">vc100</Toolset>
  </PropertyGroup>
  <!--target-->
  <PropertyGroup>
    <TargetName>$(ProjectName)-$(Toolset)-$(ShortPlatform)$(DebugSuffix)</TargetName>
  </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

唯一的问题是GUI无法处理它的属性,使用上述属性表的项目只报告目标的默认继承值,如"$(ProjectName)".

  • 如果您需要更高级的String函数,可以使用System.String方法:http://msdn.microsoft.com/en-us/library/system.string_methods%28v=vs.110%29.aspx示例:`< ShortHasRelPos> $(Configuration.ToLower().LastIndexOf( '相对'))</ ShortHasRelPos> (4认同)

lun*_*con 28

我做了一些改进,可能对某些人有用

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="UserMacros">
    <!--IsDebug: search for 'Debug' in Configuration-->
    <IsDebug>$([System.Convert]::ToString( $([System.Text.RegularExpressions.Regex]::IsMatch($(Configuration), '[Dd]ebug'))))</IsDebug>

    <!--ShortPlatform-->
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform>
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform>

    <!--build parameters-->
    <BUILD_DIR>$(registry:HKEY_CURRENT_USER\Software\MyCompany\@BUILD_DIR)</BUILD_DIR>
  </PropertyGroup>

  <Choose>
    <When Condition="$([System.Convert]::ToBoolean($(IsDebug)))">
      <!-- debug macroses -->
      <PropertyGroup Label="UserMacros">
        <MyOutDirBase>Debug</MyOutDirBase>
        <DebugSuffix>-d</DebugSuffix>
      </PropertyGroup>
    </When>
    <Otherwise>
      <!-- other/release macroses -->
      <PropertyGroup Label="UserMacros">
        <MyOutDirBase>Release</MyOutDirBase>
        <DebugSuffix></DebugSuffix>
      </PropertyGroup>
    </Otherwise>
  </Choose>

  <Choose>
    <When Condition="Exists($(BUILD_DIR))">
      <PropertyGroup Label="UserMacros">
        <MyOutDir>$(BUILD_DIR)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir>
        <MyIntDir>$(BUILD_DIR)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup Label="UserMacros">
        <MyOutDir>$(SolutionDir)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir>
        <MyIntDir>$(SolutionDir)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir>
      </PropertyGroup>
    </Otherwise>
  </Choose>

  <PropertyGroup>
    <OutDir>$(MyOutDir)</OutDir>
    <IntDir>$(MyIntDir)</IntDir>
<!-- some common for projects
    <CharacterSet>Unicode</CharacterSet>
    <LinkIncremental>false</LinkIncremental>
--> 
  </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

玩得开心!


Peo*_*eat 12

我之前对我公司的产品(200多个项目)也有同样的痛苦.我解决它的方法是建立一个很好的属性表层次结构.

项目按其输出类型继承属性表,例如x64.Debug.Dynamic.Library.vsprops.此vsprops文件使用InheritedPropertySheets属性简单地继承其他属性表

<VisualStudioPropertySheet
    ProjectType="Visual C++"
    Version="8.00"
    Name="x64.Debug.Dynamic.Binary"
    InheritedPropertySheets=".\Common.vsprops;.\x64.vsprops;.\Debug.vsprops;.\Runtime.Debug.Dynamic.vsprops;.\Output.x64.Library.vsprops"
    >
Run Code Online (Sandbox Code Playgroud)

您还可以在属性表中使用变量(即UserMacro,其值可以是绝对值或甚至是环境变量)来根据您的需要自定义很多内容.例如,在Debug.vsprops中定义BIN变量

<UserMacro name="BIN" Value="Debug" />
Run Code Online (Sandbox Code Playgroud)

然后当您在vsprops系列中设置输出名称时,例如,Output.x64.Library.vsprops

<VisualStudioPropertySheet
    ProjectType="Visual C++"
    Version="8.00"
    OutputDirectory="$(BIN)"
>
Run Code Online (Sandbox Code Playgroud)

$(BIN)变量将扩展为已设置的值(在本例中为Debug).使用这种技术,您可以轻松构建一个很好的属性表层次结构,以满足您的需求.

现在还有一件事你可能想做:构建自己的项目模板,使用你的属性表集.真正困难的部分是强制正确使用模板和属性表.我的个人经验是,即使一切都已设置,有人仍会忘记使用模板创建新项目......


小智 5

可以为每个配置创建单独的属性表.去做这个:

  1. 创建特定于配置的属性表
  2. 打开物业经理
  3. 右键单击要修改的配置(而不是项目)
  4. 单击"添加现有属性表"并添加工作表

这样可以减轻您将条件插入单个工作表以进行多种配置的麻烦.如果您希望在配置之间共享某些公共属性,则创建层次结构.顶部工作表可用于所有配置,嵌套工作表仅包含特定于配置的属性