Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Se você estiver criando um projeto .NET para várias estruturas usando a multisegmentação do SDK do .NET, geralmente cada compilação é uma compilação completa 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 incrementa uma versão.
Definir os objetivos
A solução mostrada aqui é executada uma MyBeforeBuildTarget vez e apenas uma vez, independentemente de uma única estrutura estar sendo construída, ou se várias estruturas estiverem sendo construídas, sem uma alteração no próprio destino.
Adicione expressões
Conditionque utilizem a propriedadeMultitargetpara determinar se deve criar várias estruturas de software 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 alvos ao projeto, o seu que você deseja executar apenas uma vez (
MyBeforeBuildTarget), os outros dois como 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 a multisegmentação funciona em projetos .NET SDK. Os conjuntos de construção externos definem TargetFrameworks, enquanto as construções internas definem TargetFramework para cada destino desejado. Portanto, para compilar uma vez para a construção interna, remova a propriedade TargetFramework. Isso invoca a compilação externa com o destino desejado em vez de executá-la em cada uma das compilações internas.
Compilar o projeto
A partir da linha de comando, crie 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 multitargeting ter sido usado ou não.
A solução mostrada aqui funciona porque o destino que você deseja executar uma vez, MyBeforeBuildTarget, está vinculado a um destino diferente usando BeforeTargets, mas independentemente de a multisegmentação ser verdadeira ou falsa, o destino ao qual está anexado é sempre executado uma vez. A compilação externa é um alvo único, DispatchToInnerBuilds, que executa a compilação interna para todos os diferentes frameworks especificados em TargetFrameworks; DispatchToInnerBuilds só é executada uma vez para uma compilação multi-alvo, mas para uma compilação alvo único, não é executada de todo. Para uma única compilação direcionada, define-se BeforeTargets como BeforeBuild para executar o seu alvo, mas o Condition garante que ele esteja anexado a BeforeBuild apenas no caso de uma compilação com alvo único.