代码之家  ›  专栏  ›  技术社区  ›  Fire Lancer

对多个项目和配置有效地使用VisualStudio项目属性

  •  69
  • Fire Lancer  · 技术社区  · 14 年前

    我一直使用visualstudios内置的GUI支持来配置我的项目,经常使用属性表,以便几个项目将使用一个公共集。

    我的主要抱怨之一就是管理多个项目、配置和平台。如果只使用主GUI(右键单击项目->属性)执行所有操作,它很快就会变得一团糟,难以维护,并且容易出现错误(例如无法正确定义某些宏,或者使用错误的运行库等)。处理不同的人把不同的依赖库放在不同的地方(例如,我的所有的都在C:\LIBS[C,C++ ] [LIBNMEN] ]中,然后经常不同地管理这些库的不同版本(发布,调试,x86,x64,etc)也是一个大问题,因为在一个新系统上设置它的时间非常复杂,而且版本控制和保持每个人的路径独立也有问题。。。

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

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

    我意识到要转移到完全不同的系统,比如创建所需文件的CMake,但是这会使其他地方的事情变得复杂,即使是简单的任务,比如向项目添加新文件,也需要在其他地方进行额外的更改,这也不是我完全满意的,除非有一些与VS2010集成可以跟踪这些变化。

    6 回复  |  直到 9 年前
        1
  •  79
  •   Fire Lancer    14 年前

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

    <?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>
    

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

        2
  •  28
  •   lunicon    13 年前

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

    <?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>
    

        3
  •  12
  •   Peon the Great    13 年前

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

    <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"
        >
    

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

    <UserMacro name="BIN" Value="Debug" />
    

    <VisualStudioPropertySheet
        ProjectType="Visual C++"
        Version="8.00"
        OutputDirectory="$(BIN)"
    >
    

    $(BIN)变量将扩展到已设置的内容(在本例中为Debug)。使用此技术,您可以轻松地构建一个良好的属性表层次结构,以满足您的需求。

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

        4
  •  5
  •   gogisan    12 年前

    1. 打开属性管理器
    2. 配置 (不是要修改的项目)
    3. 单击“添加现有属性表”并添加您的表

        5
  •  4
  •   ngoozeff    14 年前

    对于输出库,您可以选择所有项目,然后打开属性页,选择所有配置、所有平台,然后将目标名称设置为:

    $(ProjectName)-$(PlatformToolset)-$(PlatformShortName)-$(Configuration)

    这将产生类似mylib-v100-x86的输出-调试.lib

    $(PlatformName) #(Configuration) 选择正确的库路径,尽管这确实意味着在库的初始设置上有些混乱。我们已经把它的libs安装到 boost/lib.Win32 boost/lib.x64 .


    想到的另一个选择是在每个用户机器上设置一个环境变量,该变量指向他们的libraries文件夹的根,例如 LIB_ROOT=c:\libraries $(LIB_ROOT) .

        6
  •  0
  •   Rune Andersen    13 年前

    这听起来像是一个值得检查的构建工具-在我的地方,我们使用一个定制的工具,监视文件和项目的变化,并数字的依赖关系和编译顺序。添加新文件没什么大不了的-编译是用msbuild完成的。

    如果我要编译更多的项目,我会使用nant: http://nant.sourceforge.net/