Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Se você estiver criando um projeto .NET para várias frameworks usando multitargeting do SDK do .NET, geralmente cada build é um build completo de todos os destinos relevantes. No entanto, em alguns casos, você deseja que um determinado destino seja executado apenas uma vez, por exemplo, um destino que incremente uma versão.
Configurar os alvos
A solução mostrada aqui executa o MyBeforeBuildTarget uma vez e uma única vez, independentemente de um único framework estar sendo criado ou se vários frameworks estão sendo criados, sem uma alteração no próprio destino.
Adicione
Conditionexpressões que usam aMultitargetpropriedade para decidir se devem ser criadas várias estruturas ou apenas uma.<PropertyGroup> <TargetFrameworks Condition=" '$(Multitarget)' == 'true' ">net7.0;net8.0</TargetFrameworks> <TargetFramework Condition=" '$(Multitarget)' != 'true' ">net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage> </PropertyGroup>Adicione três destinos ao projeto: o que você deseja executar apenas uma vez (
MyBeforeBuildTarget) e os outros dois, conforme mostrado aqui.<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks Condition=" '$(Multitarget)' == 'true' ">net7.0;net8.0</TargetFrameworks> <TargetFramework Condition=" '$(Multitarget)' != 'true' ">net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage> </PropertyGroup> <Target Name="MyBeforeBuildTarget"> <Warning Text="MyBeforeBuildTarget" /> </Target> <Target Name="BuildMyBeforeBuildTargetBeforeOuterBuild" DependsOnTargets="MyBeforeBuildTarget" BeforeTargets="DispatchToInnerBuilds" /> <Target Name="BuildMyBeforeBuildTargetBeforeInnerBuild" BeforeTargets="BeforeBuild"> <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="MyBeforeBuildTarget" RemoveProperties="TargetFramework" /> </Target> </Project>
Esse método depende da maneira como o multitargeting funciona em projetos do SDK do .NET. Os builds externos definem TargetFrameworks, enquanto os builds internos definem TargetFramework para cada alvo desejado. Portanto, para compilar uma vez para o build interno, remova a TargetFramework propriedade. Isso invoca a compilação externa com o destino desejado ao invés de executá-la em cada uma das compilações internas.
Compilar o projeto
Na linha de comando, compile sem multitargeting:
dotnet msbuild -nologo -tl:false -bl -clp:nosummary -p:Multitarget=falseExtendMaybeMultitargeted.csproj(12,5): warning : MyBeforeBuildTarget ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net8.0\ExtendMaybeMultitargeted.dllAgora tente criar com multitargeting:
dotnet msbuild -nologo -tl:false -bl -clp:nosummary -p:Multitarget=trueExtendMaybeMultitargeted\ExtendMaybeMultitargeted.csproj(12,5): warning : MyBeforeBuildTarget ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net8.0\ExtendMaybeMultitargeted.dll ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net7.0\ExtendMaybeMultitargeted.dll
Como você pode ver na saída, o aviso só foi emitido uma vez, independentemente de o multitargeting ter sido usado ou não.
A solução mostrada aqui funciona porque o destino ao qual você deseja executar uma vez, MyBeforeBuildTargetestá vinculado a um destino diferente usando BeforeTargets, mas independentemente de o multitargeting ser verdadeiro ou falso, o destino ao qual ele está anexado é sempre um que é executado uma vez. O build externo é um único destino, DispatchToInnerBuilds que executa o build interno para todos os diferentes frameworks especificados em TargetFrameworks; DispatchToInnerBuilds é executado apenas uma vez para um build multissegmentado, mas para um único build direcionado, ele não é executado. Para um único build direcionado, você configura BeforeTargets para BeforeBuild como de costume para rodar seu alvo, mas Condition assegura que ele esteja anexado a BeforeBuild apenas no caso de alvo único.