3

MSBuild のドキュメントでは、項目が必ずしもファイルと同じではないことがいくつかの場所で示唆されています。

「MSBuild アイテムはビルド システムへの入力であり、通常はファイルを表します。」

「アイテムは通常、ファイルを表すオブジェクトです。」

ただし、アイテムがファイルを表していない例が見つからないようです。特に、一連の非ファイル項目に対してバッチ処理を実行したいと考えています。しかし、私が作成するすべてのアイテムは、カスタム ビルド タスクからであっても、何らかの方法でファイルのようなメタデータ (FullPath、RootDir、Filename、Extension など) を取得します。さらに、ターゲットの入力をファイルではないアイテムのセットに設定することの影響と、そのターゲットの出力として何を使用するかについて混乱しています。

ファイル以外の項目を使用して MSBuild でバッチ処理を実行する例はありますか?

編集

例を思い付くのに時間がかかり申し訳ありません。私は物事をもう少し理解していますが、まだ確信が持てません (そして、これに関するドキュメントが完全に不足しているようです)。ここにあるものはすべて私の記憶から外れています。現在、職場のコンピューターにいないため、確認できません。

私の経験では、MSBuild は .sln ファイルの複数の構成を一度にビルドすることを好みません。したがって、この:

msbuild.exe SampleMSBuild.sln /p:Configuration=Debug%3BRelease

(エンコードされたセミコロンは、複数のプロパティを定義しようとしないために必要です。)

これを生成します:

"D:\src\SampleMSBuild\SampleMSBuild.sln" (default target) (1) ->
(ValidateSolutionConfiguration target) ->
  D:\src\SampleMSBuild\SampleMSBuild.sln.metaproj : error MSB4126: The 
  specified solution configuration "Debug;Release|Any CPU" is invalid. 
  Please specify a valid solution configuration using the Configuration 
  and Platform properties (e.g. MSBuild.exe Solution.sln 
  /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties 
  blank to use the default solution configuration. 
  [D:\src\SampleMSBuild\SampleMSBuild.sln]

したがって、バッチ処理とアイテムを使用してこれを処理できるようにする必要があるようです。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
         DefaultTarget="Rebuild" 
         ToolsVersion="4.0">
  <ItemGroup>
    <Configurations Include="Debug" />-->
    <Configurations Include="Release" />-->
  </ItemGroup>

  <UsingTask TaskName="LogMetadata"
             TaskFactory="CodeTaskFactory"
             AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <Items ParameterType="Microsoft.Build.Framework.ITaskItem[]" 
             Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
        foreach (var item in Items) {
          Console.Write(item.ItemSpec);
          Console.Write(" {");
          foreach (string metadataKey in item.MetadataNames) {
            Console.Write(metadataKey);
            Console.Write("=\"");
            Console.Write(item.GetMetadata(metadataKey).
                ToString().Replace("\"", "\\\""));
            Console.Write("\" ");
          }
          Console.WriteLine("}");
        }]]>
      </Code>
    </Task>
  </UsingTask>

  <Target Name="Rebuild">
    <LogMetadata Items="%(Configurations.Identity)" />
  </Target>
</Project>

これが生成されます:

Debug {
  FullPath="D:\src\SampleMSBuild\Debug" 
  RootDir="D:\" 
  Filename="Debug" 
  Extension="" 
  RelativeDir="" 
  Directory="src\SampleMSBuild\" 
  RecursiveDir="" 
  Identity="Debug" 
  ModifiedTime="" 
  CreatedTime="" 
  AccessedTime="" 
}
Release {
  FullPath="D:\src\SampleMSBuild\Release" 
  RootDir="D:\" 
  Filename="Release" 
  Extension="" 
  RelativeDir="" 
  Directory="src\SampleMSBuild\" 
  RecursiveDir="" 
  Identity="Release" 
  ModifiedTime="" 
  CreatedTime="" 
  AccessedTime=""
}

ご覧のとおり、アイテムにはあらゆる種類のファイル メタデータが添付されています。Include 属性は必須であるため削除できませんが、カスタム タスクでアイテムを合成することはできました。ただし、私がそれを行うと、彼らはまだ魔法のようにすべて同じファイルメタデータを取得します.

これの影響は何ですか?これらをターゲットへの入力または出力として指定していないため、ファイル メタデータによって問題が発生しますか? アイテムの FullPath メタデータで指定されたファイルが存在しないため、ビルド システムはターゲットをスキップするか、必要以上にビルドしますか? それらのファイルが存在した場合はどうなりますか? それは何か問題を引き起こしますか?

4

2 に答える 2

2

アイテムを使用して、いくつかのソリューションを次々に構築し、それらを使用して「手動」タスクを実行するため、独自のアイテムを定義します。

<ItemGroup>
 <MergeConfigurations Include="project1\project1.SDK.sln">
  <MergeOutAssemblyName>product1.dll</MergeOutAssemblyName>
  <MergePrimaryAssemblyName>project1.Interfaces.dll</MergePrimaryAssemblyName>
  <SolutionBinaries>project1\bin\$(FlavorToBuild)</SolutionBinaries>
 </MergeConfigurations>

 <MergeConfigurations Include="project1\project1.Plugin.sln">
  <MergeOutAssemblyName>product1.dll</MergeOutAssemblyName>
  <MergePrimaryAssemblyName>project1.Interfaces.dll</MergePrimaryAssemblyName>
  <SolutionBinaries>project1\bin\plugin\$(FlavorToBuild)</SolutionBinaries>
 </MergeConfigurations>
<ItemGroup>

次に、ターゲットを使用して情報を取得し、必要なことを行います。

<Target Name="MergeSolution"
      Inputs="%(MergeConfigurations.Identity)"
      Outputs="%(MergeConfigurations.Identity)\Ignore_this">

  <PropertyGroup>
   <MergeSolution>%(MergeConfigurations.Identity)</MergeSolution>
   <MergeOutAssemblyName>%(MergeConfigurations.MergeOutAssemblyName)</MergeOutAssemblyName>
   <MergePrimaryAssemblyName>%(MergeConfigurations.MergePrimaryAssemblyName)</MergePrimaryAssemblyName>
   <SolutionBinaries>%(MergeConfigurations.SolutionBinaries)</SolutionBinaries>
  </PropertyGroup>

  [....]
 </Target>

これが、必要な方向に向けるのに役立つことを願っています。

于 2012-12-13T16:41:28.257 に答える
1

ひっかけ問題。私は MSBuild 初心者で、最近バッチ処理を理解する必要があることに気付きました。

一般に、そうです。ITaskItem に関するサンプルや議論を目にするほとんどの場所で、それらはファイルに関するものになる傾向があるようです。しかし、基礎となる実装は非常に柔軟で、他の多くのものにも対処できます。私の場合、文字列と XML データを扱ってきました。

この MS の記事では、ファイル以外の ItemGroup とメタデータの優れた例がいくつか紹介されています。

この記事は、アイテムのメカニズムとプロパティとの違いについて説明している、私が見つけることができる最高の要約でした。また、@ と % の構文、文字列と項目の間の変換、およびこれらのファイル メタデータ プロパティがどこから来ているかについてのヒント (MSBuild は最適化されています) についても説明します。

タスクなどへのパラメーターとして使用されるインターフェースがある場合はいつでも、そのインターフェースのデフォルトの実装がどこかにあるでしょう。私の推測では、あなたのコード サンプルは内部でこれらの既定のオブジェクトを多数作成しており、それらは既定で作成されるメタデータを定義していると思います。このインターフェイスを自分で実装する場合は、この動作を変更できると思います。おそらく質問の範囲を超えていますが=)

于 2013-02-26T18:02:57.710 に答える