Skip to content

Commit

Permalink
[One .NET] exclude .dll/.pdb files from @(None) or @(Content) (#6514)
Browse files Browse the repository at this point in the history
Context: https://github.com/jonathanpeppers/android-pipe/blob/c313259b782bff40204e1a1ca988659dc7d3180b/csharp/Benchmark.csproj#L25

When using BenchmarkDotNet in a .NET 6 Android app for the first time,
I hit this build error:

	Microsoft.Android.Sdk.AssemblyResolution.targets(106,5): error XAPRAS7009: System.InvalidOperationException: PE image does not have metadata.
	  at System.Reflection.PortableExecutable.PEReader.GetMetadataBlock()
	  at System.Reflection.PortableExecutable.PEReader.GetMetadata()
	  at System.Reflection.Metadata.PEReaderExtensions.GetMetadataReader(PEReader peReader, MetadataReaderOptions options, MetadataStringDecoder utf8Decoder)
	  at System.Reflection.Metadata.PEReaderExtensions.GetMetadataReader(PEReader peReader)
	  at Xamarin.Android.Tasks.ProcessAssemblies.DeduplicateAssemblies(List`1 output, Dictionary`2 symbols)
	  at Xamarin.Android.Tasks.ProcessAssemblies.RunTask()
	  at Microsoft.Android.Build.Tasks.AndroidTask.Execute() in C:\src\xamarin-android\external\xamarin-android-tools\src\Microsoft.Android.Build.BaseTasks\AndroidTask.cs:line 17

I could also reproduce the issue in a test.

The problem is that `Microsoft.Diagnostics.Tracing.TraceEvent.props`
includes Windows native `.dll` files:

	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\x86\KernelTraceControl.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\x86\KernelTraceControl.dll">
	  <Link>x86\KernelTraceControl.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\x86\KernelTraceControl.Win61.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\x86\KernelTraceControl.Win61.dll">
	  <Link>x86\KernelTraceControl.Win61.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\x86\msdia140.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\x86\msdia140.dll">
	  <Link>x86\msdia140.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\x86\msvcp140.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\x86\msvcp140.dll">
	  <Link>x86\msvcp140.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\x86\vcruntime140.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\x86\vcruntime140.dll">
	  <Link>x86\vcruntime140.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\amd64\KernelTraceControl.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\amd64\KernelTraceControl.dll">
	  <Link>amd64\KernelTraceControl.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\amd64\msdia140.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\amd64\msdia140.dll">
	  <Link>amd64\msdia140.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\amd64\msvcp140.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\amd64\msvcp140.dll">
	  <Link>amd64\msvcp140.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\amd64\vcruntime140.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\amd64\vcruntime140.dll">
	  <Link>amd64\vcruntime140.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>
	<None Condition="Exists('$(MSBuildThisFileDirectory)..\lib\native\amd64\vcruntime140_1.dll')" Include="$(MSBuildThisFileDirectory)..\lib\native\amd64\vcruntime140_1.dll">
	  <Link>amd64\vcruntime140_1.dll</Link>
	  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  <Visible>False</Visible>
	</None>

This isn't great; we don't really want users to be able to use
`@(None)` to include random `.dll` files…

I could workaround the problem by using this in the `.csproj`:

	<None Remove="@(None->WithMetadataValue('Extension', '.dll'))" />

Reviewing the `.binlog`, I found the only way to identify
`%(CopyToOutputDirectory)` items was to do:

	<ResolvedFileToPublish Remove="@(_SourceItemsToCopyToPublishDirectory)" />

Even though `@(_SourceItemsToCopyToPublishDirectory)` has a private
name, it seems like the only way to fix this?  If it was ever
renamed, we have a test and the above code would change to a no-op.

The test now passes, excluding these files from the build.
  • Loading branch information
jonathanpeppers committed Nov 30, 2021
1 parent 457d2d5 commit c31b45b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
Expand Up @@ -42,12 +42,19 @@ _ResolveAssemblies MSBuild target.
DependsOnTargets="_FixupIntermediateAssembly;ResolveReferences;ComputeFilesToPublish;_AndroidAot"
Returns="@(ResolvedFileToPublish)">
<ItemGroup>
<ResolvedFileToPublish Remove="@(_SourceItemsToCopyToPublishDirectory)" />
<ResolvedFileToPublish
Condition=" '%(ResolvedFileToPublish.RuntimeIdentifier)' == '' "
Update="@(ResolvedFileToPublish)"
RuntimeIdentifier="$(RuntimeIdentifier)"
/>
</ItemGroup>
<AndroidWarning
Code="XA1024"
ResourceName="XA1024"
FormatArguments="%(_SourceItemsToCopyToPublishDirectory.Identity)"
Condition=" '%(Extension)' == '.config' "
/>
</Target>

<Target Name="_FixupIntermediateAssembly" Condition=" '$(_OuterIntermediateAssembly)' != '' ">
Expand Down Expand Up @@ -95,14 +102,7 @@ _ResolveAssemblies MSBuild target.
<ItemGroup>
<_ResolvedAssemblyFiles Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.dll' " />
<_ResolvedSymbolFiles Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.pdb' " />
<_UnusedConfigFiles Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.config' " />
</ItemGroup>
<AndroidWarning
Code="XA1024"
ResourceName="XA1024"
FormatArguments="%(_UnusedConfigFiles.Identity)"
Condition=" '%(Identity)' != '' "
/>
<ProcessAssemblies
RuntimeIdentifiers="@(_RIDs)"
InputAssemblies="@(_ResolvedAssemblyFiles->Distinct())"
Expand Down
Expand Up @@ -852,6 +852,19 @@ public void SignAndroidPackage ()
Assert.IsTrue (builder.Build ("SignAndroidPackage", parameters), $"{proj.ProjectName} should succeed");
}

[Test]
public void BenchmarkDotNet ()
{
var proj = new XASdkProject {
PackageReferences = {
new Package { Id = "BenchmarkDotNet", Version = "0.13.1" },
}
};
var builder = CreateDotNetBuilder (proj);
Assert.IsTrue (builder.Build (), $"{proj.ProjectName} should succeed");
builder.AssertHasNoWarnings ();
}

DotNetCLI CreateDotNetBuilder (string relativeProjectDir = null)
{
if (string.IsNullOrEmpty (relativeProjectDir)) {
Expand Down
Expand Up @@ -142,12 +142,13 @@ List<string> GetDefaultCommandLineArgs (string verb, string target = null, strin
if (string.IsNullOrEmpty (BuildLogFile))
BuildLogFile = Path.Combine (testDir, "build.log");

var binlog = string.IsNullOrEmpty (target) ? "msbuild" : target;
var arguments = new List<string> {
verb,
$"\"{projectOrSolution}\"",
"/noconsolelogger",
$"/flp1:LogFile=\"{BuildLogFile}\";Encoding=UTF-8;Verbosity={Verbosity}",
$"/bl:\"{Path.Combine (testDir, $"{target}.binlog")}\""
$"/bl:\"{Path.Combine (testDir, $"{binlog}.binlog")}\""
};
if (!string.IsNullOrEmpty (target)) {
arguments.Add ($"/t:{target}");
Expand Down

0 comments on commit c31b45b

Please sign in to comment.