6

我在命令行上使用 msbuild 来构建一个包含 C++ 项目的 VS2012 解决方案。该项目有一个在构建之后运行的目标:

<Target Name="RunTargetAfterBuild" AfterTargets="Build">
  <Error Text="I am a failing target" />
</Target>

我希望 msbuild 在构建时返回错误,但是在构建过程中的某个地方,错误会丢失并且 msbuild 报告“构建成功”。因此,ERRORLEVEL 仍然设置为 0,因此很难检测到在自动构建期间是否出现问题。如何让 msbuild 将此错误一直传播到顶级项目/解决方案?我知道这是可能的,因为编译器错误等会发生这种情况。

以下是输出的相关部分:

> msbuild test.sln

...

...: error : I am a failing target  [...test.vcxproj]
Done Building Project "...test.vcxproj" (default targets) -- FAILED.

Done Building Project "...test.vcxproj.metaproj" (default targets).

Done Building Project "...test.sln" (Build target(s)).

Build succeeded.    --> this is NOT what I want

....

0 Warning(s)
1 Error(s)

而对于编译器错误,输出是这样的:

> msbuild test.sln

....

...: error C3861: 'HECK': identifier not found [...test.vcxproj]
Done Building Project "...test.vcxproj" (default targets) -- FAILED.

Done Building Project "...test.vcxproj.metaproj" (default targets) -- FAILED.

Done Building Project "....test.sln" (Build target(s)) -- FAILED.


Build FAILED.     --> this is what I want

0 Warning(s)
1 Error(s)

解决方案

正如艾伦回答的那样,命名目标是有效的,AfterBuild因为这是 msbuild 的已知目标。但是,这需要在导入 Microsoft.Cpp.targets 之后定义目标,这有点容易出错,并且更难定义多个目标以在构建后运行。在研究这个时,我发现在不使用目标但使用任何其他目标AfterTargets时使用确实按预期工作。Build不知道为什么,但是现在我正在使用这个解决方案:

<Target Name="RunTargetAfterBuild" AfterTargets="FinalizeBuildStatus">
  <Error Text="I am a failing target" />
</Target>
4

4 回答 4

2

您可以扩展 BuildDependsOn 属性以将您的目标作为构成成功构建的一部分:

<PropertyGroup>
  <BuildDependsOn>
      $(BuildDependsOn);
      RunTargetAfterBuild
  </BuildDependsOn>
</PropertyGroup>

更多细节可以在这里找到:http: //msdn.microsoft.com/en-us/library/ms366724.aspx

于 2014-11-06T15:04:11.417 回答
2

将您的自定义目标添加到项目的 InitialTargets 属性。

InitialTargets="RunTargetAfterBuild"

你是对的,这不会解决你的问题。但是使用 AfterBuild 目标,我能够在 .sln 上重现并让 msbuild 失败

于 2013-01-25T04:04:45.840 回答
0

我相信错误项应该只在满足条件时才会失败,而不是每次都失败(这可能是你想要的?)

例如

<Error Text="Setup Kit Failed to copy!" Condition="'@(FilesList)' == ''" /> 

如果满足条件(在这种情况下,之前的复制任务没有复制文件),那么只会引发错误,然后构建失败

于 2013-01-17T14:26:12.617 回答
0

您的解决方案的更好实施AfterBuild是使用BeforeTargets,如下所示:

<Target Name="RunTargetAfterBuild" BeforeTargets="AfterBuild">
  <Error Text="I am a failing target" />
</Target>

这支持多个这样的目标,并且不依赖于包含顺序与Microsoft.Cpp.targets.

于 2017-09-03T07:27:10.927 回答