2

I'm struggling with the following problem and I don't get it. I have a Visual Studio Xamarin project (VS 2019 on Windows 10). In the project file I defined a custom build target:

<Target Name="MyCustomTarget" AfterTargets="PrepareForBuild">
  <Message Importance="high" Text="=== executing MyCustomTarget" />
  <!-- do some file modifications -->
</Target>

I want it to run always after the predefined PrepareForBuild target. When I build the project, my target is executed and I see it in the build output (my custom message is shown also some files are updated as defined in the target).

The problem is that my custom target also executes (maybe even several times!), when I execute the "clean" command for the project. In this case I don't see my message in the output log (MSBuild verbosity is set to diagnostic in the options), the target is also not listed in the task performance summary, but it is executed (my files are updated). This is something I don't understand. The PrepareForBuild target is also not executed, when clean is called. Why does my target execute even when clean is called?

If I change my task to execute after BeforeBuild, then it is not called, when clean is executed, but I need it to execute earlier then after BeforeBuild.

Jimmie
  • 61
  • 1
  • 5
  • *my files are updated* is it possible something else is updating your file? It's rather unlikely that msbuild is running a target but there's no trace of it in the log. – stijn Nov 18 '21 at 16:43
  • Yes, I'm sure that nothing else is updating my files. The target contains some commands to update my files, there is nothing else that modifies these files. It's really strange and the behaviour depends on after/before which target I call my target. – Jimmie Nov 22 '21 at 09:00
  • Aha, I was testing this with another project type. What's going on here is that VS is running design-time builds, including PrepareForBuild. So for instance merely *loading* a project which has a form in it is enough to have PrepareForBuild called. Solution is going to be to either use another target to run after or detect whether it's running a design-time build. – stijn Nov 22 '21 at 10:03

1 Answers1

0

See the design time build docs: VS runs quite a lot of targets at design time and to make things more complicated it depends on which project system is being used. That answers the question about what is going on, even when just loading the project VS will run your target. The link also mentions what can be done about it:

<Target Name="MyCustomTarget" AfterTargets="PrepareForBuild" Condition="'$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true'">
  <Message Importance="high" Text="=== executing MyCustomTarget" />
</Target>

An alternative would be to look for a target which is never run at design time but that's not very easy (could go through build log manually and try some targets, or use something like Project System Tools to enable binary design time logging and compare with normal builds to see which targets get used)

However, the docs also mention:

Targets that dynamically change references, source files or compilation options must run during design-time builds to avoid unexpected behavior in Visual Studio

So depending on what you're doing exactly, it might actually be better to just leave things as-is.

stijn
  • 34,664
  • 13
  • 111
  • 163