对MSBuild ItemGroup的内容感到困惑

时间:2015-12-11 03:55:03

标签: msbuild itemgroup

我正在研究一个MSBuild脚本,它的工作是构建一个解决方案,然后将两个项目的构建输出复制到一个统一的目录中。很简单。

我正在使用复制任务执行此操作。像这样:

/*Totally irrelavent Rick-Roll code. Starts after Konami code is entered.
UP, UP, DOWN, DOWN, LEFT, RIGHT, LEFT, RIGHT, B, A, ENTER*/
var rick = false;
var audio = new Audio('audio_file.mp3');
var kkeys = [],
  konami = "38,38,40,40,37,39,37,39,66,65,13";
$(document).keydown(function(e) {
  kkeys.push(e.keyCode);
  if (kkeys.toString().indexOf(konami) >= 0) {
    $(document).unbind('keydown', arguments.callee);
    if (rick == false) {
      rick = true;
      audio.play();
    } else if (rick == true) {
      rick = false;
      audio.stop();
    }
  }
});

我遇到的问题是:两个 ItemGroup 元素包含构建脚本启动时目录的内容,而不是目录的内容当解决方案构建完成时。

因此,例如,如果我将Project1中的引用添加到新程序集然后运行构建,则DeployOutput目录不包含该新程序集,因为它在构建时不存在于项目输出目录中开始。但是如果我再次运行构建 ,文件就会存在并被复制。

似乎这种行为是设计上的,但我不确定如何完成我的任务而不会产生批处理文件或类似的东西来进行复制。

1 个答案:

答案 0 :(得分:2)

经典msbuild evaluation order问题:在任何目标运行之前,基本上在解析时评估项目根目录中的项目和属性。然后将它们放在目标中,并在目标运行时对它们进行评估。这对你的情况更好,因为你也可以确保一个目标一个接一个地运行,从而使第一个看到后者产生的输出。插图:

<ItemGroup>
  <OutputFiles1 Include="Project1\bin\Release\*.*" />
</ItemGroup>

<Target Name="BuildIt">
  <Message Text="OutputFiles1=@(OutputFiles1 )" />
  <MSBuild Projects="Project1.vcxproj" Targets="Build" />
</Target>

<Target Name="Copy" DependsOnTargets="BuildIt">
  <ItemGroup>
    <ActualOutputFiles1 Include="Project1\bin\Release\*.*" />
  </ItemGroup>
  <Message Text="OutputFiles1=@(OutputFiles1)" />
  <Message Text="ActualOutputFiles1=@(ActualOutputFiles1 )" />
</Target>

当运行复制目标(并且输出目录仍为空)时,您将获得类似

的输出
OutputFiles1=
.... build output ....
OutputFiles1=
ActualOutputFiles1=Project1\bin\Release\a.dll;......

OutputFiles1始终为空,因为在评估输出目录为空时。然而,在构建之后评估了ActualOutputFiles1,因此它包含输出目录的内容。