インクリメンタル ビルド

大規模なプロジェクトをビルドする場合、今でも最新の以前にビルドされたコンポーネントが再ビルドされないことが重要です。 すべてのターゲットが毎回ビルドされると、各ビルドが完了するのに長い時間がかかります。 インクリメンタル ビルド (以前にビルドされていないターゲット、または古くなっているターゲットだけがリビルドされるビルド) を有効にするため、Microsoft Build Engine (MSBuild) では、入力ファイルのタイムスタンプと出力ファイルのタイムスタンプを比較して、ターゲットをスキップするか、ビルドするか、または部分的にリビルドするかどうかを判断できます。 ただし、入力と出力の間に一対一のマッピングが必要です。 変換を使用して、ターゲットがこの直接マッピングを識別できるようにすることができます。 変換の詳細については、「MSBuild 変換」を参照してください。

入力と出力を指定する

入力と出力がプロジェクト ファイルで指定されている場合は、ターゲットはインクリメンタル方式でビルドできます。

ターゲットに入力と出力を指定するには

  • Target 要素の Inputs 属性と Outputs 属性を使用します。 たとえば次のような点です。

    <Target Name="Build"
        Inputs="@(CSFile)"
        Outputs="hello.exe">
    

MSBuild では、入力ファイルのタイムスタンプと出力ファイルのタイムスタンプを比較して、ターゲットをスキップするか、ビルドするか、または部分的にリビルドするかどうかを判断できます。 次の例では、@(CSFile) 項目リスト内の任意のファイルが hello.exe ファイルよりも新しい場合、MSBuild によってそのターゲットが実行されます。それ以外の場合はスキップされます。

<Target Name="Build"
    Inputs="@(CSFile)"
    Outputs="hello.exe">

    <Csc
        Sources="@(CSFile)"
        OutputAssembly="hello.exe"/>
</Target>

ターゲットで入力と出力が指定されている場合は、各出力を 1 つの入力のみにマップできるか、出力と入力の間に直接マッピングがないかのいずれかになります。 たとえば前の Csc タスクでは、出力 hello.exe はどの単一の入力にもマップできず、すべての入力に依存します。

Note

入力と出力の間の直接マッピングが存在しないターゲットは、各出力が 1 つの入力のみにマップされるターゲットよりもより頻繁にビルドされます。これは、入力の一部が変更された場合に、どの出力をリビルドする必要があるかを MSBuild が判断できないためです。

LC タスクなど、出力と入力間の直接マッピングを識別できるタスクは、多くの入力から出力アセンブリを生成する CscVbc などとは異なり、インクリメンタル ビルドに最も適しています。

次の例では、架空のヘルプ システムのヘルプ ファイルをビルドするプロジェクトを使用します。 プロジェクトは、ソースの .txt ファイルを、中間の .content ファイルに変換し、これを XML メタデータ ファイルと結合してヘルプ システムで使用される最終の .help ファイルを生成することによって機能します。 プロジェクトでは、次の仮想タスクを使用します。

  • GenerateContentFiles: .txt ファイルを .content ファイルに変換します。

  • BuildHelp: .content ファイルと XML メタデータ ファイルを結合し、最終の .help ファイルをビルドします。

プロジェクトは、変換を使用して、GenerateContentFiles タスクで入力と出力間の一対一のマッピングを作成します。 詳細については、「MSBuild 変換」をご覧ください。 また、Output 要素が GenerateContentFiles タスクからの出力を BuildHelp タスクの入力として自動的に使用するように設定されます。

このプロジェクト ファイルには、ConvertBuild の両方のターゲットが含まれます。 GenerateContentFiles タスクと BuildHelp タスクはそれぞれ ConvertBuild のターゲットに配置され、各ターゲットがそれぞれインクリメンタル方式でビルドできるようにします。 Output 要素を使用することで、GenerateContentFiles タスクの出力が ContentFile 項目リストに配置され、BuildHelp タスクの入力として使用できます。 このように Output 要素を使用することで、1 つのタスクからの出力が別のタスクの入力として自動的に提供されるため、各タスクで個々の項目または項目リストから手動でリストする必要はありません。

Note

Convert ターゲットはインクリメンタル ビルドできますが、そのターゲットからのすべての出力は Build ターゲットの入力とし常に要求されます。 MSBuild では、Output 要素を使用する場合に、1 つのターゲットからのすべての出力が別のターゲットの入力として自動的に提供されます。

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

    <ItemGroup>
        <TXTFile Include="*.txt"/>
        <XMLFiles Include="\metadata\*.xml"/>
    </ItemGroup>

    <Target Name = "Convert"
        Inputs="@(TXTFile)"
        Outputs="@(TXTFile->'%(Filename).content')">

        <GenerateContentFiles
            Sources = "@(TXTFile)">
            <Output TaskParameter = "OutputContentFiles"
                ItemName = "ContentFiles"/>
        </GenerateContentFiles>
    </Target>

    <Target Name = "Build" DependsOnTargets = "Convert"
        Inputs="@(ContentFiles);@(XMLFiles)"
        Outputs="$(MSBuildProjectName).help">

        <BuildHelp
            ContentFiles = "@(ContentFiles)"
            MetadataFiles = "@(XMLFiles)"
            OutputFileName = "$(MSBuildProjectName).help"/>
    </Target>
</Project>