Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Si va a compilar un proyecto de .NET para múltiples frameworks mediante el multitargeting del SDK de .NET, por lo general, cada compilación es una compilación completa de todos los destinos pertinentes. Sin embargo, en algunos casos, desea que un objetivo determinado solo se ejecute una vez, por ejemplo, un objetivo que incremente una versión.
Configura los destinos
La solución que se muestra aquí ejecuta el MyBeforeBuildTarget una vez y solo una vez, independientemente de si se está compilando un solo framework o varios frameworks, sin cambiar el destino en sí.
Agregue
Conditionexpresiones que usen laMultitargetpropiedad para determinar si se van a compilar varios frameworks o solo uno.<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>Agregue tres objetivos al proyecto: el tuyo, que deseas ejecutar una sola vez (
MyBeforeBuildTarget), y los otros dos, tal como se muestra aquí.<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>
Este método se basa en la forma en que el destino múltiple funciona en proyectos del SDK de .NET. Las compilaciones externas establecen TargetFrameworks, pero las internas establecen TargetFramework para cada objetivo deseado. Por lo tanto, para compilar una vez para el build interno, quite la propiedad TargetFramework. Esto invoca la compilación externa con el destino deseado en lugar de ejecutarla en cada una de las compilaciones internas.
Construir el proyecto
Desde la línea de comandos, compile sin multiestinación:
dotnet msbuild -nologo -tl:false -bl -clp:nosummary -p:Multitarget=falseExtendMaybeMultitargeted.csproj(12,5): warning : MyBeforeBuildTarget ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net8.0\ExtendMaybeMultitargeted.dllAhora intente crear con 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 puede ver en el resultado, la advertencia solo se emitió una vez, independientemente de si se usó o no multitargeting.
La solución que se muestra aquí funciona porque el destino al que desea ejecutar una vez, MyBeforeBuildTarget, está vinculado a otro destino mediante BeforeTargets, pero independientemente de si el destino múltiple es true o false, el destino al que está asociado siempre es uno que se ejecuta una vez. La compilación externa es un único objetivo, DispatchToInnerBuilds, que ejecuta la compilación interna para todos los diferentes marcos especificados en TargetFrameworks; DispatchToInnerBuilds se ejecuta solo una vez en una compilación con múltiples objetivos, pero para una compilación con un único objetivo, no se ejecuta en absoluto. En el caso de una sola compilación específica, se establece BeforeTargets como BeforeBuild como de costumbre para ejecutar el destino, pero Condition se asegura de que esté asociado solo a BeforeBuild en el caso de un solo destino.