Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对多个项目和配置有效地使用Visual Studio项目属性_C++_Visual Studio 2010_Visual Studio_Build_Projects And Solutions - Fatal编程技术网

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

C++ 对多个项目和配置有效地使用Visual Studio项目属性,c++,visual-studio-2010,visual-studio,build,projects-and-solutions,C++,Visual Studio 2010,Visual Studio,Build,Projects And Solutions,我一直使用Visual Studio内置的GUI支持来配置我的项目,通常使用属性表,以便多个项目将使用一个公共集 我的一个主要抱怨是管理多个项目、配置和平台。如果您只是使用主GUI(右键单击项目->属性)执行所有操作,它很快就会变得一团糟,难以维护,并且容易出现错误(例如无法正确定义某些宏,或者使用错误的运行库等等)。处理这样一个事实:不同的人在不同的地方放置依赖库(例如,我的所有依赖库都位于“C:\Libs\[C,C++]\[lib name]\”),然后经常以不同的方式管理这些库的不同版本(

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

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

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

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


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

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

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

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

对于其他库目录,我们也使用
$(PlatformName)
#(配置)执行类似的操作
选择正确的库路径,尽管这确实意味着在库的初始设置上会有一些混乱。例如,我们让boost将其libs安装到
boost/lib.Win32
boost/lib.x64


对于库,以及安装在不同地方的人,有两种选择。如果你有一个非常强大的源代码管理系统,你可以把所有东西都放在源代码管理中,放在源代码旁边的libs文件夹中。如果你使用的库超过几个,或者它们特别复杂,那么这可能不起作用阿吉


想到的另一个选项是在每台用户计算机上设置一个环境变量,该变量指向其库文件夹的根,例如
LIB\u root=c:\libraries
,然后您可以在Visual Studio中以
$(LIB\u root)

的身份访问它。我刚刚发现了一些我认为不可能的事情(它没有被GUI公开)这有助于使属性表更加有用。项目属性文件中许多标记的“条件”属性也可以在.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>

-d
x86
x64
vc90
vc100
$(项目名称)-(工具集)-(ShortPlatform)$(调试后缀)

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

我以前对公司的产品(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中定义BIN变量

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

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

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

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


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

这听起来可能值得一看构建工具——在我的位置上,我们使用一个定制的工具来监视文件和项目的更改,并计算依赖项和编译顺序。添加一个新文件不是什么大问题
<?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>