Skip to content

Commit 8e54441

Browse files
[Xamarin.Android.Build.Tasks] combine CheckTargetFrameworks/ResolveAssemblies
Context: https://gist.github.com/jonathanpeppers/a207a8828317460239a12a8b0cc918d7 When reviewing how many times we are using Mono.Cecil to open every assembly, it was happening 9 times! Unfortunately it is not as easy as just "caching" something, the simplest approach for now is to start combining functionality that are in multiple tasks right now. A simple first example is the `CheckTargetFrameworks` MSBuild task, which runs after the `Compile` and `ResolveAssemblies` MSBuild tasks. `CheckTargetFrameworks` has the job of emitting warnings about `[assembly: System.Runtime.Versioning.TargetFramework]`. We can easily do this work in `ResolveAssemblies` as it is already looping over all the assemblies' custom attributes for other reasons. Changes to make this happen: - Removed `CheckTargetFrameworks` and the `_CheckTargetFrameworks` target, adding the required `TargetFrameworkVersion` and `ProjectFile` properties to `ResolveAssemblies`. - Added a new `CheckAssemblyAttributes` where we can add to a `switch` statement for new attribute types in the future as needed. - Added a dictionary of `api_levels`, and copied over the logic from `CheckTargetFrameworks` Before: 105 ms CheckTargetFrameworks 1 calls 188 ms ResolveAssemblies 1 calls After: 216 ms ResolveAssemblies 1 calls I timed the `tests/Xamarin.Forms-Performance-Integration` project in this repository: a build with no changes. Since `CheckTargetFrameworks` is removed completely, we can avoid the time it was taking to open every assembly again. This saves around 77ms.
1 parent 38bc7d0 commit 8e54441

File tree

4 files changed

+51
-94
lines changed

4 files changed

+51
-94
lines changed

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

Lines changed: 0 additions & 76 deletions
This file was deleted.

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

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ public class ResolveAssemblies : AsyncTask
2828
[Required]
2929
public string ReferenceAssembliesDirectory { get; set; }
3030

31+
[Required]
32+
public string TargetFrameworkVersion { get; set; }
33+
34+
[Required]
35+
public string ProjectFile { get; set; }
36+
3137
public string ProjectAssetFile { get; set; }
3238

3339
public string TargetMoniker { get; set; }
@@ -122,6 +128,14 @@ void Execute (DirectoryAssemblyResolver resolver)
122128
// Add I18N assemblies if needed
123129
AddI18nAssemblies (resolver, assemblies);
124130

131+
var mainapiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
132+
foreach (var item in api_levels.Where (x => mainapiLevel < x.Value)) {
133+
var itemOSVersion = MonoAndroidHelper.SupportedVersions.GetFrameworkVersionFromApiLevel (item.Value);
134+
Log.LogCodedWarning ("XA0105", ProjectFile, 0,
135+
"The $(TargetFrameworkVersion) for {0} ({1}) is greater than the $(TargetFrameworkVersion) for your project ({2}). " +
136+
"You need to increase the $(TargetFrameworkVersion) for your project.", Path.GetFileName (item.Key), itemOSVersion, TargetFrameworkVersion);
137+
}
138+
125139
var resolvedAssemblies = new List<ITaskItem> (assemblies.Count);
126140
var resolvedSymbols = new List<ITaskItem> (assemblies.Count);
127141
var resolvedFrameworkAssemblies = new List<ITaskItem> (assemblies.Count);
@@ -149,6 +163,7 @@ void Execute (DirectoryAssemblyResolver resolver)
149163
}
150164

151165
readonly List<string> do_not_package_atts = new List<string> ();
166+
readonly Dictionary<string, int> api_levels = new Dictionary<string, int> ();
152167
int indent = 2;
153168

154169
AssemblyDefinition ResolveRuntimeAssemblyForReferenceAssembly (LockFile lockFile, DirectoryAssemblyResolver resolver, string assemblyPath)
@@ -198,13 +213,8 @@ void AddAssemblyReferences (DirectoryAssemblyResolver resolver, Dictionary<strin
198213

199214
if (resolutionPath == null)
200215
resolutionPath = new List<string>();
201-
202-
foreach (var att in assembly.CustomAttributes.Where (a => a.AttributeType.FullName == "Java.Interop.DoNotPackageAttribute")) {
203-
string file = (string) att.ConstructorArguments.First ().Value;
204-
if (string.IsNullOrWhiteSpace (file))
205-
LogError ("In referenced assembly {0}, Java.Interop.DoNotPackageAttribute requires non-null file name.", assembly.FullName);
206-
do_not_package_atts.Add (Path.GetFileName (file));
207-
}
216+
217+
CheckAssemblyAttributes (assembly);
208218

209219
LogMessage ("{0}Adding assembly reference for {1}, recursively...", new string (' ', indent), assembly.Name);
210220
resolutionPath.Add (assembly.Name.Name);
@@ -245,6 +255,38 @@ void AddAssemblyReferences (DirectoryAssemblyResolver resolver, Dictionary<strin
245255
resolutionPath.RemoveAt (resolutionPath.Count - 1);
246256
}
247257

258+
void CheckAssemblyAttributes (AssemblyDefinition assembly)
259+
{
260+
foreach (var att in assembly.CustomAttributes) {
261+
switch (att.AttributeType.FullName) {
262+
case "Java.Interop.DoNotPackageAttribute": {
263+
string file = (string)att.ConstructorArguments.First ().Value;
264+
if (string.IsNullOrWhiteSpace (file))
265+
LogError ("In referenced assembly {0}, Java.Interop.DoNotPackageAttribute requires non-null file name.", assembly.FullName);
266+
do_not_package_atts.Add (Path.GetFileName (file));
267+
}
268+
break;
269+
case "System.Runtime.Versioning.TargetFrameworkAttribute": {
270+
foreach (var p in att.ConstructorArguments) {
271+
var value = p.Value.ToString ();
272+
if (value.StartsWith ("MonoAndroid")) {
273+
var values = value.Split ('=');
274+
var apiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (values [1]);
275+
if (apiLevel != null) {
276+
var assemblyName = assembly.Name.Name;
277+
Log.LogDebugMessage ("{0}={1}", assemblyName, apiLevel);
278+
api_levels [assemblyName] = apiLevel.Value;
279+
}
280+
}
281+
}
282+
}
283+
break;
284+
default:
285+
break;
286+
}
287+
}
288+
}
289+
248290
static LinkModes ParseLinkMode (string linkmode)
249291
{
250292
if (string.IsNullOrWhiteSpace (linkmode))

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,6 @@
444444
<Compile Include="Tasks\JavaCompileToolTask.cs" />
445445
<Compile Include="Tasks\AsyncTask.cs" />
446446
<Compile Include="Utilities\ResourceMerger.cs" />
447-
<Compile Include="Tasks\CheckTargetFrameworks.cs" />
448447
<Compile Include="Tasks\Dx.cs" />
449448
<Compile Include="Tasks\CreateMsymManifest.cs" />
450449
<Compile Include="Utilities\AndroidResource.cs">

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
3737
<UsingTask TaskName="Xamarin.Android.Tasks.CalculateLayoutCodeBehind" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
3838
<UsingTask TaskName="Xamarin.Android.Tasks.CalculateProjectDependencies" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
3939
<UsingTask TaskName="Xamarin.Android.Tasks.CheckForRemovedItems" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
40-
<UsingTask TaskName="Xamarin.Android.Tasks.CheckTargetFrameworks" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
4140
<UsingTask TaskName="Xamarin.Android.Tasks.CheckForInvalidResourceFileNames" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
4241
<UsingTask TaskName="Xamarin.Android.Tasks.CompileToDalvik" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
4342
<UsingTask TaskName="Xamarin.Android.Tasks.CollectPdbFiles" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
@@ -487,14 +486,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
487486
</CreateItem>
488487
</Target>
489488

490-
<Target Name="_CheckTargetFrameworks"
491-
DependsOnTargets="_ResolveAssemblies">
492-
<CheckTargetFrameworks
493-
ResolvedAssemblies="@(ResolvedAssemblies)"
494-
ProjectFile="$(MSBuildProjectFullPath)"
495-
TargetFrameworkVersion="$(TargetFrameworkVersion)" />
496-
</Target>
497-
498489
<Target Name="_StripEmbeddedLibraries"
499490
Inputs="@(ResolvedAssemblies)"
500491
Outputs="$(_AndroidStripFlag)"
@@ -1891,6 +1882,8 @@ because xbuild doesn't support framework reference assemblies.
18911882
Assemblies="@(FilteredAssemblies)"
18921883
I18nAssemblies="$(MandroidI18n)"
18931884
LinkMode="$(AndroidLinkMode)"
1885+
ProjectFile="$(MSBuildProjectFullPath)"
1886+
TargetFrameworkVersion="$(TargetFrameworkVersion)"
18941887
ProjectAssetFile="$(ProjectLockFile)"
18951888
TargetMoniker="$(NuGetTargetMoniker)"
18961889
ReferenceAssembliesDirectory="$(TargetFrameworkDirectory)">
@@ -2143,7 +2136,6 @@ because xbuild doesn't support framework reference assemblies.
21432136
<_PrepareAssembliesDependsOnTargets>
21442137
_ResolveAssemblies
21452138
;_ResolveSatellitePaths
2146-
;_CheckTargetFrameworks
21472139
;_CreatePackageWorkspace
21482140
;_StripEmbeddedLibraries
21492141
;_LinkAssemblies

0 commit comments

Comments
 (0)