web-dev-qa-db-ja.com

Visual Studioプロジェクトプロパティを複数のプロジェクトと構成に効果的に使用する

私は常に、プロジェクトの構成にGUIサポートに組み込まれたVisual Studioを使用しました。多くの場合、プロパティシートを使用して、複数のプロジェクトで共通のセットを使用します。

これに関する私の主な不満の1つは、複数のプロジェクト、構成、およびプラットフォームの管理です。メインGUI(プロジェクトを右クリック->プロパティ)ですべてを行うと、すぐに混乱し、保守が難しくなり、バグ(マクロを正しく定義できない、間違ったランタイムライブラリを使用するなど)が発生しやすくなります。異なる人々が異なる場所に依存ライブラリを配置し(たとえば、私のすべてが "C:\ Libs\[C、C++]\[lib-name] \"に存在する)、それらのライブラリの異なるバージョンをしばしば管理するという事実に対処する同様に(リリース、デバッグ、x86、x64など)も、新しいシステムにセットアップする時間が非常に複雑になるため、バージョン管理と全員のパスの分離に問題があるため、大きな問題です。 。

プロパティシートはこれを少し改善しますが、1つのシートに異なる構成とプラットフォーム用の個別の設定を持たせることはできません(ドロップダウンボックスがグレー表示されます)。 「x86」、「x64」、「debug」、「release」、「common」、「directories」(BoostX86LibDirなどのユーザーマクロを定義することで前述の依存関係の問題に対処)など、間違った順序で継承された場合「x64」および「debug」の前の「common」は、誤ったライブラリバージョンをリンクしようとしたり、出力に誤って名前を付けたりするなどの問題を引き起こします...

私が欲しいのは、これらの散在するすべての依存関係を処理し、出力ライブラリに「mylib- [vc90、vc100]-[x86」という名前を付けるなど、ソリューション内のすべてのプロジェクトで使用される一連の「ルール」を設定する方法です、x64] [-d] .lib」、個々のプロジェクト、構成、プラットフォームの組み合わせごとにこれらすべてを実行する必要はなく、すべての同期を正しく維持します。

必要なファイルを作成するCMakeのようなまったく異なるシステムに移行することは承知していますが、これにより、プロジェクトに新しいファイルを追加するなどの単純なタスクでも他の場所で追加の変更が必要になるため、他の場所で物事が複雑になりますこれらの種類の変更を追跡できるVS2010統合の一部がない限り、どちらにも完全に満足しています。

69
Fire Lancer

プロパティシートをさらに便利にするのに役立つ(GUIで公開されていない)可能性があるとは思わなかったものを見つけました。プロジェクトプロパティファイル内の多くのタグの「条件」属性。propsファイルでも使用できます。

私はテストとして以下をまとめただけで、うまく機能し、5つの(common、x64、x86、debug、release)別のプロパティシートのタスクを実行しました!

<?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)」のようなデフォルトの継承値を報告するだけです。

77
Fire Lancer

私はいくつかの改善を行いました、誰かに役立つかもしれません

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

楽しんで!

27
lunicon

以前、私の会社の製品(200以上のプロジェクト)にも同じ痛みがありました。私が解決したのは、プロパティシートのNice階層を構築することです。

プロジェクトは、出力タイプ(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)に展開されます。この手法を使用すると、ニーズに合わせてプロパティシートのNice階層を簡単に構築できます。

もう1つやりたいことがあります。プロパティシートセットを使用する独自のプロジェクトテンプレートを作成します。本当に難しいのは、テンプレートとプロパティシートを適切に使用することです。私の個人的な経験では、すべてがセットアップされていても、誰かがテンプレートを使用して新しいプロジェクトを作成することを忘れることがあります...

11
Peon the Great

構成ごとに個別のプロパティシートを作成することができます。これをする:

  1. 構成固有のプロパティシートを作成する
  2. プロパティマネージャーを開く
  3. 変更するconfiguration(プロジェクトではなく)を右クリックします。
  4. [既存のプロパティシートを追加]をクリックして、シートを追加します

これにより、複数の構成の条件を1つのシートに挿入する必要がなくなります。構成間で共有する一般的な属性がある場合は、階層を作成します。トップシートはすべての構成で使用でき、ネストされたシートには構成固有の属性のみが含まれます

5
gogisan

出力ライブラリに関する限り、すべてのプロジェクトを選択し、プロパティページを表示して、[すべての構成]、[すべてのプラットフォーム]を選択し、[ターゲット名]を次のように設定できます。

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

mylib-v100-x86-Debug.libのような出力が得られます

$(PlatformName)#(Configuration)を使用して適切なライブラリパスを選択しますが、これはライブラリの初期セットアップをいじることを意味しますが、追加のライブラリディレクトリに対してもこれに似た処理を行います。たとえば、ライブラリをboost/lib.Win32またはboost/lib.x64に追加インストールします。


ライブラリ、およびそれらを異なる場所にインストールする人々に関しては、いくつかのオプションがあります。非常に堅牢なソース管理システムを使用している場合は、ソース管理のすべてを配置し、ソースの隣のlibsフォルダーに配置することができます。ただし、いくつかのライブラリを使用する場合、またはそれらが特に大きい場合は、おそらく機能しません。

思い浮かぶもう1つのオプションは、各ユーザーマシンでライブラリフォルダーのルートを指す環境変数を設定することです(例:LIB_ROOT=c:\libraries)。Visual Studioで$(LIB_ROOT)としてアクセスできます。 。

4
ngoozeff

ビルドツールをチェックアウトする価値があるように思えます-私の場所では、ファイルとプロジェクトの変更を監視し、依存関係とコンパイル順序を計算するカスタムメイドのツールを使用します。新しいファイルを追加することは大したことではありません-コンパイルはmsbuildで行われます。

複数のプロジェクトをコンパイルする必要がある場合、nantのようなものを使用します。 http://nant.sourceforge.net/

0
Rune Andersen