Use current runtime version in ILLink.Tasks package (#90197)
authorSven Boemer <sbomer@gmail.com>
Thu, 10 Aug 2023 00:32:37 +0000 (17:32 -0700)
committerGitHub <noreply@github.com>
Thu, 10 Aug 2023 00:32:37 +0000 (17:32 -0700)
The ILLink.Tasks package should have a runtimeconfig.json that
matches the runtime version bundled with the SDK that references
it. This used to be done by stomping the runtime version in the
dotnet/sdk build, but ILLink.Tasks is no longer bundled with the
SDK so we need to do this ourselves.

Tests that use live ILLink bits need to continue working with the
SDK specified in global.json, so this preserves the existing
illink.runtimeconfig.json in the build output, but defines an
additional illink.runtimeconfig.pack.json file that uses the
current runtime version. The pack.json file is included in the
package (with the name illink.runtimeconfig.json) instead of the
original.

This includes a fix for 429a5c3a2ea096758c2b9b8907a8231d4e686a46:
we weren't actually using live illink for tests due to an
ordering issue introduced in response to feedback on that change.
The Directory.Build.props is imported too early (before the nuget
props that this is trying to override), so we need to import
Microsoft.NET.ILLink.props directly from the project file.

---------

Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>
eng/packaging.targets
eng/testing/linker/SupportFiles/Directory.Build.props
eng/testing/linker/project.csproj.template
src/tools/illink/src/ILLink.Tasks/ILLink.Tasks.csproj
src/tools/illink/src/linker/Mono.Linker.csproj

index ea2f143..a36102a 100644 (file)
   <Target Name="AddBuildOutputToToolsPackage">
     <ItemGroup>
       <!-- Include build outputs in the package under tools directory. -->
-      <TfmSpecificPackageFile Include="$(OutputPath)**"
-                              Exclude="$(OutputPath)publish\**;
-                                       $(OutputPath)"
+      <_BuildOutputPackageFile Include="$(OutputPath)**"
+                               Exclude="$(OutputPath)publish\**;
+                                        $(OutputPath)" />
+      <TfmSpecificPackageFile Include="@(_BuildOutputPackageFile)"
                               PackagePath="tools/$(TargetFramework)/%(RecursiveDir)%(FileName)%(Extension)" />
       <TfmSpecificDebugSymbolsFile Include="@(TfmSpecificPackageFile->WithMetadataValue('Extension', '.pdb'))"
                                    TargetPath="/%(TfmSpecificPackageFile.PackagePath)/%(Filename)%(Extension)"
index 546b2ee..5a54c83 100644 (file)
@@ -1,13 +1,4 @@
 <Project>
-
-  <!-- Use live illink bits. It is necessary to both import the package props and override
-       the tasks assembly, because the live package props in the build output do not use
-       the same layout as the NuGet package. -->
-  <Import Project="$(ToolsILLinkDir)$(NetCoreAppToolCurrent)/build/Microsoft.NET.ILLink.Tasks.props" />
-  <PropertyGroup>
-    <ILLinkTasksAssembly>$(ToolsILLinkDir)$(NetCoreAppToolCurrent)/ILLink.Tasks.dll</ILLinkTasksAssembly>
-  </PropertyGroup>
-
   <PropertyGroup>
     <SkipConfigureTrimming>true</SkipConfigureTrimming>
     <PublishTrimmed>true</PublishTrimmed>
index bec1429..3916d05 100644 (file)
@@ -1,4 +1,4 @@
-<Project>
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <!-- Needed for PublishTrimmed -->
@@ -6,7 +6,15 @@
     <ToolsILLinkDir>{ToolsILLinkDir}</ToolsILLinkDir>
   </PropertyGroup>
 
-  <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
+  <!-- Use live illink bits. It is necessary to both import the package props and override
+       the tasks assembly, because the live package props in the build output do not use
+       the same layout as the NuGet package. -->
+  <!-- This must be done after the usual nuget props imports, to override the implicitly referenced
+       Microsoft.NET.ILLink.Tasks.props from the SDK. -->
+  <Import Project="$(ToolsILLinkDir)$(NetCoreAppToolCurrent)/build/Microsoft.NET.ILLink.Tasks.props" />
+  <PropertyGroup>
+    <ILLinkTasksAssembly>$(ToolsILLinkDir)$(NetCoreAppToolCurrent)/ILLink.Tasks.dll</ILLinkTasksAssembly>
+  </PropertyGroup>
 
   <PropertyGroup>
     <TargetFramework>{TargetFramework}</TargetFramework>
@@ -84,6 +92,4 @@
 
   <Import Project="{NativeSanitizersTargets}" />
 
-  <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
-
 </Project>
index 9cd6c88..1199101 100644 (file)
     <EnableSingleFileAnalyzer>false</EnableSingleFileAnalyzer>
   </PropertyGroup>
 
+  <!-- Include the illink.runtimeconfig.pack.json file (which depends on the runtimeversion being built)
+       as illink.runtimeconfig.json in the package, instead of the original illink.runtimeconfig.json. -->
+  <Target Name="FixPackageRuntimeConfigPath"
+          AfterTargets="AddBuildOutputToToolsPackage"
+          Condition="'$(TargetFramework)' == '$(NetCoreAppToolCurrent)'">
+    <ItemGroup>
+      <TfmSpecificPackageFile Remove="@(TfmSpecificPackageFile)"
+                              Condition="$([System.String]::Copy('%(Identity)').EndsWith('.runtimeconfig.json'))" />
+      <TfmSpecificPackageFile
+        Condition="$([System.String]::Copy('%(TfmSpecificPackageFile.PackagePath)').EndsWith('.pack.json'))"
+        PackagePath="$([System.String]::Copy(%(TfmSpecificPackageFile.PackagePath)).Substring(0, $([MSBuild]::Subtract($([System.String]::Copy('%(TfmSpecificPackageFile.PackagePath)').Length), 10)))).json" />
+    </ItemGroup>
+  </Target>
+
   <ItemGroup>
     <!-- Note: 'build/Microsoft.NET.ILLink.targets' should not match the package name, because we don't want the targets
          to be imported by nuget. The SDK will import them in the right order. -->
index 16e5cf9..e5cdbb8 100644 (file)
     <DefineConstants>$(DefineConstants);ILLINK</DefineConstants>
   </PropertyGroup>
 
+  <Target Name="_ComputePackRuntimeConfigFilePath">
+    <PropertyGroup>
+      <PackRuntimeConfigFilePath>$([System.IO.Path]::ChangeExtension($(ProjectRuntimeConfigFilePath), pack.json))</PackRuntimeConfigFilePath>
+    </PropertyGroup>
+  </Target>
+
+  <!-- Generate a runtimeconfig.pack.json file that has the runtime version replaced by version of dotnet/runtime being built.
+       This will be the version used by the ILLink.Tasks package. -->
+  <Target Name="GeneratePackageRuntimeConfig" AfterTargets="GenerateBuildRuntimeConfigurationFiles"
+          DependsOnTargets="_ComputePackRuntimeConfigFilePath"
+          Condition="'$(TargetFramework)' == '$(NetCoreAppToolCurrent)'">
+    <PropertyGroup>
+      <_RuntimeConfigContents>$([System.IO.File]::ReadAllText('$(ProjectRuntimeConfigFilePath)'))</_RuntimeConfigContents>
+      <ReplacementPattern>"version": ".*"</ReplacementPattern>
+      <ReplacementString>"version": "$(Version)"</ReplacementString>
+      <_NewRuntimeConfigContents>$([System.Text.RegularExpressions.Regex]::Replace($(_RuntimeConfigContents), $(ReplacementPattern), $(ReplacementString)))</_NewRuntimeConfigContents>
+    </PropertyGroup>
+
+    <WriteLinesToFile File="$(PackRuntimeConfigFilePath)"
+                      Lines="$(_NewRuntimeConfigContents)"
+                      Overwrite="true"
+                      WriteOnlyWhenDifferent="true" />
+  </Target>
+
+  <!-- Ensure that the pack.json file flows to ILLink.Tasks so that it can be included in the package.
+       The original runtimeconfig.json file (included by default) is also needed so that projects which use
+       the ILLink.Tasks build output can run illink using the LKG SDK. -->
+  <Target Name="AddPackageRuntimeConfigToCopyItemsForReferencingProjects"
+          DependsOnTargets="_ComputePackRuntimeConfigFilePath"
+          AfterTargets="AddDepsJsonAndRuntimeConfigToCopyItemsForReferencingProjects">
+    <ItemGroup>
+      <AllItemsFullPathWithTargetPath Include="$(PackRuntimeConfigFilePath)"
+                                      TargetPath="$([System.IO.Path]::GetFileName($(PackRuntimeConfigFilePath)))"
+                                      CopyToOutputDirectory="PreserveNewest" />
+    </ItemGroup>
+  </Target>
+
   <!-- The default pack logic will include the implementation assembly in lib.
        This also adds the reference assembly under ref. -->
   <Target Name="_AddReferenceAssemblyToPackage" DependsOnTargets="ResolveProjectReferences">