59

我一直使用Visual Studio内置的GUI支持来配置我的项目,通常使用属性表,以便几个项目将使用通用集合。为多个项目和配置有效地使用Visual Studio项目属性

我的主要抱怨之一是管理多个项目,配置和平台。如果你只是使用主GUI来完成所有任务(右键点击项目 - >属性),它很快就会变得混乱,难以维护并容易出现错误(如未能正确定义一些宏或使用错误的运行时库等)。处理这样一个事实,即不同的人在不同的地方放置依赖库(例如,我的所有生活在“C:\ Libs \ [C,C++] \ [lib-name] \”中),然后经常管理这些库的不同版本不同的(发布,调试,x86,x64等)也是一个大问题,因为它大大增加了在新系统上设置它的时间复杂度,然后存在版本控制问题并且保持每个人的路径不同。 。

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

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

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

+1

我感到你的痛苦:我们的产品在工作中有超过600个vcproj。 :( – 2010-08-17 12:53:54

回答

67

我刚刚发现的财产以后我没有认为是可能的(它不是由GUI曝光),有助于使属性表更为有用。项目属性文件中许多标记的“条件”属性,它也可用于.props文件中!

我只是放在一起作为一个试验中,以下和它的工作很大,做了5(通用,64,86,调试,发布)独立属性表的任务!

<?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不能处理它,使用上面的属性表项目只是报告默认继承的值,如“$(项目名)”为目标。

+0

好技巧! – Mordachai 2011-01-04 20:59:47

+0

+1这与我使用的非常相似 – AJG85 2011-01-07 15:53:52

+0

是的,属性表在VS2k10中要强大得多。只是一个耻辱,没有一个是通过IDE公开的。我做了类似的事情,它真的简化了事情。 – jalf 2011-01-07 18:35:00

4

至于输出库的话,你可以选择所有的项目,然后弹出的属性页中,选择所有配置,所有平台,然后设定目标名称:

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

这会给像输出MYLIB-V100 86 Debug.lib

我们为附加库目录做一些类似的还有,使用$(PlatformName)#(Configuration)挑选出合适的库路径,但它确实意味着一些乱搞与李的初始设置braries。例如我们已经提升安装它的库到boost/lib.Win32boost/lib.x64


关于图书馆和人们在不同的地方安装它们,有几个选项。如果你有一个非常强大的源代码控制系统,你可以把所有东西都放在源代码控制中,生活在源代码旁边的libs文件夹中。如果您使用的库不止一个,或者它们特别大,那么这可能不起作用。

想到的另一个选项是在每个用户机器上设置一个指向其库文件夹根目录的环境变量,例如LIB_ROOT=c:\libraries,然后您可以在Visual Studio中以$(LIB_ROOT)的身份访问该环境变量。

+0

我已经做了一些这样的事情,但是有一些库在其名称中使用了其他名称(例如,opt代替release,-d代替-Debug)等,这仍然需要很多特殊规则(我的debug.props和release.props设置了用户宏来帮助解决这个问题,common.props实际上设置了include/lib路径)。没有考虑它的提升,好主意(如果包含自动链接不使用相同的名称为x86和x64版本,但boost.build人们似乎认为它的一个问题) – 2010-08-17 13:09:10

+0

我想你的PlatformShortName来自一个x86.props和x64.props必须正确地继承或什么,或者它只是没有证件? – 2010-08-17 13:12:27

+0

@Fire Lancer:说实话我不确定PlatformShortName是从哪里来的,我认为它必须是内置的,因为我们在属性表中没有任何特别的东西 – ngoozeff 2010-08-17 13:29:31

7

我有同样的痛苦在我的公司(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" 
    > 

您还可以使用变量(即UserMacro,其值可以是绝对的,甚至环境变量)的属性表基础上定制了很多东西你需要。例如,在Debug.vsprops

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

定义一个变量BIN然后当你在系列vsprops,说的,Output.x64.Library.vsprops

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

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

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

0

这听起来像它可能是值得一试构建工具 - 在我的地方,我们使用自定义该工具可以监视文件和项目以进行更改并计算依赖关系和编译顺序。添加一个新文件并不是什么大事 - 用msbuild编译。

如果我不得不编译比一堆的项目,我会使用类似恶性更多: http://nant.sourceforge.net/

20

我做了一些改进,可能是有人

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

有乐趣!

+2

你......疯了。但在一个好方法:) – 2015-03-03 15:56:34

+0

什么时候这将被评估?在加载项目时?我想将自定义后构建复制规则添加到属性表,以仅复制实际链接到项目的DLL。你认为这可能吗? – Bim 2016-05-19 14:07:34

+0

Bim,我认为它在构建之前进行了评估,因为它从注册表中读取变量(请参阅$(registry:key))。 – lunicon 2016-05-20 07:10:34

4

可以为每个配置创建一个单独的属性表。要做到这一点:

  1. 创建一个配置特定的属性表
  2. 打开属性管理器
  3. 右键单击配置(而不是项目),您想修改
  4. 点击“添加现有资产负债表“并添加您的工作表

这可以免除您将条件插入到多个配置的单张工作表中。如果您有一些您希望在配置之间共享的共同属性,请创建一个层次结构。顶部表格可用于所有配置,并且嵌套表格仅包含特定配置attribut

+0

完美!谢谢。 因此,您也可以在每个配置节点中创建新页面。易于陷入编辑共享页面的陷阱,该页面即使在每个配置节点下访问,也会影响所有配置。 – Justin 2015-10-28 09:34:23