0

I'm having a multiple targeting project using a script that generates classes out of a XSD. That should only be done once - for all build targets.

I found that SO-question but this solution does not work.

My filtered csproj contains these entries:

<PropertyGroup>
  <TargetFrameworks>net472;net60-windows</TargetFrameworks>
...
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
  <Exec Command="call $(ProjectDir)..\..\..\Scripts\Python\XsdClassConverter2-Invoke.bat  ..." />
</Target>

I tried to change BeforeTargets and Name to <Target Name="OuterPreBuild" BeforeTargets="DispatchToInnerBuilds"> as suggested in linked post. But this does not work.

I'm sure that I'm missing something.

I tried to find all possible entries for BeforeTargets and found that link. But all of the possibilities does not sound like the setting that I'm looking for.

How do I've to call/setup my script to run only once?

Build environment is VS2022.

EDIT

I've a working solution:

<Target Name="GenerateXsdsCore">
  <Exec Command="call &quot;$(ProjectDir)..\..\..\Scripts\Python\XsdClassConverter2-Invoke.bat&quot; &quot;$(ProjectDir)Csv\Persistence\V1\V1_0.CsvCommon.xsd&quot; -n &quot;Toolkit.IO.Framework.Csv.Persistence.V1&quot; --field-specified-as-compare-default" />
  <Exec Command="call &quot;$(ProjectDir)..\..\..\Scripts\Python\XsdClassConverter2-Invoke.bat&quot; &quot;$(ProjectDir)Licensing\Osi\Persistence\V1\V1_0.OpenSourceLicenseInformation.xsd&quot; -n &quot;Toolkit.IO.Framework.Licensing.Osi.Persistence.V1&quot; --field-specified-as-compare-default" />
</Target>
<Target Name="GenerateXsds" BeforeTargets="DispatchToInnerBuilds;BeforeBuild">
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="GenerateXsdsCore" Properties="TargetFramework=once" />
</Target>

The interesting point is TargetFramework=once. But this solution does not look like it should be done.

Sebastian Schumann
  • 3,204
  • 19
  • 37
  • Is the project an SDK style project or a legacy style project? It appears that `DispatchToInnerBuilds` is part of SDK style projects, but not legacy style. – Jonathan Dodds May 15 '23 at 12:43
  • 1
    @JonathanDodds We're using only projects in SDK format even if they build against net472. – Sebastian Schumann May 15 '23 at 13:15
  • For current (VS2022) documentation for `BeforeTargets` see "[Target build order](https://learn.microsoft.com/en-us/visualstudio/msbuild/target-build-order?view=vs-2022)" and "[Extend the Visual Studio build process](https://learn.microsoft.com/en-us/visualstudio/msbuild/how-to-extend-the-visual-studio-build-process?view=vs-2022)". – Jonathan Dodds May 15 '23 at 14:39
  • There is not a target in the documentation for 'before all builds in a multi-target project' but the `Microsoft.Common.CrossTargeting.targets` defines the `DispatchToInnerBuilds` target which "Builds this project with /t:$(InnerTarget) /p:TargetFramework=X for each value X in $(TargetFrameworks)". – Jonathan Dodds May 15 '23 at 14:52

1 Answers1

0

You haven't explained how "this solution does not work".

If you create a target like the following, do you see the message appear in the build output? Does it appear once when there are multiple targets?

  <Target Name="TestTargetBeforeMultiFrameworkTargeting" BeforeTargets="DispatchToInnerBuilds">
    <Message Text="*** in TestTargetBeforeMultiFrameworkTargeting" Importance="high" />
  </Target>

This is testing that the technique in the answer to the "How do I call my script before all the builds for only once in a multi-targeting project" question, works as advertised.

Jonathan Dodds
  • 2,654
  • 1
  • 10
  • 14
  • I added your code to my csproj. I clicked build for that project and I don't see your message. I've another solution but that does not work. – Sebastian Schumann May 16 '23 at 06:49