Skip to content

Commit 2f06e64

Browse files
[Xamarin.Android.Build.Tasks] remove TFI == MonoAndroid checks
In preparation for .NET 5, we think the `$(TargetFrameworkMoniker)` *might* be: .NETCoreApp,Version=5.0,Profile=Xamarin.Android It might also be `Profile=Android`, we don't know for sure yet. The TFM currently is: MonoAndroid,Version=v10.0 I think we can (and should) remove any code during the build that looks at `$(TargetFrameworkIdentifier)`. The places we are currently doing this are for performance: * The `_ResolveLibraryProjectImports` or `_GenerateJavaStubs` targets do not need to run against .NET standard assemblies. We can rely on a reference to `Mono.Android.dll` instead. We are already using System.Reflection.Metadata to see if the assembly actually has this reference. So an example of the condition: Condition="'%(ResolvedUserAssemblies.TargetFrameworkIdentifier)' == 'MonoAndroid' Or '%(ResolvedUserAssemblies.HasMonoAndroidReference)' == 'True'" Can just be: Condition="'%(ResolvedUserAssemblies.HasMonoAndroidReference)' == 'True'" I also took the opportunity for two small perf improvements: * `<FilterAssemblies/>` only needs to look for obsolete attributes in assemblies that reference `Mono.Android.dll`. * `<ResolveAssemblies/>` was collection a dictionary of API levels and then iterating over it later to emit warnings. This now just emits warnings as assemblies are processed. ~~ Results ~~ Testing a build with no changes for the SmartHotel360 app: Before: 60 ms FilterAssemblies 2 calls 318 ms ResolveAssemblies 1 calls After: 49 ms FilterAssemblies 2 calls 317 ms ResolveAssemblies 1 calls I would think there is a small ~12ms performance improvement to all builds of this app.
1 parent 476921a commit 2f06e64

File tree

5 files changed

+21
-66
lines changed

5 files changed

+21
-66
lines changed

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Designer.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Copyright (C) 2016 Xamarin. All rights reserved.
5757
/>
5858
<_ResolvedUserMonoAndroidAssembliesForDesigner
5959
Include="@(ResolvedUserAssemblies)"
60-
Condition="'%(ResolvedUserAssemblies.TargetFrameworkIdentifier)' == 'MonoAndroid' Or '%(ResolvedUserAssemblies.HasMonoAndroidReference)' == 'True'"
60+
Condition="'%(ResolvedUserAssemblies.HasMonoAndroidReference)' == 'True'"
6161
/>
6262
</ItemGroup>
6363
</Target>

src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public class FilterAssemblies : AndroidTask
1919
{
2020
public override string TaskPrefix => "FLT";
2121

22-
const string TargetFrameworkIdentifier = "MonoAndroid";
2322
const string MonoAndroidReference = "Mono.Android";
2423

2524
public bool DesignTimeBuild { get; set; }
@@ -42,19 +41,9 @@ public override bool RunTask ()
4241
}
4342
using (var pe = new PEReader (File.OpenRead (assemblyItem.ItemSpec))) {
4443
var reader = pe.GetMetadataReader ();
45-
var assemblyDefinition = reader.GetAssemblyDefinition ();
46-
var targetFrameworkIdentifier = GetTargetFrameworkIdentifier (assemblyDefinition, reader);
47-
if (string.Compare (targetFrameworkIdentifier, TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) == 0) {
48-
output.Add (assemblyItem);
49-
continue;
50-
}
51-
52-
// In the rare case, [assembly: TargetFramework("MonoAndroid,Version=v9.0")] may not match
53-
Log.LogDebugMessage ($"{nameof (TargetFrameworkIdentifier)} did not match: {assemblyItem.ItemSpec}");
54-
55-
// Fallback to looking for a Mono.Android reference
44+
// By default look for a reference to Mono.Android.dll
5645
if (HasReference (reader)) {
57-
Log.LogDebugMessage ($"{MonoAndroidReference} reference found: {assemblyItem.ItemSpec}");
46+
CheckAssemblyAttributes (reader);
5847
output.Add (assemblyItem);
5948
continue;
6049
}
@@ -71,27 +60,13 @@ public override bool RunTask ()
7160
return !Log.HasLoggedErrors;
7261
}
7362

74-
string GetTargetFrameworkIdentifier (AssemblyDefinition assembly, MetadataReader reader)
63+
void CheckAssemblyAttributes (MetadataReader reader)
7564
{
76-
string targetFrameworkIdentifier = null;
65+
var assembly = reader.GetAssemblyDefinition ();
7766
foreach (var handle in assembly.GetCustomAttributes ()) {
7867
var attribute = reader.GetCustomAttribute (handle);
7968
var name = reader.GetCustomAttributeFullName (attribute);
8069
switch (name) {
81-
case "System.Runtime.Versioning.TargetFrameworkAttribute":
82-
var arguments = attribute.GetCustomAttributeArguments ();
83-
foreach (var p in arguments.FixedArguments) {
84-
// Of the form "MonoAndroid,Version=v8.1"
85-
var value = p.Value?.ToString ();
86-
if (!string.IsNullOrEmpty (value)) {
87-
int commaIndex = value.IndexOf (",", StringComparison.Ordinal);
88-
if (commaIndex != -1) {
89-
targetFrameworkIdentifier = value.Substring (0, commaIndex);
90-
break;
91-
}
92-
}
93-
}
94-
break;
9570
case "Android.IncludeAndroidResourcesFromAttribute":
9671
case "Android.NativeLibraryReferenceAttribute":
9772
case "Java.Interop.JavaLibraryReferenceAttribute":
@@ -102,7 +77,6 @@ string GetTargetFrameworkIdentifier (AssemblyDefinition assembly, MetadataReader
10277
break;
10378
}
10479
}
105-
return targetFrameworkIdentifier;
10680
}
10781

10882
bool HasReference (MetadataReader reader)

src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ void Execute (MetadataResolver resolver)
8181
lockFile = LockFileUtilities.GetLockFile (ProjectAssetFile, logger);
8282
}
8383

84+
mainApiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
85+
8486
try {
8587
foreach (var assembly in Assemblies) {
8688
// Add each user assembly and all referenced assemblies (recursive)
@@ -123,14 +125,6 @@ void Execute (MetadataResolver resolver)
123125
// Add I18N assemblies if needed
124126
AddI18nAssemblies (resolver, assemblies);
125127

126-
var mainapiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
127-
foreach (var item in api_levels.Where (x => mainapiLevel < x.Value)) {
128-
var itemOSVersion = MonoAndroidHelper.SupportedVersions.GetFrameworkVersionFromApiLevel (item.Value);
129-
LogCodedWarning ("XA0105", ProjectFile, 0,
130-
"The $(TargetFrameworkVersion) for {0} ({1}) is greater than the $(TargetFrameworkVersion) for your project ({2}). " +
131-
"You need to increase the $(TargetFrameworkVersion) for your project.", Path.GetFileName (item.Key), itemOSVersion, TargetFrameworkVersion);
132-
}
133-
134128
var resolvedAssemblies = new List<ITaskItem> (assemblies.Count);
135129
var resolvedSymbols = new List<ITaskItem> (assemblies.Count);
136130
var resolvedFrameworkAssemblies = new List<ITaskItem> (assemblies.Count);
@@ -157,7 +151,7 @@ void Execute (MetadataResolver resolver)
157151
}
158152

159153
readonly List<string> do_not_package_atts = new List<string> ();
160-
readonly Dictionary<string, int> api_levels = new Dictionary<string, int> ();
154+
int? mainApiLevel;
161155
int indent = 2;
162156

163157
string ResolveRuntimeAssemblyForReferenceAssembly (LockFile lockFile, string assemblyPath)
@@ -214,23 +208,16 @@ void AddAssemblyReferences (MetadataResolver resolver, Dictionary<string, ITaskI
214208
if (resolutionPath == null)
215209
resolutionPath = new List<string>();
216210

217-
CheckAssemblyAttributes (assembly, reader, out string targetFrameworkIdentifier);
211+
CheckAssemblyAttributes (assembly, reader);
218212

219213
LogMessage ("{0}Adding assembly reference for {1}, recursively...", new string (' ', indent), assemblyName);
220214
resolutionPath.Add (assemblyName);
221215
indent += 2;
222216

223217
// Add this assembly
224-
ITaskItem assemblyItem = null;
225-
if (topLevel) {
226-
if (assemblies.TryGetValue (assemblyName, out assemblyItem)) {
227-
if (!string.IsNullOrEmpty (targetFrameworkIdentifier) && string.IsNullOrEmpty (assemblyItem.GetMetadata ("TargetFrameworkIdentifier"))) {
228-
assemblyItem.SetMetadata ("TargetFrameworkIdentifier", targetFrameworkIdentifier);
229-
}
230-
}
231-
} else {
218+
if (!assemblies.TryGetValue (assemblyName, out ITaskItem assemblyItem) && !topLevel) {
232219
assemblies [assemblyName] =
233-
assemblyItem = CreateAssemblyTaskItem (assemblyPath, targetFrameworkIdentifier);
220+
assemblyItem = CreateAssemblyTaskItem (assemblyPath);
234221
}
235222

236223
// Recurse into each referenced assembly
@@ -272,10 +259,8 @@ void AddAssemblyReferences (MetadataResolver resolver, Dictionary<string, ITaskI
272259
resolutionPath.RemoveAt (resolutionPath.Count - 1);
273260
}
274261

275-
void CheckAssemblyAttributes (AssemblyDefinition assembly, MetadataReader reader, out string targetFrameworkIdentifier)
262+
void CheckAssemblyAttributes (AssemblyDefinition assembly, MetadataReader reader)
276263
{
277-
targetFrameworkIdentifier = null;
278-
279264
foreach (var handle in assembly.GetCustomAttributes ()) {
280265
var attribute = reader.GetCustomAttribute (handle);
281266
switch (reader.GetCustomAttributeFullName (attribute)) {
@@ -293,22 +278,24 @@ void CheckAssemblyAttributes (AssemblyDefinition assembly, MetadataReader reader
293278
var arguments = attribute.GetCustomAttributeArguments ();
294279
foreach (var p in arguments.FixedArguments) {
295280
// Of the form "MonoAndroid,Version=v8.1"
281+
// If this is a .NET 5 TFM, we won't emit these warnings
296282
var value = p.Value?.ToString ();
297283
if (!string.IsNullOrEmpty (value)) {
298284
int commaIndex = value.IndexOf (",", StringComparison.Ordinal);
299285
if (commaIndex != -1) {
300-
targetFrameworkIdentifier = value.Substring (0, commaIndex);
286+
string targetFrameworkIdentifier = value.Substring (0, commaIndex);
301287
if (targetFrameworkIdentifier == "MonoAndroid") {
302288
const string match = "Version=";
303289
var versionIndex = value.IndexOf (match, commaIndex, StringComparison.Ordinal);
304290
if (versionIndex != -1) {
305291
versionIndex += match.Length;
306292
string version = value.Substring (versionIndex, value.Length - versionIndex);
307293
var apiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (version);
308-
if (apiLevel != null) {
294+
if (apiLevel > mainApiLevel) {
309295
var assemblyName = reader.GetString (assembly.Name);
310-
LogDebugMessage ("{0}={1}", assemblyName, apiLevel);
311-
api_levels [assemblyName] = apiLevel.Value;
296+
LogCodedWarning ("XA0105", ProjectFile, 0,
297+
"The $(TargetFrameworkVersion) for {0} ({1}) is greater than the $(TargetFrameworkVersion) for your project ({2}). " +
298+
"You need to increase the $(TargetFrameworkVersion) for your project.", assemblyName, version, TargetFrameworkVersion);
312299
}
313300
}
314301
}
@@ -368,14 +355,12 @@ void ResolveI18nAssembly (MetadataResolver resolver, string name, Dictionary<str
368355
assemblies [name] = CreateAssemblyTaskItem (assembly);
369356
}
370357

371-
static ITaskItem CreateAssemblyTaskItem (string assembly, string targetFrameworkIdentifier = null)
358+
static ITaskItem CreateAssemblyTaskItem (string assembly)
372359
{
373360
var assemblyFullPath = Path.GetFullPath (assembly);
374-
var dictionary = new Dictionary<string, string> (2) {
361+
var dictionary = new Dictionary<string, string> (1) {
375362
{ "ReferenceAssembly", assemblyFullPath },
376363
};
377-
if (!string.IsNullOrEmpty (targetFrameworkIdentifier))
378-
dictionary.Add ("TargetFrameworkIdentifier", targetFrameworkIdentifier);
379364
return new TaskItem (assemblyFullPath, dictionary);
380365
}
381366
}

src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,6 @@ public static string GetNativeLibraryAbi (ITaskItem lib)
290290

291291
public static bool IsMonoAndroidAssembly (ITaskItem assembly)
292292
{
293-
var tfi = assembly.GetMetadata ("TargetFrameworkIdentifier");
294-
if (string.Compare (tfi, "MonoAndroid", StringComparison.OrdinalIgnoreCase) == 0)
295-
return true;
296-
297293
var hasReference = assembly.GetMetadata ("HasMonoAndroidReference");
298294
return bool.TryParse (hasReference, out bool value) && value;
299295
}

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,7 @@ because xbuild doesn't support framework reference assemblies.
20322032
<ItemGroup>
20332033
<_ResolvedUserMonoAndroidAssemblies
20342034
Include="@(_ResolvedUserAssemblies)"
2035-
Condition=" '%(_ResolvedUserAssemblies.TargetFrameworkIdentifier)' == 'MonoAndroid' Or '%(_ResolvedUserAssemblies.HasMonoAndroidReference)' == 'True' "
2035+
Condition=" '%(_ResolvedUserAssemblies.HasMonoAndroidReference)' == 'True' "
20362036
/>
20372037
</ItemGroup>
20382038
</Target>

0 commit comments

Comments
 (0)