简体   繁体   English

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

[英]Using Visual Studio project properties effectively for multiple projects and configurations

I have always used Visual Studios built in GUI support for configuring my projects, often using property sheets so that several projects will use a common set.我一直使用 Visual Studios 内置的 GUI 支持来配置我的项目,经常使用属性表,以便多个项目使用一个公共集。

One of my main gripes with this is managing multiple projects, configurations and platforms.我对此的主要抱怨之一是管理多个项目、配置和平台。 If you just do everything with the main GUI (right click the project -> properties) it quickly becomes a mess, difficult to maintain and prone to bugs (like failing to correctly define some macro, or using the wrong runtime library, etc).如果您只是使用主 GUI 完成所有操作(右键单击项目 -> 属性),它很快就会变得一团糟,难以维护并且容易出现错误(例如无法正确定义某些宏,或使用错误的运行时库等)。 Dealing with the fact that different people put there dependency libraries in different places (eg mine all live in "C:\\Libs\\[C,C++]\\[lib-name]\\") and then often manage the different versions of those libraries differently as well (release, debug, x86, x64, etc) is also a large problem since it vastly complicates the time to set it up on a new system, and then there is issues with version-control and keeping everyone's paths separate...处理不同的人将依赖库放在不同位置的事实(例如我的都位于“C:\\Libs\\[C,C++]\\[lib-name]\\”),然后经常管理这些库的不同版本不同的(发布、调试、x86、x64 等)也是一个大问题,因为它使在新系统上设置它的时间大大复杂化,然后存在版本控制和保持每个人的路径分开的问题。 .

Property sheets make this a bit better, but I cant have one sheet have separate settings for different configurations and platforms (the drop down boxes a greyed out), resulting in me having many sheets which if inherited in the correct order do what I want ("x86", "x64", "debug", "release", "common", "directories" (deals with the previously mentioned dependency issue by defining user macros like BoostX86LibDir), etc) and if inherited in the wrong order (eg "common" before "x64" and "debug") lead to issues like trying to link an incorrect library version, or incorrectly naming the output...属性表使这更好一点,但我不能让一张表对不同的配置和平台有单独的设置(下拉框变灰),导致我有很多表,如果以正确的顺序继承,我想做的事( “x86”、“x64”、“debug”、“release”、“common”、“directories”(通过定义像 BoostX86LibDir 这样的用户宏来处理前面提到的依赖问题)等)并且如果以错误的顺序继承(例如“x64”和“debug”之前的“common”)会导致诸如尝试链接不正确的库版本或错误地命名输出之类的问题...

What I want is a way of dealing with all these scattered dependencies and setting up a set of "rules" which are used by all my projects in the solution, like naming an output library as "mylib-[vc90,vc100]-[x86,x64][-d].lib", without having to do all this for each individual project, configuration and platform combination, and then keep them all correctly in sync.我想要的是一种处理所有这些分散的依赖项并设置一组“规则”的方法,这些规则被解决方案中的所有项目使用,例如将输出库命名为“mylib-[vc90,vc100]-[x86 ,x64][-d].lib",而不必为每个单独的项目、配置和平台组合执行所有这些操作,然后使它们全部正确同步。

I am aware of moving to entirely different systems like CMake that create the needed files, however this then complicates things elsewhere by making it so even simple tasks like adding a new file to the project then requires additional changes elsewhere, which is not something I am entirely happy with either, unless there is some with VS2010 integration which can keep track of these sorts of changes.我知道转移到完全不同的系统,如创建所需文件的 CMake,但是这会使其他地方的事情复杂化,因为它使即使是简单的任务,如向项目添加新文件,然后需要在其他地方进行额外的更改,这不是我的事情对任何一个都非常满意,除非有一些与 VS2010 集成可以跟踪这些类型的变化。

I just found out somthing I didnt think was possible (it is not exposed by the GUI) that helps make property sheet far more useful. 我只是发现了一些我认为不可能的事情(GUI并未公开)可以帮助使属性表更加有用。 The "Condition" attribute of many of the tags in the project property files and it can be used in the .props files as well! 项目属性文件中许多标签的“ Condition”属性,也可以在.props文件中使用它!

I just put together the following as a test and it worked great and did the task of 5 (common,x64,x86,debug,release) separate property sheets! 我只是整理了以下内容作为测试,并且效果很好,并完成了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>

Only issue is the properties GUI cant handle it, a project that uses the above property sheet just reports default inherited values like "$(ProjectName)" for the target. 唯一的问题是GUI无法处理属性,使用上述属性表的项目仅报告目标的默认继承值,例如“ $(ProjectName)”。

I made some improvements, may be useful for somebody 我做了一些改进,可能对某人有用

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

have fun! 玩得开心!

I had same pain for the product of my company (200+ projects) before. 以前,我对公司的产品(200多个项目)有同样的痛苦。 The way I solved it is to build a nice hierarchy of the property sheets. 我解决的方法是建立属性表的良好层次结构。

The projects inherits the property sheet by its output type, say x64.Debug.Dynamic.Library.vsprops. 项目通过其输出类型(例如x64.Debug.Dynamic.Library.vsprops)继承属性表。 This vsprops file simply inherits other property sheets using the InheritedPropertySheets attribute 这个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"
    >

You can also use variables (ie UserMacro, whose value can be absolute or even environment variables) in property sheets to customize a lot of things based on your need. 您还可以在属性表中使用变量(即UserMacro,其值可以是绝对值甚至是环境变量)来根据需要自定义很多内容。 For example, defining a BIN variable in Debug.vsprops 例如,在Debug.vsprops中定义BIN变量

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

then when you set the output name in the series of vsprops, say, Output.x64.Library.vsprops 然后,当您在一系列vsprops中设置输出名称时,请说Output.x64.Library.vsprops

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

The $(BIN) variable will be expanded to what's been set (in this case, Debug). $(BIN)变量将扩展为已设置的值(在本例中为Debug)。 Use this technique you can easily construct a nice hierarchy of property sheets to meet your demand. 使用此技术,您可以轻松地构建良好的属性表层次结构来满足您的需求。

Now there's one more thing you might want to do: build your own project templates that uses your property sheet set. 现在,您可能还要做一件事:使用属性表集构建自己的项目模板。 The real difficult part is to enforce proper usage of the templates and property sheets. 真正困难的部分是强制正确使用模板和属性表。 My personal experience is that even if everything is setup, somebody will still forget to use the template to create new projects ... 我的个人经验是,即使一切都已设置,仍然有人会忘记使用模板来创建新项目...

It is possible to create a separate property sheet for each configuration. 可以为每个配置创建一个单独的属性表。 To do this: 去做这个:

  1. Create a configuration-specific property sheet 创建特定于配置的属性表
  2. Open the Property Manager 打开物业经理
  3. Right click the configuration (not the project) that you would like to modify 右键单击要修改的配置 (不是项目)
  4. Click "Add Existing Property Sheet" and add your sheet 单击“添加现有属性表”并添加您的表

This relieves you from inserting conditions into a single sheet for multiple configurations. 这使您不必将条件插入到多个配置的单张纸中。 If you have some common attributes that you would like to share between configurations, then create a hierarchy. 如果您要在配置之间共享某些通用属性,请创建一个层次结构。 The top sheet can be used in all configurations and the nested sheets will only contain the configuration-specific attribut 顶层工作表可用于所有配置,并且嵌套工作表将仅包含特定于配置的属性

As far as the output library goes, you can select all your projects, then bring up the property pages, select All Configurations, All Platforms and then set the Target Name to: 就输出库而言,您可以选择所有项目,然后调出属性页,选择“所有配置”,“所有平台”,然后将“目标名称”设置为:

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

which would give an output like mylib-v100-x86-Debug.lib 这将给出类似于mylib-v100-x86-Debug.lib的输出

We do something similar to this for Additional Library Directories as well, using $(PlatformName) and #(Configuration) to pick out the right library paths, although it does mean some messing around with initial setup of the libraries. 对于其他库目录,我们也执行类似的操作,使用$(PlatformName)#(Configuration)选择正确的库路径,尽管这确实意味着对库的初始设置有些麻烦。 eg we have boost install its libs to boost/lib.Win32 or boost/lib.x64 . 例如,我们已经将其库升压安装到boost/lib.Win32boost/lib.x64


With regards to libraries, and people installing them in different places, there are a couple of options. 关于库以及将它们安装在不同位置的人们,有两种选择。 If you have a very robust source control system, you can just put everything in source control, living in a libs folder next to your source. 如果您有一个非常强大的源代码管理系统,则可以将所有内容放入源代码管理中,位于源代码旁边的libs文件夹中。 That probably won't work if you use more than a few libraries though, or if they are particularly large. 如果您使用多个库,或者它们很大,那可能就行不通了。

The other option that comes to mind is to set an environment variable on each user machine that points to the root of their libraries folder, eg LIB_ROOT=c:\\libraries , and you can then access that in Visual Studio as $(LIB_ROOT) . 想到的另一个选择是在每个用户计算机上设置一个指向其库文件夹根目录的环境变量,例如LIB_ROOT=c:\\libraries ,然后可以在Visual Studio中以$(LIB_ROOT)访问该环境变量。

It sounds like it could be worth checking out a build tool - at my place we use a custom made tool that watches files and projects for changes and figures the dependencies and compile order. 听起来可能值得一试构建工具-在我这里,我们使用一个定制的工具,该工具可以监视文件和项目中的更改并计算依赖性和编译顺序。 Adding a new file is no big deal - compilation is done with msbuild. 添加新文件没什么大不了的-编译是通过msbuild完成的。

If i had to compile more than a bunch of projects I would use something like nant: http://nant.sourceforge.net/ 如果我不得不编译多个项目,那么我会使用类似nant的东西: http : //nant.sourceforge.net/

If you want to define some UserMacros which should be valid for the entire solution:如果要定义一些对整个解决方案有效的 UserMacros:

  1. Create a solution-global.props file in your solution root folder在您的解决方案根文件夹中创建一个solution-global.props文件

  2. Define there your UserMacros:在那里定义您的 UserMacros:

     <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="UserMacros" > <CommonUtilsDir>$(SolutionDir)Common\\Utils\\</CommonUtilsDir> <DriverBaseDir>$(SolutionDir)Common\\DriverBase\\</DriverBaseDir> </PropertyGroup> </Project>
  3. insert in each *.vcxproj file in which you want to use your custom macros this line:在要使用自定义宏的每个*.vcxproj文件中插入此行:

    <Import Project="$(SolutionDir)solution-global.props" />

  4. Use your custom macro:使用您的自定义宏:

    <AdditionalIncludeDirectories>$(CommonUtilsDir)\\Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

Works in VS2015适用于 VS2015

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Visual Studio 2010 - 在不同的构建配置之间保留项目属性? - Visual studio 2010 - retain project properties between different build configurations? 在多项目Visual Studio解决方案中以不同配置编译项目 - Compiling projects in different configurations in a multi-projects Visual Studio Solution 避免 Visual Studio 项目的配置过多 - Avoiding too many configurations for a Visual Studio project Visual Studio项目包含多个文件夹 - Visual Studio projects with multiple folders 具有多个项目的 Visual Studio 解决方案 - Visual studio solution with multiple projects Visual C ++ 2010多个项目的不同配置 - Visual C++ 2010 Different configurations for multiple projects 在Visual Studio中为单个解决方案编译和使用多个项目 - Compiling and using multiple projects for a single solution in Visual Studio Visual Studio 2008:如何将项目属性另存为要在其他项目中使用的属性表 - Visual Studio 2008: how to save project properties as a property sheet to be used in other projects 在Visual Studio中使用子项目 - Using sub projects in Visual Studio 如何使用 BatchBuild 并行构建多个 C++ Visual Studio v2015+ 配置 - How can you build multiple C++ visual studio v2015+ configurations in parallel using BatchBuild
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM