diff --git a/MonoMod.Backports.slnx b/MonoMod.Backports.slnx
index 3841476..ca155d6 100644
--- a/MonoMod.Backports.slnx
+++ b/MonoMod.Backports.slnx
@@ -18,8 +18,10 @@
-
-
-
+
+
+
+
+
diff --git a/src/MonoMod.Backports.Shims/ApiCompat.targets b/src/MonoMod.Backports.Shims/ApiCompat.targets
index 294c2e7..5fd044d 100644
--- a/src/MonoMod.Backports.Shims/ApiCompat.targets
+++ b/src/MonoMod.Backports.Shims/ApiCompat.targets
@@ -1,210 +1,273 @@
-
-
-
-
-
-
-
-
-
- <_DummyRestoreProjectDir>$(IntermediateOutputPath)dummy/
- <_DummyRestoreProjectPath>$(_DummyRestoreProjectDir)dummy.csproj
- <_DummyRestoreProjectTemplate>
-
-
- {{TFMS}}
- false
- false
- false
- false
-
-
-
- {{PKGREF}}
-
-
-
-
- <_DummyPackageReferenceTemplate>
-
-
-
- <_ApiCompatAsmOut>$(IntermediateOutputPath)apicompat/
- <_BackportsTfmsTxt>$(IntermediateOutputPath)backports_tfms.txt
-
-
-
-
- <_PkgPath>%(_ShimmedPackages.PkgPath)
-
-
- <_PkgLibFolderPaths Remove="@(_PkgLibFolders)" />
- <_PkgLibFolderPaths Include="$([System.IO.Directory]::GetDirectories('$(_PkgPath)/lib/'))" />
- <_PkgLibFolders Remove="@(_PkgLibFolders)" />
- <_PkgLibFolders Include="@(_PkgLibFolderPaths->'$([System.IO.Path]::GetFileName('%(_PkgLibFolderPaths.Identity)'))')" />
- <_PkgCond Remove="@(_PkgCond)" />
- <_PkgCond Include="%(_PkgLibFolders.Identity)">
- $([MSBuild]::GetTargetFrameworkIdentifier('%(_PkgLibFolders.Identity)'))
- $([MSBuild]::GetTargetFrameworkVersion('%(_PkgLibFolders.Identity)'))
-
- <_PkgCond>
-
- (%24([MSBuild]::GetTargetFrameworkIdentifier('%24(TargetFramework)')) == '%(TgtFwk)'
- and %24([MSBuild]::VersionGreaterThanOrEquals(%24([MSBuild]::GetTargetFrameworkVersion('%24(TargetFramework)')),'%(TgtVer)')))
-
-
-
-
- <_PkgTfms>@(_PkgLibFolders)
- <_PkgCond>@(_PkgCond->'%(Cond)',' or ')
-
-
- <_ShimmedPackages Update="%(_ShimmedPackages.Identity)" Tfms="$(_PkgTfms)" TfmCond="$(_PkgCond)" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_BackportsTfms>@(_BackportsProps->'%(Value)')
-
-
- <_BackportsTfms1 Include="$(_BackportsTfms)" />
- <_BackportsTfms1 Include="$(_TfmsWithFiles)" />
- <_BackportsTfms Include="@(_BackportsTfms1->Distinct())" />
-
-
- <_BackportsTfms>@(_BackportsTfms)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_NativeExecutableExtension Condition="'$(_NativeExecutableExtension)' == '' and '$(OS)' == 'Windows_NT'">.exe
- <_GenApiCompatExe>%(MMGenApiCompat.RelativeDir)%(FileName)$(_NativeExecutableExtension)
-
-
-
- <_PPArguments Remove="@(_PPArguments)" />
-
- <_PPArguments Include="$(IntermediateOutputPath)apicompat/" />
-
- <_PPArguments Include="$(_BackportsTfmsTxt)" />
-
- <_PPArguments Include="$(_ShimsDir)" />
-
- <_PPArguments Include="%(_ShimmedPackages.PkgPath)" />
-
-
-
-
-
-
-
-
-
-
-
- <_GenApiCompatParsed Include="%(_GenApiCompatOutput.Identity)">
- $([System.String]::Copy('%(Identity)').Split('|')[0])
- $([System.String]::Copy('%(Identity)').Split('|')[1])
- $([System.String]::Copy('%(Identity)').Split('|')[2])
- $([System.String]::Copy('%(Identity)').Split('|')[3])
-
-
-
-
-
-
-
- <_Tfm>%(_GenApiCompatParsed.Tfm)
- <_RefPath>
- <_RefPath Condition="'$(_Tfm)' == '%(_ApiCompatRefPath.Identity)'">%(_ApiCompatRefPath.ReferencePath)
-
-
- <_GenApiCompatParsed Update="%(_GenApiCompatParsed.Identity)">
- %(LeftRefPath),$(_RefPath)
- %(RightRefPath),$(_RefPath)
-
-
-
-
-
-
-
-
-
-
-
-
- <_ApiCompatValidateAssembliesSemaphoreFile>$(IntermediateOutputPath)$(MSBuildThisFileName).apicompat.semaphore
- CollectApiCompatInputs;$(ApiCompatValidateAssembliesDependsOn);_ApiCompatFinalizeInputs;_WaitForBackportsBuild
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ <_DummyRestoreProjectDir>$(IntermediateOutputPath)dummy/
+ <_DummyRestoreProjectPath>$(_DummyRestoreProjectDir)dummy.csproj
+ <_DummyRestoreProjectTemplate>
+
+
+ {{TFMS}}
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+ {{PKGREF}}
+
+
+
+ <_DummyPackageReferenceTemplate>
+
+
+
+ <_ApiCompatAsmOut>$(IntermediateOutputPath)apicompat/
+ <_BackportsTfmsTxt2>$(IntermediateOutputPath)backports_tfms_final.txt
+
+
+
+
+
+ <_PkgPath>%(_ShimmedPackages.PkgPath)
+
+
+ <_PkgLibFolderPaths Remove="@(_PkgLibFolders)" />
+ <_PkgLibFolderPaths Include="$([System.IO.Directory]::GetDirectories('$(_PkgPath)/lib/'))" />
+ <_PkgLibFolders Remove="@(_PkgLibFolders)" />
+ <_PkgLibFolders Include="@(_PkgLibFolderPaths->'$([System.IO.Path]::GetFileName('%(_PkgLibFolderPaths.Identity)'))')" />
+ <_PkgCond Remove="@(_PkgCond)" />
+ <_PkgCond Include="%(_PkgLibFolders.Identity)">
+ $([MSBuild]::GetTargetFrameworkIdentifier('%(_PkgLibFolders.Identity)'))
+ $([MSBuild]::GetTargetFrameworkVersion('%(_PkgLibFolders.Identity)'))
+
+ <_PkgCond>
+
+ (%24([MSBuild]::GetTargetFrameworkIdentifier('%24(TargetFramework)')) == '%(TgtFwk)'
+ and %24([MSBuild]::VersionGreaterThanOrEquals(%24([MSBuild]::GetTargetFrameworkVersion('%24(TargetFramework)')),'%(TgtVer)')))
+
+
+
+
+ <_PkgTfms>@(_PkgLibFolders)
+ <_PkgCond>@(_PkgCond->'%(Cond)',' or ')
+
+
+ <_ShimmedPackages Update="%(_ShimmedPackages.Identity)" Tfms="$(_PkgTfms)" TfmCond="$(_PkgCond)" />
+
+
+
+
+
+
+
+
+
+ <_BackportsProps Remove="@(_BackportsProps)"/>
+
+
+
+
+
+
+
+
+ <_BackportsTfms>@(_BackportsProps->'%(Value)')
+
+
+ <_BackportsTfms1 Remove="@(_BackportsTfms1)" />
+ <_BackportsTfms1 Include="$(_BackportsTfms)" />
+ <_BackportsTfms1 Include="$(_TfmsWithFiles)" />
+ <_BackportsTfms Remove="@(_BackportsTfms)" />
+ <_BackportsTfms Include="@(_BackportsTfms1->Distinct())" />
+
+
+ <_BackportsTfms>@(_BackportsTfms)
+
+
+
+
+
+ <_NativeExecutableExtension Condition="'$(_NativeExecutableExtension)' == '' and '$(OS)' == 'Windows_NT'">.exe
+ <_FilterPkgsExe>%(MMFilterPkgs.RelativeDir)%(FileName)$(_NativeExecutableExtension)
+
+
+
+ <_PPArguments Remove="@(_PPArguments)" />
+
+ <_PPArguments Include="$(_BackportsTfmsTxt2)" />
+
+ <_PPArguments Include="@(_ShimmedPackagePaths)" />
+
+
+
+
+
+
+
+ <_PkgRefs>@(_FilterPkgsOutput->'%(Identity)','%0a')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_GenApiCompatExe>%(MMGenApiCompat.RelativeDir)%(FileName)$(_NativeExecutableExtension)
+
+
+
+ <_PPArguments Remove="@(_PPArguments)" />
+
+ <_PPArguments Include="$(IntermediateOutputPath)apicompat/" />
+
+ <_PPArguments Include="$(_BackportsTfmsTxt2)" />
+
+ <_PPArguments Include="$(_ShimsDir)" />
+
+ <_PPArguments Include="@(_ShimmedPackagePaths)" />
+
+
+
+
+
+
+
+
+
+
+
+ <_GenApiCompatParsed Include="%(_GenApiCompatOutput.Identity)">
+ $([System.String]::Copy('%(Identity)').Split('|')[0])
+ $([System.String]::Copy('%(Identity)').Split('|')[1])
+ $([System.String]::Copy('%(Identity)').Split('|')[2])
+ $([System.String]::Copy('%(Identity)').Split('|')[3])
+
+
+
+
+
+
+
+ <_ArCompareDef Remove="@(_ArCompareDef)" />
+
+
+
+
+
+ <_Tfm>%(_GenApiCompatParsed.Tfm)
+ <_Dll>%(_GenApiCompatParsed.Dll)
+ <_LeftRefPath>%(_GenApiCompatParsed.LeftRefPath)
+ <_RightRefPath>%(_GenApiCompatParsed.RightRefPath)
+ <_RefPath>
+ <_RefPath Condition="'$(_Tfm)' == '%(_ApiCompatRefPath.Identity)'">%(_ApiCompatRefPath.ReferencePath)
+
+
+
+ <_LRefPath Remove="@(_LRefPath)" />
+ <_LRefPath Include="$([System.String]::Copy('$(_LeftRefPath)').Split(','))" />
+ <_LRefPath Include="$([System.String]::Copy('$(_RefPath)').Split(','))" />
+
+ <_RRefPath Remove="@(_RRefPath)" />
+ <_RRefPath Include="$([System.String]::Copy('$(_RightRefPath)').Split(','))" />
+ <_RRefPath Include="$([System.String]::Copy('$(_RefPath)').Split(','))" />
+
+
+
+ <_ArCompareDef Include="$(_Tfm) baseline" />
+ <_ArCompareDef Include="$(_Dll)" />
+ <_ArCompareDef Include="@(_LRefPath->Count())" />
+ <_ArCompareDef Include="@(_LRefPath)"/>
+
+ <_ArCompareDef Include="$(_Tfm) shimmed" />
+ <_ArCompareDef Include="$(_Dll)" />
+ <_ArCompareDef Include="@(_RRefPath->Count())" />
+ <_ArCompareDef Include="@(_RRefPath)"/>
+
+
+
+
+ $(IntermediateOutputPath)comparisons.txt
+
+
+
+
+
+
+
+ <_ArApiCompatExe>%(MMArApiCompat.RelativeDir)%(FileName)$(_NativeExecutableExtension)
+
+
+
+ <_PPArguments Remove="@(_PPArguments)" />
+
+ <_PPArguments Include="@(ApiCompatSuppressionFile)" />
+
+ <_PPArguments Include="$(ArApiCompatComparisonDefsFile)" />
+
+ <_PPArguments Include="--write-suppressions" Condition="'$(ApiCompatGenerateSuppressionFile)' == 'true'" />
+ <_PPArguments Include="Pass '-p:ApiCompatGenerateSuppressionsFile=true' to regenerate." Condition="'$(ApiCompatGenerateSuppressionFile)' != 'true'" />
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MonoMod.Backports.Shims/CompatibilitySuppressions.xml b/src/MonoMod.Backports.Shims/CompatibilitySuppressions.xml
new file mode 100644
index 0000000..b074b51
--- /dev/null
+++ b/src/MonoMod.Backports.Shims/CompatibilitySuppressions.xml
@@ -0,0 +1,83 @@
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'new()' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+ ArApiCompat.ApiCompatibility.Comparing.Rules.CannotChangeGenericConstraintDifference
+ Cannot add constraint 'struct' on type parameter 'T' of '!!0& System.Runtime.CompilerServices.Unsafe::Unbox<T>(System.Object)'
+
+
+
\ No newline at end of file
diff --git a/src/MonoMod.Backports.Shims/Directory.Build.targets b/src/MonoMod.Backports.Shims/Directory.Build.targets
index 11e3073..73fdf13 100644
--- a/src/MonoMod.Backports.Shims/Directory.Build.targets
+++ b/src/MonoMod.Backports.Shims/Directory.Build.targets
@@ -1,192 +1,270 @@
-
-
-
-
-
-
-
-
-
-
-
- false
-
-
-
-
- <_ShimsDir>$(IntermediateOutputPath)shims/
- <_OutputTfmsTxt>$(IntermediateOutputPath)tfms.txt
-
-
-
-
-
- none
- false
- true
-
-
-
-
-
-
- <_ShimmedPackages Include="@(PackageReference)" Condition="'%(Shim)' == 'true'">
- Pkg$([System.String]::Copy('%(Identity)').Replace('.','_'))
-
-
-
- <_ShimmedPackages>
- $(%(PkgProp))
-
-
-
-
-
-
-
- <_ExistingShimFiles Include="$(_ShimsDir)**/*" />
-
-
-
-
-
-
- <_NativeExecutableExtension Condition="'$(_NativeExecutableExtension)' == '' and '$(OS)' == 'Windows_NT'">.exe
- <_ShimGenExe>%(MMShimGen.RelativeDir)%(FileName)$(_NativeExecutableExtension)
- <_SnkDir>$(MMRootPath)snk/
-
-
-
- <_PPArguments Remove="@(_PPArguments)" />
- <_PPArguments Include="$(_ShimsDir)" />
- <_PPArguments Include="$(_SnkDir)" />
-
- <_PPArguments Include="%(_ShimmedPackages.PkgPath)" />
-
-
-
-
-
-
-
-
- <_ShimFiles Include="$(_ShimsDir)**/*.dll" />
-
-
-
-
- <_DebugSymbolsIntermediatePath Remove="@(_DebugSymbolsIntermediatePath)" />
- <_ShimFiles Include="$(_ShimsDir)**/*.pdb" />
-
- <_ShimFiles Include="$(_ShimsDir)*.xml" />
-
-
-
-
-
-
- <_TfmDirs Include="$([System.String]::Copy('%(_ShimGenOutput.Identity)').Replace('tfm:', ''))"
- Condition="$([System.String]::Copy('%(_ShimGenOutput.Identity)').StartsWith('tfm:'))" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_PackageMinTfms Include="$(PackageMinTfms)" />
-
-
- <_TfmsWithFiles>@(PackageFile->'%(TargetFramework)')
-
-
- <_PackageMinTfms Include="@(PackageFile->'%(TargetFramework)')" />
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_OverridePackages>@(_ShimmedPackages->'%(Identity)|%(Version)')
- <_ImportedPropOpen>]]>
- <_ImportedPropClose>]]>
- <_BuildFileContent>
-
-
- $(_ImportedPropOpen)true$(_ImportedPropClose)
-
-
-
- $(_OverridePackages)
-
-
-
-
- <_BuildTransitiveContent>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+ <_PkgName>%(ExtraShimPackageVersion.Identity)
+ <_VerList>%(ExtraShimPackageVersion.Version)
+
+
+ <_VerList Remove="@(_VerList)" />
+ <_VerList Include="$(_VerList)" />
+
+
+
+ @(_VerList->'[%(Identity)]',';')
+
+
+
+
+
+ <_ShimsDir>$(IntermediateOutputPath)shims/
+ <_OutputTfmsTxt>$(IntermediateOutputPath)tfms.txt
+ <_BackportsTfmsTxt>$(IntermediateOutputPath)backports_tfms.txt
+
+
+
+
+
+ none
+ false
+ true
+
+
+
+
+
+
+ <_PkgName>%(ExtraShimPackageVersion.Identity)
+ <_VerList>%(ExtraShimPackageVersion.Version)
+ <_PkgNameLower>$([System.String]::Copy($(_PkgName)).ToLowerInvariant())
+ <_PkgBasePath>$([MSBuild]::NormalizePath('$(NuGetPackageRoot)', '$(_PkgNameLower)'))
+
+
+ <_VerList Remove="@(_VerList)" />
+ <_VerList Include="$(_VerList)" />
+
+
+ <_VerList>
+ $([MSBuild]::NormalizePath('$(_PkgBasePath)', '%(_VerList.Identity)'))
+
+ <_ShimmedPackagePaths Include="@(_VerList->'%(Path)')"/>
+
+
+
+
+
+ <_ShimmedPackages Include="@(PackageReference)" Condition="'%(Shim)' == 'true'">
+ Pkg$([System.String]::Copy('%(Identity)').Replace('.','_'))
+
+
+
+ <_ShimmedPackages>
+ $(%(PkgProp))
+
+
+
+
+ <_ShimmedPackagePaths Include="@(_ShimmedPackages->'%(PkgPath)')" />
+
+
+
+
+
+ <_BackportsProps Remove="@(_BackportsProps)"/>
+
+
+
+
+
+
+
+
+ <_BackportsTfms>@(_BackportsProps->'%(Value)')
+
+
+ <_BackportsTfms1 Remove="@(_BackportsTfms1)" />
+ <_BackportsTfms1 Include="$(_BackportsTfms)" />
+ <_BackportsTfms1 Include="$(PackageMinTfms)" />
+ <_BackportsTfms Remove="@(_BackportsTfms)" />
+ <_BackportsTfms Include="@(_BackportsTfms1->Distinct())" />
+
+
+ <_BackportsTfms>@(_BackportsTfms)
+
+
+
+
+
+
+
+
+ <_ExistingShimFiles Include="$(_ShimsDir)**/*" />
+
+
+
+
+
+
+ <_NativeExecutableExtension Condition="'$(_NativeExecutableExtension)' == '' and '$(OS)' == 'Windows_NT'">.exe
+ <_ShimGenExe>%(MMShimGen.RelativeDir)%(FileName)$(_NativeExecutableExtension)
+ <_SnkDir>$(MMRootPath)snk/
+
+
+
+ <_PPArguments Remove="@(_PPArguments)" />
+
+ <_PPArguments Include="$(_ShimsDir)" />
+
+ <_PPArguments Include="$(_SnkDir)" />
+
+ <_PPArguments Include="$(_BackportsTfmsTxt)" />
+
+ <_PPArguments Include="@(_ShimmedPackagePaths)" />
+
+
+
+
+
+
+
+
+ <_ShimFiles Include="$(_ShimsDir)**/*.dll" />
+
+
+
+
+ <_DebugSymbolsIntermediatePath Remove="@(_DebugSymbolsIntermediatePath)" />
+ <_ShimFiles Include="$(_ShimsDir)**/*.pdb" />
+
+ <_ShimFiles Include="$(_ShimsDir)*.xml" />
+
+
+
+
+
+
+ <_TfmDirs Include="$([System.String]::Copy('%(_ShimGenOutput.Identity)').Replace('tfm:', ''))"
+ Condition="$([System.String]::Copy('%(_ShimGenOutput.Identity)').StartsWith('tfm:'))" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_PackageMinTfms Include="$(PackageMinTfms)" />
+
+
+ <_TfmsWithFiles>@(PackageFile->'%(TargetFramework)')
+
+
+ <_PackageMinTfms Include="@(PackageFile->'%(TargetFramework)')" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_OverridePackages>@(_ShimmedPackages->'%(Identity)|9999.9999.9999.9999')
+ <_ImportedPropOpen>]]>
+ <_ImportedPropClose>]]>
+ <_BuildFileContent>
+
+
+ $(_ImportedPropOpen)true$(_ImportedPropClose)
+
+
+
+ $(_OverridePackages)
+
+
+
+
+ <_BuildTransitiveContent>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MonoMod.Backports.Shims/MonoMod.Backports.Shims.csproj b/src/MonoMod.Backports.Shims/MonoMod.Backports.Shims.csproj
index c52ed54..d9e8431 100644
--- a/src/MonoMod.Backports.Shims/MonoMod.Backports.Shims.csproj
+++ b/src/MonoMod.Backports.Shims/MonoMod.Backports.Shims.csproj
@@ -1,4 +1,4 @@
-
+
true
@@ -26,6 +26,11 @@
+
+
+
+
+
@@ -36,5 +41,4 @@
-
diff --git a/src/MonoMod.Backports/Directory.Build.props b/src/MonoMod.Backports/Directory.Build.props
index af38c79..801e033 100644
--- a/src/MonoMod.Backports/Directory.Build.props
+++ b/src/MonoMod.Backports/Directory.Build.props
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/MonoMod.Backports/FilterTfms.targets b/src/MonoMod.Backports/FilterTfms.targets
index 436b4b5..ce719ec 100644
--- a/src/MonoMod.Backports/FilterTfms.targets
+++ b/src/MonoMod.Backports/FilterTfms.targets
@@ -1,73 +1,73 @@
-
-
-
-
- true
-
-
-
-
-
-
-
-
- $([MSBuild]::NormalizePath('$(NuGetPackageRoot)', 'system.collections.immutable', '6.0.0'))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_MSBPropsFile>$(IntermediateOutputPath)Backports.TfmFilter.props
-
-
-
-
-
-
-
- <_CompileUnfiltered Include="@(Compile)" />
- <_CompileUnfiltered Include="@($(CompileRemovedItem))" Condition="'$(CompileRemovedItem)' != ''" />
-
-
-
-
-
-
-
-
-
-
-
-
- <_CompileUnfiltered Include="@(Compile)" />
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ $([MSBuild]::NormalizePath('$(NuGetPackageRoot)', 'system.collections.immutable', '6.0.0'))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_MSBPropsFile>$(IntermediateOutputPath)Backports.TfmFilter.props
+
+
+
+
+
+
+
+ <_CompileUnfiltered Include="@(Compile)" />
+ <_CompileUnfiltered Include="@($(CompileRemovedItem))" Condition="'$(CompileRemovedItem)' != ''" />
+
+
+
+
+
+
+
+
+
+
+
+
+ <_CompileUnfiltered Include="@(Compile)" />
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MonoMod.Backports/MonoMod.Backports.csproj b/src/MonoMod.Backports/MonoMod.Backports.csproj
index 7c31ee3..5450345 100644
--- a/src/MonoMod.Backports/MonoMod.Backports.csproj
+++ b/src/MonoMod.Backports/MonoMod.Backports.csproj
@@ -33,4 +33,3 @@
-
diff --git a/src/MonoMod.Backports/System/Threading/ThreadLocalEx.cs b/src/MonoMod.Backports/System/Threading/ThreadLocalEx.cs
index dee50ef..6e7f393 100644
--- a/src/MonoMod.Backports/System/Threading/ThreadLocalEx.cs
+++ b/src/MonoMod.Backports/System/Threading/ThreadLocalEx.cs
@@ -64,7 +64,7 @@ public static bool SupportsAllValues
#if HAS_ALLVALUES
=> true;
#else
- => false;
+ => ThreadLocalInfo
diff --git a/src/GenApiCompatDll/Program.cs b/src/build/GenApiCompatDll/Program.cs
similarity index 76%
rename from src/GenApiCompatDll/Program.cs
rename to src/build/GenApiCompatDll/Program.cs
index ed8eb6a..2d26808 100644
--- a/src/GenApiCompatDll/Program.cs
+++ b/src/build/GenApiCompatDll/Program.cs
@@ -5,6 +5,7 @@
using AsmResolver.IO;
using AsmResolver.PE.DotNet.Metadata.Tables;
using NuGet.Frameworks;
+using NuGet.Versioning;
using System.Collections.Immutable;
if (args is not [
@@ -42,12 +43,60 @@ .. var dotnetOobPackagePaths
// load packages dict
var packages = dotnetOobPackagePaths
.Select(pkgPath
- => (path: pkgPath, name: Path.GetFileName(Path.TrimEndingDirectorySeparator(Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(pkgPath))!)),
+ => (path: pkgPath,
+ name: Path.GetFileName(Path.TrimEndingDirectorySeparator(Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(pkgPath))!)),
+ version: new NuGet.Versioning.NuGetVersion((Path.GetFileName(Path.TrimEndingDirectorySeparator(pkgPath)))),
fwks: Directory.EnumerateDirectories(Path.Combine(pkgPath, "lib"))
.Select(libPath => (fwk: NuGetFramework.ParseFolder(Path.GetFileName(libPath)),
files: Directory.GetFiles(libPath, "*.dll")))
.ToDictionary(t => t.fwk, t => t.files)))
- .ToDictionary(t => t.name, t => (t.path, t.fwks));
+ .GroupBy(t => t.name)
+ .Select(g => (name: g.Key,
+ fwks: g.Select(t => (t.fwks, t.version))
+ .Aggregate(MergeFrameworks)))
+ .ToDictionary(t => t.name, t => t.fwks.fwks);
+
+(Dictionary d, NuGetVersion v) MergeFrameworks((Dictionary d, NuGetVersion v) a, (Dictionary d, NuGetVersion v) b)
+{
+ if (a.v == b.v)
+ {
+ // unify
+ var dict = new Dictionary>();
+ foreach (var (k, v) in a.d)
+ {
+ dict.Add(k, v.ToHashSet());
+ }
+ foreach (var (k, v) in b.d)
+ {
+ if (!dict.TryGetValue(k, out var l))
+ {
+ dict.Add(k, l = new());
+ }
+ foreach (var vi in v)
+ {
+ _ = l.Add(vi);
+ }
+ }
+
+ return (dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToArray()), a.v);
+ }
+
+ if (a.v > b.v)
+ {
+ // a is newer than b, add frameworks from b not present in a
+ foreach (var (k, v) in b.d)
+ {
+ _ = a.d.TryAdd(k, v);
+ }
+
+ return (a.d, a.v);
+ }
+ else
+ {
+ // b is newer (or equal) to a, reverse parameters
+ return MergeFrameworks(b, a);
+ }
+}
// load available shims
var allShimDlls = Directory.EnumerateFiles(shimsDir, "*.dll", new EnumerationOptions() { RecurseSubdirectories = true })
@@ -69,16 +118,32 @@ .. var dotnetOobPackagePaths
// load our tfm list
-var packageTfms = reducer.ReduceEquivalent(
+var packageTfmsRaw = reducer.ReduceEquivalent(
packages
- .SelectMany(t => t.Value.fwks)
+ .SelectMany(t => t.Value)
.Select(t => t.Key)
).ToArray();
-var tfms = reducer.ReduceEquivalent(
+
+var packageTfmsDirect =
+ packageTfmsRaw
+ .Where(f => f is not { Framework: ".NETStandard", Version.Major: < 2 }) // make sure we ignore netstandard1.x
+ .Where(f => DotNetRuntimeInfo.TryParse(f.GetDotNetFrameworkName(DefaultFrameworkNameProvider.Instance), out var rti)
+ && (rti.IsNetFramework || rti.IsNetStandard || rti.IsNetCoreApp));
+
+var backportsTfms = reducer.ReduceEquivalent(
File.ReadAllLines(tfmsFilePath)
- .Select(NuGetFramework.ParseFolder)
- .Concat(packageTfms)
- )
+ .Select(NuGetFramework.ParseFolder)
+ ).ToArray();
+var packageTfmsIndirect = backportsTfms
+ .Where(tfm
+ => packages.Any(kvp => reducer.GetNearest(tfm, kvp.Value.Keys) is not null));
+
+var packageTfms = reducer.ReduceEquivalent(
+ packageTfmsDirect.Concat(packageTfmsIndirect)
+ ).ToArray();
+
+var tfms = reducer
+ .ReduceEquivalent(backportsTfms.Concat(packageTfmsDirect))
.Order(precSorter)
.ToArray();
@@ -89,7 +154,7 @@ .. var dotnetOobPackagePaths
var exports = new Dictionary();
var assemblyRefsByName = new Dictionary();
var didReportError = false;
-foreach (var (pkgName, (_, fwks)) in packages)
+foreach (var (pkgName, fwks) in packages)
{
foreach (var file in fwks.SelectMany(kvp => kvp.Value))
{
@@ -233,7 +298,7 @@ void ExportType(TypeExport export, IImplementation impl, bool nested)
IImplementation impl;
// resolve the implementation for this export
- var pkgFwks = packages[export.FromPackage].fwks;
+ var pkgFwks = packages[export.FromPackage];
if (reducer.GetNearest(tfm, pkgFwks.Keys) is not null)
{
// valuetuple is a bit special...
@@ -289,7 +354,7 @@ void ExportType(TypeExport export, IImplementation impl, bool nested)
string GetReferencePathForTfm(NuGetFramework framework, bool useShim)
{
IEnumerable dlls = [];
- foreach (var (_, (_, fwks)) in packages)
+ foreach (var (_, fwks) in packages)
{
var best = reducer.GetNearest(framework, fwks.Keys);
if (best is null) continue; // no match, shouldn't be included
@@ -298,7 +363,8 @@ string GetReferencePathForTfm(NuGetFramework framework, bool useShim)
// if we want to use shims instead, remap all of the files to use the shims
if (useShim)
{
- var shimFilesDict = shimsByTfm[reducer.GetNearest(best, shimsByTfm.Keys)!];
+ var shimTfm = reducer.GetNearest(framework, shimsByTfm.Keys);
+ var shimFilesDict = shimsByTfm[shimTfm!];
pkgFiles = pkgFiles
.Select(f => Path.GetFileName(f))
.Select(n => shimFilesDict.TryGetValue(n, out var v) ? v : null)
diff --git a/src/MonoMod.Backports.Tasks/FilterTfmsTask.cs b/src/build/MonoMod.Backports.Tasks/FilterTfmsTask.cs
similarity index 100%
rename from src/MonoMod.Backports.Tasks/FilterTfmsTask.cs
rename to src/build/MonoMod.Backports.Tasks/FilterTfmsTask.cs
diff --git a/src/MonoMod.Backports.Tasks/MonoMod.Backports.Tasks.csproj b/src/build/MonoMod.Backports.Tasks/MonoMod.Backports.Tasks.csproj
similarity index 100%
rename from src/MonoMod.Backports.Tasks/MonoMod.Backports.Tasks.csproj
rename to src/build/MonoMod.Backports.Tasks/MonoMod.Backports.Tasks.csproj
diff --git a/src/ShimGen/Directory.Build.props b/src/build/ShimGen/Directory.Build.props
similarity index 100%
rename from src/ShimGen/Directory.Build.props
rename to src/build/ShimGen/Directory.Build.props
diff --git a/src/ShimGen/Program.cs b/src/build/ShimGen/Program.cs
similarity index 89%
rename from src/ShimGen/Program.cs
rename to src/build/ShimGen/Program.cs
index 4aeb5f8..bf99141 100644
--- a/src/ShimGen/Program.cs
+++ b/src/build/ShimGen/Program.cs
@@ -15,11 +15,12 @@
if (args is not [
var outputRefDir,
var snkPath,
+ var tfmsFilePath,
.. var dotnetOobPackagePaths
])
{
Console.Error.WriteLine("Assemblies not provided.");
- Console.Error.WriteLine("Syntax: