.vcxproj.props ファイルの構造

MSBuild は、Visual Studio の既定のプロジェクト システムです。Visual C++ で [ファイル]>[新しいプロジェクト] を選ぶと、MSBuild プロジェクトが作成されて、その設定が拡張子 .vcxproj の XML プロジェクト ファイルに格納されます。 プロジェクト ファイルでは .props ファイルと .targets ファイルをインポートすることもでき、これらのファイルにも設定を格納できます。

プロジェクトのプロパティを IDE にメインする場合は、IDE でプロジェクトを.vcxproj作成および変更することのみをお勧めします。また、ファイルを手動で編集しないようにすることをお勧めします。 ほとんどの場合、プロジェクト ファイルを手動で編集する必要はありません。 手動で編集すると、Visual Studio プロパティ ページのプロジェクト設定を変更するために必要なプロジェクト接続が切断され、デバッグや修復が困難なビルド エラーが発生する可能性があります。 プロパティ ページの使用方法の詳細については、「Visual Studio で C++ コンパイラとビルド プロパティを設定する」を参照してください

大規模に、IDE で多数の個々のプロジェクトを管理することは面倒になり、エラーが発生しやすくなります。 一貫性をメインしたり、数十から数百のプロジェクトにわたって標準化を実施したりすることは困難です。 このような場合は、プロジェクト ファイルを編集して、多くのプロジェクトの共通プロパティに合わせてカスタマイズまたは.props.targetsファイルを使用する価値があります。 IDE では不可能なカスタマイズが必要な場合は、これらのファイルを使用することもできます。 Directory.Build.props ファイルと Directory.Build.targets ファイルはカスタマイズを挿入する便利な場所で、すべての MSBuild ベースのプロジェクトに自動的にインポートされます。

場合によっては、プロジェクト管理のニーズに合わせてカスタマイズ .props または .targets ファイルだけでは不十分な場合があります。 プロジェクト ファイルまたはプロパティ シートを手動で変更 .vcxproj する必要がある場合があります。 手動編集では、MSBuild をよく理解している必要があり、この記事のガイドラインに従う必要があります。 IDE で .vcxproj ファイルを自動的に読み込んで更新するために、これらのファイルには、MSBuild のその他のプロジェクト ファイルには適用されないいくつかの制限があります。 間違いがあると、IDE がクラッシュしたり、予期しない動作が発生したりする可能性があります。

手動で編集するシナリオのために、この記事では .vcxproj と関連ファイルの構造に関する基本的な情報を提供します。

重要な考慮事項

.vcxproj ファイルを手動で編集する場合は、次のことに注意してください。

  • ファイルの構造は、この記事に記載されている所定のフォームに従う必要があります。

  • 現在、Visual Studio C++ プロジェクト システムでは、プロジェクト項目でワイルドカードとリストを直接的にはサポートしていません。 たとえば、次の形式はサポートしていません。

    <ItemGroup>
       <None Include="*.txt"/>
       <ClCompile Include="a.cpp;b.cpp"/>
    </ItemGroup>
    

    プロジェクトでのワイルドカードのサポートと考えられる回避策の詳細については、「.vcxproj ファイルとワイルドカード」を参照してください。

  • 現在、Visual Studio C++ プロジェクト システムでは、プロジェクト項目パスでのマクロをサポートしていません。 たとえば、次の形式はサポートしていません。

    <ItemGroup>
       <ClCompile Include="$(IntDir)\generated.cpp"/>
    </ItemGroup>
    

    "サポートされていない" とは、IDE において、すべての操作に対してマクロが機能することが保証されないという意味です。 異なる構成でその値を変えないマクロは機能するはずですが、ある項目が別のフィルターまたはプロジェクトに移動すると保持されないことがあります。 構成ごとに値が変化するマクロを使用すると、問題が発生します。 IDE では、プロジェクト項目のパスがプロジェクト構成ごとに異なるとは想定されていません。

  • [プロジェクトのプロパティ] ダイアログで編集するときにプロジェクトのプロパティを正しく追加、削除、変更するには、ファイルにプロジェクト構成ごとに別個のグループが含まれている必要があります。 条件は次の形式で指定する必要があります。

    Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"
    
  • 各プロパティは、プロパティ規則ファイル内で指定されている正しいラベルを持つグループにおいて指定されている必要があります。 詳しくは、「プロパティ ページの XML 規則ファイル」をご覧ください。

.vcxproj ファイルの要素

任意のテキスト エディターまたは XML エディターを使用して、.vcxproj ファイルの内容を調べることができます。 Visual Studio のソリューション エクスプローラーでプロジェクトを右クリックし、[プロジェクトのアンロード][Foo.vcxproj の編集] の順に選ぶと表示されます。

最初に注目する点は、最上位の要素が特定の順序で表示されることです。 次に例を示します。

  • ほとんどのプロパティ グループおよび項目定義グループは、Microsoft.Cpp.Default.props のインポートの後に出現します。

  • すべてのターゲットは、ファイルの最後にインポートされます。

  • 複数のプロパティ グループがあり、それぞれが一意のラベルを持ち、特定の順序で出現します。

MSBuild は順次評価モデルに基づいているため、プロジェクト ファイル内の要素の順序が非常に重要です。 インポートされたすべての .props ファイルと .targets ファイルを含むプロジェクト ファイルが、複数のプロパティ定義で構成されている場合、最後の定義によって前の定義がオーバーライドされます。 次の例では、コンパイル中に値 "xyz" が設定されますが、これは MSBUild エンジンによる評価中に値 "xyz" が最後に検出されるためです。

  <MyProperty>abc</MyProperty>
  <MyProperty>xyz</MyProperty>

次のスニペットに、最小限の .vcxproj ファイルを示します。 Visual Studio によって生成される .vcxproj ファイルには、それら MSBuild の最上位の要素が含まれます。 また、そのような最上位の各要素の複数のコピーが含まれている場合もありますが、この順序で表示されます。 Label 属性は任意のタグであり、Visual Studio によって編集のための目印としてのみ使用されます。それ以外の機能はありません。

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
  <ItemGroup Label="ProjectConfigurations" />
  <PropertyGroup Label="Globals" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
  <PropertyGroup Label="Configuration" />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings" />
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <ItemDefinitionGroup />
  <ItemGroup />
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets" />
</Project>

次のセクションでは、これらの各要素の目的と、その順序の理由について説明します。

Project 要素

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >

Project はルート ノードです。 使用される MSBuild のバージョンを指定し、このファイルが MSBuild.exe に渡されたときに実行する既定のターゲットも指定します。

ItemGroup の ProjectConfigurations 要素

<ItemGroup Label="ProjectConfigurations" />

ProjectConfigurations には、プロジェクトの構成の説明が含まれます。 たとえば、Debug|Win32、Release|Win32、Debug|ARM などです。 プロジェクトの多くの設定は、特定の構成に固有です。 たとえば、リリース ビルドでは最適化プロパティを設定しても、デバッグ ビルドでは設定しないことがあります。

ProjectConfigurations 項目グループは、ビルド時には使用されません。 Visual Studio IDE でプロジェクトを読み込むために必要です。 この項目グループを .props ファイルに移動して、.vcxproj ファイルにインポートすることができます。 ただし、その際に、構成の追加または削除が必要になった場合は、.props ファイルを手動で編集する必要があります。IDE を使用することはできません。

ProjectConfiguration 要素

次のスニペットでは、プロジェクトの構成を示します。 この例では、"Debug|x64" が構成の名前です。 プロジェクトの構成の名前は、$(Configuration)|$(Platform) という形式になっている必要があります。 ProjectConfiguration ノードには、ConfigurationPlatform という 2 つのプロパティがある場合があります。 構成がアクティブになると、ここで指定した値がこれらのプロパティに自動的に設定されます。

<ProjectConfiguration Include="Debug|x64">
  <Configuration>Debug</Configuration>
  <Platform>x64</Platform>
</ProjectConfiguration>

IDE では、すべての ProjectConfiguration 項目で使用されている ConfigurationPlatform の値の任意の組み合わせに対して、プロジェクトの構成が見つかるものと想定しています。 多くの場合、これはこの要件を満たすためにプロジェクトに意味のないプロジェクト構成が存在する可能性があることを意味します。 たとえば、プロジェクトに次のような構成があるものとします。

  • Debug|Win32

  • Retail|Win32

  • Special 32-bit Optimization|Win32

この場合、"Special 32-bit Optimization" は x64 に対しては意味がありませんが、次のような構成も存在する必要があります。

  • Debug|x64

  • Retail|x64

  • Special 32-bit Optimization|x64

ソリューション構成マネージャーでは、任意の構成に対してビルドと配置のコマンドを無効にできます。

PropertyGroup の Globals 要素

<PropertyGroup Label="Globals" />

Globals には、ProjectGuidRootNamespaceApplicationType または ApplicationTypeRevision などのプロジェクト レベルの設定が含まれます。 最後の 2 つは、多くの場合、ターゲット OS を定義します。 プロジェクトでターゲットに設定できるのは単一の OS のみです。現在、参照やプロジェクト項目には条件を設定できないためです。 これらのプロパティは、通常、プロジェクト ファイル内の他の場所ではオーバーライドされません。 このグループは構成に依存しないので、普通、プロジェクト ファイル内に存在する Globals グループは 1 つのみです。

Import の Microsoft.Cpp.default.props 要素

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />

Microsoft.Cpp.default.props プロパティ シートは Visual Studio に付属しており、変更できません。 プロジェクトの既定の設定が含まれます。 既定値は、ApplicationType によって異なる場合があります。

PropertyGroup の Configuration 要素

<PropertyGroup Label="Configuration" />

Configuration プロパティ グループには、添付された構成条件 (Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" など) があり、構成ごとに 1 つずつの、複数のコピーが提供されます。 このプロパティ グループは、特定の構成に対して設定されるプロパティをホストします。 構成プロパティは PlatformToolset を含み、Microsoft.Cpp.props でのシステム プロパティ シートのインクルードも制御します。 たとえば、プロパティ <CharacterSet>Unicode</CharacterSet> を定義した場合、システム プロパティ シート microsoft.Cpp.unicodesupport.props がインクルードされます。 Microsoft.Cpp.props を調べると、<Import Condition="'$(CharacterSet)' == 'Unicode'" Project="$(VCTargetsPath)\microsoft.Cpp.unicodesupport.props" /> という行が見つかります。

Import の Microsoft.Cpp.props 要素

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

Microsoft.Cpp.props プロパティ シートでは、多くのツール固有プロパティの既定値が (直接的に、またはインポートを介して) 定義されています。 例として、コンパイラの最適化と警告レベルのプロパティや、MIDL ツールの TypeLibraryName プロパティなどが含まれます。 また、その直前にあるプロパティ グループで定義されている構成プロパティに基づいて、さまざまなシステム プロパティ シートをインポートします。

ImportGroup の ExtensionSettings 要素

<ImportGroup Label="ExtensionSettings" />

ExtensionSettings グループには、ビルドのカスタマイズの一部であるプロパティ シートのインポートが含まれます。 ビルドのカスタマイズは、最大 3 つのファイル (.targets ファイル、.props ファイル、.xml ファイル) によって定義されます。 このインポート グループには、.props ファイルのインポートが含まれています。

ImportGroup の PropertySheets 要素

<ImportGroup Label="PropertySheets" />

PropertySheets グループには、ユーザー プロパティ シートのインポートが含まれます。 これらのインポートは、Visual Studio のプロパティ マネージャー ビューを通じて追加するプロパティ シートです。 これらのインポートは列記されている順序が重要であり、プロパティ マネージャーに反映されます。 通常、プロジェクト ファイルには、この種のインポート グループの複数のインスタンス (プロジェクト構成ごとに 1 つずつ) が含まれます。

PropertyGroup の UserMacros 要素

<PropertyGroup Label="UserMacros" />

UserMacros には、ユーザーが変数として作成し、ビルド プロセスのカスタマイズに使われるプロパティが含まれます。 たとえば、カスタム出力パスを定義するためのユーザー マクロを $(CustomOutputPath) として定義し、それを使って他の変数を定義できます。 このプロパティ グループは、そのようなプロパティを格納します。 Visual Studio では、Visual C++ が構成用のユーザー マクロをサポートしていないため、このグループはプロジェクト ファイル内に作成されません。 ユーザー マクロは、プロパティ シートでサポートされています。

構成ごとの PropertyGroup 要素

<PropertyGroup />

このプロパティ グループには、すべてのプロジェクト構成の構成ごとに 1 つずつ、複数のインスタンスがあります。 各プロパティ グループには、1 つの構成条件が添付されている必要があります。 いずれかの構成がない場合、[プロジェクトのプロパティ] ダイアログは正しく動作しません。 前に示したプロパティ グループとは異なり、このグループにはラベルがありません。 このグループには、プロジェクトの構成レベルの設定が含まれます。 これらの設定は、指定された項目グループの一部であるすべてのファイルに適用されます。 ビルドのカスタマイズ項目定義のメタデータはここで初期化されます。

この PropertyGroup は <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> の後に続ける必要があり、それより前に Label のない他の PropertyGroup が存在していてはなりません (そうしないと、プロジェクトのプロパティの編集が正しく動作しません)。

構成ごとの ItemDefinitionGroup 要素

<ItemDefinitionGroup />

項目の定義が含まれます。 それらの定義は、ラベルのない構成ごとの PropertyGroup 要素と同じ条件規則に従う必要があります。

ItemGroup 要素

<ItemGroup />

ItemGroup 要素には、プロジェクト内の項目 (ソース ファイルなど) が格納されます。 プロジェクト項目 (つまり、規則の定義によってプロジェクト項目として扱われる項目の種類) に対しては、条件はサポートされていません。

メタデータでは、構成ごとに構成の条件が必要です (すべて同じであっても)。 次に例を示します。

<ItemGroup>
  <ClCompile Include="stdafx.cpp">
    <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError>
    <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError>
  </ClCompile>
</ItemGroup>

Visual Studio C++ プロジェクト システムでは現在、プロジェクト項目でのワイルドカードをサポートしていません。

<ItemGroup>
  <ClCompile Include="*.cpp"> <!--Error-->
</ItemGroup>

Visual Studio C++ プロジェクト システムでは現在、プロジェクト項目でのマクロをサポートしていません。

<ItemGroup>
  <ClCompile Include="$(IntDir)\generated.cpp"> <!--not guaranteed to work in all scenarios-->
</ItemGroup>

参照は ItemGroup で指定され、次のような制限があります。

  • 参照では、条件をサポートしていません。

  • 参照のメタデータでは、条件をサポートしていません。

Import の Microsoft.Cpp.targets 要素

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

ビルド、クリーンなどの C++ ターゲットを (直接、またはインポートを介して) 定義します。

ImportGroup の ExtensionTargets 要素

<ImportGroup Label="ExtensionTargets" />

このグループには、ビルド カスタマイズのターゲット ファイルのインポートが含まれます。

順序が正しくない場合の結果

Visual Studio IDE の動作は、プロジェクト ファイルが前に説明した順序になっていることに依存します。 たとえば、プロパティ ページでプロパティの値を定義すると、IDE は一般に、ラベルが空であるプロパティ グループにそのプロパティの定義を配置します。 この順序より、システム プロパティ シートで取り込まれた既定値が、ユーザー定義の値によって確実にオーバーライドされます。 同様に、ターゲット ファイルは、それより前に定義されているプロパティを使用し、一般にそれ自体ではプロパティを定義していないため、最後にインポートされます。 同じように、ユーザー プロパティ シートはシステム プロパティ シートの後でインポートされます (Microsoft.Cpp.props によってインクルードされます)。 この順序により、ユーザーはシステム プロパティ シートによって取り込まれたすべての既定値をオーバーライドできます。

.vcxproj ファイルがこのレイアウトに従っていない場合、意図したビルド結果にならない可能性があります。 たとえば、誤ってユーザー定義のプロパティ シートの後でシステム プロパティ シートをインポートした場合、ユーザーの設定はシステム プロパティ シートによってオーバーライドされます。

IDE のデザイン時のエクスペリエンスも、要素の正しい順序にある程度依存します。 たとえば、.vcxproj ファイルに PropertySheets インポート グループがない場合、IDE は、ユーザーがプロパティ マネージャーで作成した新しいプロパティ シートを配置する場所を決定できない可能性があります。 その結果、ユーザーのシートがシステムのシートによってオーバーライドされる場合があります。 IDE によって使用されるヒューリスティックは、.vcxproj ファイルのレイアウトの小さな不整合は許容できますが、この記事でこれまでに示した構造から外れないようにすることを強くお勧めします。

IDE が要素のラベルを使用する方法

IDE では、全般プロパティ ページで UseOfAtl プロパティを設定すると、プロジェクト ファイルの Configuration プロパティ グループに書き込まれます。 同じプロパティ ページの TargetName プロパティは、ラベルのない構成ごとのプロパティ グループに書き込まれます。 Visual Studio は、プロパティ ページの xml ファイルで、各プロパティを書き込む場所についての情報を取得します。 [全般] プロパティ ページでは (Visual Studio 2019 Enterprise Edition の英語版を使用しているとした場合)、そのファイルは %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCTargets\1033\general.xml です。 プロパティ ページの XML 規則ファイルでは、Rule とそのすべてのプロパティに関する静的な情報が定義されています。 そのような情報の 1 つは、書き込み先ファイル (その値が書き込まれるファイル) での Rule プロパティの優先位置です。 優先位置は、プロジェクト ファイルの要素の Label 属性によって指定されます。

プロパティ シートのレイアウト

次の XML スニペットは、プロパティ シート (.props) ファイルの最小限のレイアウトです。 .vcxproj ファイルに似ており、.props の要素の機能は、これまでの説明から推測できるものです。

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <ItemDefinitionGroup />
  <ItemGroup />
</Project>

独自のプロパティ シートを作成するには、VCTargets フォルダー内の .props ファイルの 1 つをコピーし、目的に応じて変更します。 Visual Studio 2019 Enterprise Edition の場合、VCTargets の既定のパスは %ProgramFiles%\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCTargets です。

関連項目

Visual Studio で C++ コンパイラとビルド プロパティを設定する
プロパティ ページの XML ファイル
.vcxproj ファイルとワイルドカード