How to make msbuild fail when a target fails in a VS solution?

一笑奈何 提交于 2019-12-01 17:08:19

问题


I'm using msbuild on the command line to build a VS2012 solution containing a C++ project. The project has a target that runs after the build:

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

I want msbuild to return an error when building, however somewhere in the process of building, the error gets lost and msbuild reports 'Build succeeded'. Consequently the ERRORLEVEL is still set to 0 so it's pretty hard to detect if something went wrong during automated builds. How do I make msbuild propagate this error all the way to the top level project/solution? I know this is possible since it's what happens for compiler errors and the likes.

Here are the relevant parts of the output:

> 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)

While for compiler errors the output is this:

> 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)

Solution

as Allen answered, what does work is naming the target AfterBuild since that is a known target to msbuild. However that requires the target is defined after importing Microsoft.Cpp.targets which is somewhat prone to errors, and makes it harder to define multiple targets to run after the build. While researching this I found that using AfterTargets does work as expected when not using the Build target but any other target. No idea why, but it does so now I'm using this solution instead:

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

回答1:


Add your custom target to the InitialTargets attribute of your project.

InitialTargets="RunTargetAfterBuild"

You are correct that this will not solve your issue. But using the AfterBuild Target I was able to repro and get msbuild on the .sln to fail




回答2:


You can extend the BuildDependsOn property to include your target as part of what constitutes a successful build:

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

More details can be found here: http://msdn.microsoft.com/en-us/library/ms366724.aspx




回答3:


I believe the Error item should only fail if a condition is met, not every time (which is presumably what you want?)

For instance

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

If the condition is met (in this case a previous copy task copied no files) only then will the Error be raised, which then fails the build




回答4:


A better implementation of your AfterBuild solution would be to use BeforeTargets, like this:

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

This supports multiple such targets, and doesn't depend on inclusion order vs. Microsoft.Cpp.targets.



来源:https://stackoverflow.com/questions/14376357/how-to-make-msbuild-fail-when-a-target-fails-in-a-vs-solution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!