Skip to content

Commit 3960ae7

Browse files
[One .NET] exclude .dll/.pdb files from @(None) or @(Content)
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.
1 parent f2cb33c commit 3960ae7

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ _ResolveAssemblies MSBuild target.
4242
DependsOnTargets="_FixupIntermediateAssembly;ResolveReferences;ComputeFilesToPublish;_AndroidAot"
4343
Returns="@(ResolvedFileToPublish)">
4444
<ItemGroup>
45+
<ResolvedFileToPublish Remove="@(_SourceItemsToCopyToPublishDirectory)" />
4546
<ResolvedFileToPublish
4647
Condition=" '%(ResolvedFileToPublish.RuntimeIdentifier)' == '' "
4748
Update="@(ResolvedFileToPublish)"

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,18 @@ public void SignAndroidPackage ()
845845
Assert.IsTrue (builder.Build ("SignAndroidPackage", parameters), $"{proj.ProjectName} should succeed");
846846
}
847847

848+
[Test]
849+
public void BenchmarkDotNet ()
850+
{
851+
var proj = new XASdkProject {
852+
PackageReferences = {
853+
new Package { Id = "BenchmarkDotNet", Version = "0.13.1" },
854+
}
855+
};
856+
var builder = CreateDotNetBuilder (proj);
857+
Assert.IsTrue (builder.Build (), $"{proj.ProjectName} should succeed");
858+
}
859+
848860
DotNetCLI CreateDotNetBuilder (string relativeProjectDir = null)
849861
{
850862
if (string.IsNullOrEmpty (relativeProjectDir)) {

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetCLI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,13 @@ List<string> GetDefaultCommandLineArgs (string verb, string target = null, strin
142142
if (string.IsNullOrEmpty (BuildLogFile))
143143
BuildLogFile = Path.Combine (testDir, "build.log");
144144

145+
var binlog = string.IsNullOrEmpty (target) ? "msbuild" : target;
145146
var arguments = new List<string> {
146147
verb,
147148
$"\"{projectOrSolution}\"",
148149
"/noconsolelogger",
149150
$"/flp1:LogFile=\"{BuildLogFile}\";Encoding=UTF-8;Verbosity={Verbosity}",
150-
$"/bl:\"{Path.Combine (testDir, $"{target}.binlog")}\""
151+
$"/bl:\"{Path.Combine (testDir, $"{binlog}.binlog")}\""
151152
};
152153
if (!string.IsNullOrEmpty (target)) {
153154
arguments.Add ($"/t:{target}");

0 commit comments

Comments
 (0)