|
184 | 184 | </ItemGroup> |
185 | 185 | </Target> |
186 | 186 |
|
| 187 | + <!-- |
| 188 | + net472 redistributes newer dotnet/runtime servicing assemblies than it compiles against, |
| 189 | + to line up with a Visual Studio servicing event. This mirrors the frozen maintenance-package |
| 190 | + mechanism above, in reverse: compile and restore stay at the referenced versions so there is |
| 191 | + no package downgrade (and so the .NET (Core) build, which shares these references, does not |
| 192 | + pull in new source-build prebuilts), while here we download the servicing build and copy those |
| 193 | + assemblies to the output in place of the compiled-against ones. The matching binding redirects |
| 194 | + live in src/MSBuild/app.config and src/MSBuild/app.amd64.config and must be kept in sync with |
| 195 | + %(_DeployedRuntimeAssembly.Version). |
| 196 | +
|
| 197 | + The dotnet/runtime 10.x wave is redistributed at $(RuntimePackageVersion_VSDeploy); the |
| 198 | + maintenance packages it binds to (System.Memory etc.) are redistributed at the matching |
| 199 | + servicing versions without changing their referenced ($(SystemMemoryVersion) etc.) versions. |
| 200 | +
|
| 201 | + This is opt-in per project ($(DeployRuntimeServicingAssemblies)) and intended only for the |
| 202 | + assemblies that Visual Studio actually loads (the MSBuild.exe output directory). Enabling it |
| 203 | + in a library project would make that project's output disagree with what every downstream |
| 204 | + project compiles against, producing spurious MSB3277 version-conflict warnings (errors under |
| 205 | + -warnAsError); the redistributed assemblies must therefore only appear in the final, |
| 206 | + non-referenced application output. |
| 207 | + --> |
| 208 | + <ItemGroup Condition="'$(TargetFramework)' == 'net472' and '$(DeployRuntimeServicingAssemblies)' == 'true'"> |
| 209 | + <!-- dotnet/runtime 10.x servicing wave, redistributed at $(RuntimePackageVersion_VSDeploy). --> |
| 210 | + <_DeployedRuntimeAssembly Include="System.Collections.Immutable;System.Configuration.ConfigurationManager;System.Diagnostics.DiagnosticSource;System.Diagnostics.EventLog;System.Formats.Asn1;System.Formats.Nrbf;System.Reflection.Metadata;System.Reflection.MetadataLoadContext;System.Resources.Extensions;System.Security.Cryptography.ProtectedData;System.Text.Encoding.CodePages;System.Text.Json;System.Threading.Channels;System.Threading.Tasks.Dataflow"> |
| 211 | + <Version>$(RuntimePackageVersion_VSDeploy)</Version> |
| 212 | + </_DeployedRuntimeAssembly> |
| 213 | + <!-- Transitive dependencies of the above (notably of System.Text.Json) that we also |
| 214 | + redistribute and that ship as part of the same wave. --> |
| 215 | + <_DeployedRuntimeAssembly Include="System.IO.Pipelines;System.Text.Encodings.Web;Microsoft.Bcl.AsyncInterfaces"> |
| 216 | + <Version>$(RuntimePackageVersion_VSDeploy)</Version> |
| 217 | + </_DeployedRuntimeAssembly> |
| 218 | + <!-- Maintenance packages the wave binds to. Their assembly versions move between servicing |
| 219 | + builds (so the app.config / app.amd64.config redirects move with them); they are |
| 220 | + redistributed here without bumping their referenced versions. --> |
| 221 | + <_DeployedRuntimeAssembly Include="System.Memory"> |
| 222 | + <Version>4.6.3</Version> |
| 223 | + </_DeployedRuntimeAssembly> |
| 224 | + <_DeployedRuntimeAssembly Include="System.Runtime.CompilerServices.Unsafe"> |
| 225 | + <Version>6.1.2</Version> |
| 226 | + </_DeployedRuntimeAssembly> |
| 227 | + <_DeployedRuntimeAssembly Include="System.Threading.Tasks.Extensions"> |
| 228 | + <Version>4.6.3</Version> |
| 229 | + </_DeployedRuntimeAssembly> |
| 230 | + <_DeployedRuntimeAssembly Include="System.Buffers"> |
| 231 | + <Version>4.6.1</Version> |
| 232 | + </_DeployedRuntimeAssembly> |
| 233 | + <_DeployedRuntimeAssembly Include="System.Numerics.Vectors"> |
| 234 | + <Version>4.6.1</Version> |
| 235 | + </_DeployedRuntimeAssembly> |
| 236 | + <!-- System.Formats.Nrbf in the 10.x wave binds to Microsoft.Bcl.HashCode 6.0.0.0 on net462, |
| 237 | + but the compile-time closure only brings in 1.0.0.0. Redistribute 6.0.0 so the shipped |
| 238 | + assembly matches the redirect (and the version Nrbf actually loads). --> |
| 239 | + <_DeployedRuntimeAssembly Include="Microsoft.Bcl.HashCode"> |
| 240 | + <Version>6.0.0</Version> |
| 241 | + </_DeployedRuntimeAssembly> |
| 242 | + </ItemGroup> |
| 243 | + |
| 244 | + <ItemGroup Condition="'$(TargetFramework)' == 'net472' and '$(DeployRuntimeServicingAssemblies)' == 'true'"> |
| 245 | + <PackageDownload Include="@(_DeployedRuntimeAssembly)" Version="[%(Version)]" /> |
| 246 | + </ItemGroup> |
| 247 | + |
| 248 | + <PropertyGroup Condition="'$(TargetFramework)' == 'net472' and '$(DeployRuntimeServicingAssemblies)' == 'true'"> |
| 249 | + <!-- RAR sees the net472 binding redirect to the deployed version but resolves the referenced |
| 250 | + version (the swap to the servicing build happens after RAR, and the compile references |
| 251 | + must stay on the packages so their .NET Framework type-forwards keep working), so it |
| 252 | + reports an unresolvable version conflict. That mismatch is intentional; |
| 253 | + ValidateMSBuildPackageDependencyVersions enforces that the shipped redirects match the |
| 254 | + assemblies actually in the output. --> |
| 255 | + <MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages> |
| 256 | + </PropertyGroup> |
| 257 | + |
| 258 | + <!-- |
| 259 | + Swap the runtime copy-local assemblies AFTER RAR, so the output directory contains the |
| 260 | + redistributed servicing build rather than the compiled-against one. We deliberately do NOT |
| 261 | + touch the compile-time references: the net462 reference assemblies type-forward into the |
| 262 | + .NET Framework (e.g. System.Configuration.ConfigurationManager forwards |
| 263 | + ConfigurationErrorsException to the GAC's System.Configuration), and substituting raw file |
| 264 | + references for the package references breaks those forwards. The build-time RAR |
| 265 | + version-conflict warning that results is suppressed (and the real guardrail is the |
| 266 | + ValidateMSBuildPackageDependencyVersions task) in the projects that opt in. |
| 267 | + --> |
| 268 | + <Target Name="ReplaceRuntimeAssembliesWithServicingVersions" |
| 269 | + AfterTargets="ResolveAssemblyReferences" |
| 270 | + Condition="'$(TargetFramework)' == 'net472' and '@(_DeployedRuntimeAssembly)' != ''"> |
| 271 | + <PropertyGroup> |
| 272 | + <!-- Semicolon-delimited (and -bracketed) so membership tests can't match on a substring. --> |
| 273 | + <_DeployedRuntimeAssemblyIds>;@(_DeployedRuntimeAssembly);</_DeployedRuntimeAssemblyIds> |
| 274 | + <!-- The package ids that are actually copy-local in this project, so we only swap the |
| 275 | + assemblies it really redistributes (some of the wave is not referenced here). --> |
| 276 | + <_RuntimeCopyLocalIds>;@(ReferenceCopyLocalPaths->'%(NuGetPackageId)');</_RuntimeCopyLocalIds> |
| 277 | + </PropertyGroup> |
| 278 | + <ItemGroup> |
| 279 | + <!-- Precompute the servicing-build path per assembly (kept out of the transform below so |
| 280 | + that transform string stays free of nested quotes / property functions). --> |
| 281 | + <_DeployedRuntimeAssembly> |
| 282 | + <DeployedPath>$(NuGetPackageRoot)$([System.String]::Copy('%(Identity)').ToLowerInvariant())\%(Version)\lib\net462\%(Identity).dll</DeployedPath> |
| 283 | + </_DeployedRuntimeAssembly> |
| 284 | + </ItemGroup> |
| 285 | + <ItemGroup> |
| 286 | + <!-- Drop the compiled-against copies of the assemblies we redistribute... --> |
| 287 | + <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" |
| 288 | + Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' != '' and $(_DeployedRuntimeAssemblyIds.Contains(';%(ReferenceCopyLocalPaths.NuGetPackageId);'))" /> |
| 289 | + |
| 290 | + <!-- ...and add the servicing build, but only for assemblies this project actually copies. --> |
| 291 | + <ReferenceCopyLocalPaths Include="@(_DeployedRuntimeAssembly->'%(DeployedPath)')" |
| 292 | + Condition="$(_RuntimeCopyLocalIds.Contains(';%(_DeployedRuntimeAssembly.Identity);'))"> |
| 293 | + <NuGetPackageId>%(_DeployedRuntimeAssembly.Identity)</NuGetPackageId> |
| 294 | + <NuGetPackageVersion>%(_DeployedRuntimeAssembly.Version)</NuGetPackageVersion> |
| 295 | + </ReferenceCopyLocalPaths> |
| 296 | + </ItemGroup> |
| 297 | + </Target> |
| 298 | + |
187 | 299 | <!-- Import parent targets --> |
188 | 300 | <Import Project="..\Directory.Build.targets"/> |
189 | 301 |
|
|
0 commit comments