Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[net6] Strip framework native libraries #5637

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ _ResolveAssemblies MSBuild target.

<UsingTask TaskName="Xamarin.Android.Tasks.ProcessAssemblies" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.ProcessNativeLibraries" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.StripNativeLibraries" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />

<PropertyGroup Condition=" '$(_ComputeFilesToPublishForRuntimeIdentifiers)' == 'true' ">
<OutputPath Condition=" '$(_OuterOutputPath)' != '' ">$(_OuterOutputPath)</OutputPath>
Expand Down Expand Up @@ -168,6 +169,26 @@ _ResolveAssemblies MSBuild target.
IncludeDebugSymbols="$(AndroidIncludeDebugSymbols)">
<Output TaskParameter="OutputLibraries" ItemName="FrameworkNativeLibrary" />
</ProcessNativeLibraries>
<ItemGroup>
<_StrippedFrameworkNativeLibrary Include="@(FrameworkNativeLibrary->'$(IntermediateOutputPath)native\%(RuntimeIdentifier)\%(Filename)%(Extension)')" />
</ItemGroup>
</Target>

<Target Name="_StripFrameworkNativeLibraries"
Condition=" '$(AndroidIncludeDebugSymbols)' != 'true' "
DependsOnTargets="_IncludeNativeSystemLibraries"
Inputs="@(FrameworkNativeLibrary)"
Outputs="@(_StrippedFrameworkNativeLibrary)">
<StripNativeLibraries
radekdoulik marked this conversation as resolved.
Show resolved Hide resolved
SourceFiles="@(FrameworkNativeLibrary)"
DestinationFiles="@(_StrippedFrameworkNativeLibrary)"
ToolPath="$(AndroidBinUtilsDirectory)"
/>
<ItemGroup Condition=" '$(AndroidIncludeDebugSymbols)' != 'true' ">
<FrameworkNativeLibrary Remove="@(FrameworkNativeLibrary)"/>
<FrameworkNativeLibrary Include="@(_StrippedFrameworkNativeLibrary)"/>
<FileWrites Include="@(_StrippedFrameworkNativeLibrary)" />
</ItemGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ projects, these properties are set in Xamarin.Android.Legacy.targets.
_CheckApkPerAbiFlag;
_LintChecks;
_IncludeNativeSystemLibraries;
_StripFrameworkNativeLibraries;
_CheckGoogleSdkRequirements;
</_PrepareBuildApkDependsOnTargets>
</PropertyGroup>
Expand Down
84 changes: 84 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/StripNativeLibraries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Android.Build.Tasks;
using Xamarin.Android.Tools;
using Microsoft.Build.Utilities;

namespace Xamarin.Android.Tasks
{
/// <summary>
/// Strips debug information from the native libraries
/// </summary>
public class StripNativeLibraries : AndroidToolTask
{
public override string TaskPrefix => "SNL";

public ITaskItem [] SourceFiles { get; set; }

public ITaskItem [] DestinationFiles { get; set; }

string triple;
ITaskItem source;
ITaskItem destination;

public override bool RunTask ()
{
if (SourceFiles.Length != DestinationFiles.Length)
throw new ArgumentException ("source and destination count mismatch");
if (SourceFiles == null || SourceFiles.Length == 0)
return true;

for (int i = 0; i < SourceFiles.Length; i++) {
source = SourceFiles [i];
destination = DestinationFiles [i];

var abi = AndroidRidAbiHelper.GetNativeLibraryAbi (source);
if (string.IsNullOrEmpty (abi)) {
var packageId = source.GetMetadata ("NuGetPackageId");
if (!string.IsNullOrEmpty (packageId)) {
Log.LogCodedWarning ("XA4301", source.ItemSpec, 0, Properties.Resources.XA4301_ABI_NuGet, source.ItemSpec, packageId);
} else {
Log.LogCodedWarning ("XA4301", source.ItemSpec, 0, Properties.Resources.XA4301_ABI, source.ItemSpec);
}
continue;
}

triple = GetNdkTripleFromAbi (abi);
Directory.CreateDirectory (Path.GetDirectoryName (destination.ItemSpec));

// This runs the tool
base.RunTask ();

// Stop early on failure
if (Log.HasLoggedErrors)
return false;
}

return !Log.HasLoggedErrors;
}

protected override string ToolName => OS.IsWindows ? $"{triple}-strip.exe" : $"{triple}-strip";

protected override string GenerateFullPathToTool () => Path.Combine (ToolPath, ToolName);

protected override string GenerateCommandLineCommands ()
{
var cmd = new CommandLineBuilder ();
cmd.AppendSwitchIfNotNull ("--strip-debug ", source.ItemSpec);
cmd.AppendSwitchIfNotNull ("-o ", destination.ItemSpec);
return cmd.ToString ();
}

string GetNdkTripleFromAbi (string abi)
{
return abi switch {
"arm64-v8a" => "aarch64-linux-android",
"armeabi-v7a" => "arm-linux-androideabi",
"x86" => "i686-linux-android",
"x86_64" => "x86_64-linux-android",
_ => throw new InvalidOperationException ($"Unknown ABI: {abi}"),
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,10 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease)
Assert.IsTrue (StringAssertEx.ContainsText (dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");

var outputPath = Path.Combine (FullProjectDirectory, proj.OutputPath);
var intermediateOutputPath = Path.Combine (FullProjectDirectory, proj.IntermediateOutputPath);
if (!runtimeIdentifiers.Contains (";")) {
outputPath = Path.Combine (outputPath, runtimeIdentifiers);
intermediateOutputPath = Path.Combine (intermediateOutputPath, runtimeIdentifiers);
}

var files = Directory.EnumerateFileSystemEntries (outputPath)
Expand All @@ -411,6 +413,15 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease)
Assert.IsNotNull (type, $"{assemblyPath} should contain {typeName}");
}

var rids = runtimeIdentifiers.Split (';');
if (isRelease) {
// Check for stripped native libraries
foreach (var rid in rids) {
FileAssert.Exists (Path.Combine (intermediateOutputPath, "native", rid, "libmono-android.release.so"));
FileAssert.Exists (Path.Combine (intermediateOutputPath, "native", rid, "libmonosgen-2.0.so"));
}
}

bool expectEmbeddedAssembies = !(CommercialBuildAvailable && !isRelease);
var apkPath = Path.Combine (outputPath, "UnnamedProject.UnnamedProject.apk");
FileAssert.Exists (apkPath);
Expand All @@ -419,7 +430,6 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease)
apk.AssertContainsEntry (apkPath, $"assemblies/{proj.ProjectName}.pdb", shouldContainEntry: !CommercialBuildAvailable && !isRelease);
apk.AssertContainsEntry (apkPath, $"assemblies/System.Linq.dll", shouldContainEntry: expectEmbeddedAssembies);
apk.AssertContainsEntry (apkPath, $"assemblies/es/{proj.ProjectName}.resources.dll", shouldContainEntry: expectEmbeddedAssembies);
var rids = runtimeIdentifiers.Split (';');
foreach (var abi in rids.Select (AndroidRidAbiHelper.RuntimeIdentifierToAbi)) {
apk.AssertContainsEntry (apkPath, $"lib/{abi}/libmonodroid.so");
apk.AssertContainsEntry (apkPath, $"lib/{abi}/libmonosgen-2.0.so");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,25 @@
"Size": 316988
},
"assemblies/UnnamedProject.dll": {
"Size": 2955
},
"assemblies/System.Collections.Concurrent.dll": {
"Size": 9341
},
"assemblies/System.Collections.dll": {
"Size": 4490
"Size": 2959
},
"assemblies/System.Console.dll": {
"Size": 6209
},
"assemblies/System.Linq.Expressions.dll": {
"Size": 115171
"Size": 6214
},
"assemblies/System.Linq.dll": {
"Size": 16987
},
"assemblies/System.ObjectModel.dll": {
"Size": 3372
"Size": 15127
},
"assemblies/System.Private.CoreLib.dll": {
"Size": 527251
"Size": 516700
},
"assemblies/Java.Interop.dll": {
"Size": 67979
"Size": 63117
},
"assemblies/Mono.Android.dll": {
"Size": 108095
"Size": 86318
},
"lib/arm64-v8a/libxamarin-app.so": {
"Size": 11904
"Size": 68560
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 776216
Expand All @@ -71,26 +59,26 @@
"Size": 100464
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
"Size": 18570656
"Size": 3831000
},
"lib/arm64-v8a/libmonodroid.so": {
"Size": 254616
"Size": 250136
},
"lib/arm64-v8a/libxa-internal-api.so": {
"Size": 66544
"Size": 65480
},
"lib/arm64-v8a/libxamarin-debug-app-helper.so": {
"Size": 191408
"Size": 31672
},
"META-INF/ANDROIDD.SF": {
"Size": 2948
"Size": 2512
},
"META-INF/ANDROIDD.RSA": {
"Size": 1213
},
"META-INF/MANIFEST.MF": {
"Size": 2821
"Size": 2385
}
},
"PackageSize": 8050955
"PackageSize": 2938815
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,37 @@
"Size": 316956
},
"assemblies/UnnamedProject.dll": {
"Size": 2861
"Size": 2862
},
"assemblies/Java.Interop.dll": {
"Size": 75724
"Size": 75153
},
"assemblies/Mono.Android.dll": {
"Size": 264062
"Size": 264429
},
"assemblies/mscorlib.dll": {
"Size": 779345
"Size": 769824
},
"assemblies/System.Core.dll": {
"Size": 149498
"Size": 28190
},
"assemblies/System.dll": {
"Size": 12986
},
"lib/arm64-v8a/libxamarin-app.so": {
"Size": 19824
"Size": 68560
},
"lib/arm64-v8a/libmonodroid.so": {
"Size": 254616
"Size": 250696
},
"lib/arm64-v8a/libxa-internal-api.so": {
"Size": 66544
"Size": 65184
},
"lib/arm64-v8a/libmono-btls-shared.so": {
"Size": 2160056
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
"Size": 6823104
"Size": 6819144
},
"lib/arm64-v8a/libmono-native.so": {
"Size": 1150064
Expand All @@ -74,5 +74,5 @@
"Size": 2098
}
},
"PackageSize": 5142228
"PackageSize": 5011156
}
Loading