I seem to have a problem where ProjectReference Include (currently on VS 2019 and VS 2017) when the target is NET 4.6.1 and use Worker or Web Roles and includes packages such as System.Runtime.CompilerServices.Unsafe. The result is a runtime failure some type could not be loaded, such as ReadOnlySpan if a dependent library/Nuget package or code uses it either directly or functions such as AsSpan.

Going into Nuget packages and replacing ref packages with lib ones fixes the issue. I tried quickly a targets fix as proposed at https://github.com/xamarin/xamarin-android/issues/1162#issuecomment-359475008, but it doesn't work. MSBuild reports

The target "_ResolveAssemblies" listed in an AfterTargets attribute at "\ReplaceRefAssemblies.targets (2,39)" does not exist in the project, and will be ignored.

Which seems to indicate to me the specific AfterTargets of _ResolveAssemblies doesn't exist. Trying to look through MSBuild Structured Log Viewer I'm unable to find suitable alternative either. So hence the question, where could I force reference assemblies to their actual lib counterparts? Or alternatively, is there another way to solve the issue (in general way?

There's an open GH issue about this at https://github.com/Microsoft/msbuild/issues/2776#issuecomment-487363546 where I've also written down the observations.

<Project>
  <Target Name="ReplaceRefAssemblies" AfterTargets="_ResolveAssemblies">
    <ItemGroup>
      <ResolvedAssembliesFixedWindows Include="@(ResolvedAssemblies->Replace('\ref\','\lib\'))" />
      <ResolvedAssembliesFixedUnix Include="@(ResolvedAssemblies->Replace('/ref/','/lib/'))" />
      <ResolvedAssembliesFixed Include="@(ResolvedAssembliesFixedWindows)" Condition="@(ResolvedAssembliesFixedWindows) != @(ResolvedAssemblies)" />
      <ResolvedAssembliesFixed Include="@(ResolvedAssembliesFixedUnix)" Condition="@(ResolvedAssembliesFixedUnix) != @(ResolvedAssemblies)" />
      <ResolvedAssemblies Condition="'@(ResolvedAssembliesFixed->Count())' &gt; 0" Remove="@(ResolvedAssemblies)" />
      <ResolvedAssemblies Include="@(ResolvedAssembliesFixed)" />
    </ItemGroup>
  </Target>
</Project>

<edit The resource MSBuild Wiki ResolveAssemblyReference looks like being a good reference in solving this.

<edit 2: Two versions later:

<Project>
  <Target Name="ReplaceRefAssemblies" AfterTargets="ResolveAssemblyReferences">
    <ItemGroup>
      <ResolvedAssembliesFixedWindows Include="@(ReferencePath->Replace('\ref\','\lib\'))" />
      <ResolvedAssembliesFixedUnix Include="@(ReferencePath->Replace('/ref/','/lib/'))" />
      <ResolvedAssembliesFixed Include="@(ResolvedAssembliesFixedWindows)" Condition="@(ResolvedAssembliesFixedWindows) != @(ReferencePath)" />
      <ResolvedAssembliesFixed Include="@(ResolvedAssembliesFixedUnix)" Condition="@(ResolvedAssembliesFixedUnix) != @(ReferencePath)" />
      <ResolvedAssemblies Condition="'@(ResolvedAssembliesFixed->Count())' &gt; 0" Remove="@(ReferencePath)" />   
      <ReferencePath Include="@(ResolvedAssembliesFixed)" />
    </ItemGroup>
  </Target>
</Project>

and

<Project>
  <Target Name="ReplaceRefAssemblies" AfterTargets="ResolveAssemblyReferences">
    <ItemGroup>
      <ResolvedAssembliesFixedWindows Include="@(_ResolveAssemblyReferenceResolvedFiles->Replace('\ref\','\lib\'))" />
      <ResolvedAssembliesFixedUnix Include="@(_ResolveAssemblyReferenceResolvedFiles->Replace('/ref/','/lib/'))" />
      <ResolvedAssembliesFixed Include="@(ResolvedAssembliesFixedWindows)" Condition="@(ResolvedAssembliesFixedWindows) != @(_ResolveAssemblyReferenceResolvedFiles)" />
      <ResolvedAssembliesFixed Include="@(ResolvedAssembliesFixedUnix)" Condition="@(ResolvedAssembliesFixedUnix) != @(_ResolveAssemblyReferenceResolvedFiles)" />
      <ResolvedAssemblies Condition="'@(ResolvedAssembliesFixed->Count())' &gt; 0" Remove="@(_ResolveAssemblyReferenceResolvedFiles)" />      
      <_ResolveAssemblyReferenceResolvedFiles Include="@(ResolvedAssembliesFixed)" />
    </ItemGroup>
  </Target>
</Project> 

Of these the first one gives

CSC error CS0006: Metadata file 'C:\Program Files\dotnet\sdk\NuGetFallbackFolder\system.text.encoding.codepages\4.3.0\lib\netstandard1.3\System.Text.Encoding.CodePages.dll' could not be found [C:some.csproj]

apparently because the ref folder in this particular case isn't "symmetrical" with the lib one, hence plain path substitution doesn't work. So there ought be another way, perhaps listing the changed paths one-by-one or have an exclusion list if it doesn't matter (e.g. the program functions properly).

0 Answers