Skip to content

Commit 2524fdb

Browse files
committed
[build] Allow building with msbuild.
DO NOT MERGE!!! TODO: Need the Java.Interop bump for the generator fix! dotnet/java-interop#46 Fix the solution and project files so that `msbuild` may be used to build the solution instead of requiring `xbuild`. There were a few issues that `msbuild` didn't like: 1. MSBuild doesn't like the "extra" configuration mappings in Xamarin.Android.sln. 2. MSBuild doesn't like the presence of `.dll` within `@(Reference)` entries. `<Reference Include="System.dll" />` is Bad™, so Don't Do That™.™. 3. Turning `$(AndroidSupportedAbis)` into an item group is...broken. (1) and (2) are straightforward fixes. (3) requires some explanation. `src/monodroid` needs to *only* build `libmonodroid.so` for the non-"host" ABIs within `$(AndroidSupportedAbis)`. It needs this restriction because non-selected ABIs may not be configured in `$(AndroidNdkDirectory)`, and thus can't be built. This *could* be done by following `build-tools/mono-runtimes/mono-runtimes.projitems` and doing lots of `Condition`s on `$(AndroidSupportedAbisForConditionalChecks)`: <_MonoRuntime Include="armeabi-v7a" Condition="$(AndroidSupportedAbisForConditionalChecks.Contains(':armeabi-v7a:'))" /> ... However, that's kinda ugly when *all* we need is the ABI name, so `monodroid.projitems` was "cute": <PropertyGroup> <_SupportedAbis>$(AndroidSupportedAbis.Replace(':', ';'))</_SupportedAbis> </PropertyGroup> <ItemGroup> <_MonoRuntime Include="$(_SupportedAbis)" Exclude="@(HostOSName)" /> </ItemGroup> <!-- @(_MonoRuntime) is `armeabi-v7a` by default --> This works...on xbuild, but *not* `msbuild`. Doh! (`msbuild` is "smart" and doesn't treat the `;` as an item separator, so if `$(AndroidSupportedAbis)` is `host-Darwin;armeabi-v7a` then MSBuild treats the `;` as part of the filename -- NOT a filename separator -- and `@(_MonoRuntime)` contains *one* item with an `%(Identity)` of `host-Darwin;armeabi-v7a`. On the one hand, this is kinda awesome and answers the question "how can you have a filename that contains `;`?", but on the other hand it broke my project!) The only fix I could think of was to use `.Split(':')`: <_MonoRuntime Include="$(AndroidSupportedAbis.Split(':'))" Exclude="@(HostOSName)" /> That provides desired behavior with `msbuild`, but `xbuild` doesn't support it and appears to either *ignore* it, or treat it literally. Other attempts to fix things so that `msbuild` behaves as desired would cause `xbuild` to break; they appear to be *mutually incompatible* here. To resolve this, add a new `<ValueToItems/>` task to `Xamarin.Android.Tools.BootstrapTasks.dll`. This new task takes a value, splits on a given separator, and turns it into an `<ItemGroup/>`, allowing particular items to be excluded: <ValueToItems Value="$(AndroidSupportedAbis)" Split=":" Exclude="@(HostOSName)"> <Output TaskParameter="Items" ItemName="_MonoRuntime" /> </ValueToItems> This allows for `@(_MonoRuntime)` to have the desired value on both `msbuild` and `xbuild`, allowing `src/monodroid` to build as desired.
1 parent 0175852 commit 2524fdb

File tree

7 files changed

+74
-16
lines changed

7 files changed

+74
-16
lines changed

Xamarin.Android.sln

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ Global
8181
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8282
Debug|AnyCPU = Debug|AnyCPU
8383
Release|AnyCPU = Release|AnyCPU
84-
XAIntegrationDebug|Any CPU = XAIntegrationDebug|Any CPU
85-
XAIntegrationRelease|Any CPU = XAIntegrationRelease|Any CPU
8684
XAIntegrationDebug|AnyCPU = XAIntegrationDebug|AnyCPU
8785
XAIntegrationRelease|AnyCPU = XAIntegrationRelease|AnyCPU
8886
EndGlobalSection

src/Mono.Android.Export/Mono.Android.Export.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@
3636
<HintPath>$(OutputPath)..\v1.0\mscorlib.dll</HintPath>
3737
<Private>False</Private>
3838
</Reference>
39-
<Reference Include="System.dll">
39+
<Reference Include="System">
4040
<HintPath>$(OutputPath)..\v1.0\System.dll</HintPath>
4141
<Private>False</Private>
4242
</Reference>
43-
<Reference Include="System.Core.dll">
43+
<Reference Include="System.Core">
4444
<HintPath>$(OutputPath)..\v1.0\System.Core.dll</HintPath>
4545
<Private>False</Private>
4646
</Reference>
47-
<Reference Include="System.Xml.dll">
47+
<Reference Include="System.Xml">
4848
<HintPath>$(OutputPath)..\v1.0\System.Xml.dll</HintPath>
4949
<Private>False</Private>
5050
</Reference>

src/Mono.Android/Mono.Android.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,23 @@
3939
<HintPath>$(OutputPath)..\v1.0\mscorlib.dll</HintPath>
4040
<Private>False</Private>
4141
</Reference>
42-
<Reference Include="System.dll">
42+
<Reference Include="System">
4343
<HintPath>$(OutputPath)..\v1.0\System.dll</HintPath>
4444
<Private>False</Private>
4545
</Reference>
46-
<Reference Include="System.Core.dll">
46+
<Reference Include="System.Core">
4747
<HintPath>$(OutputPath)..\v1.0\System.Core.dll</HintPath>
4848
<Private>False</Private>
4949
</Reference>
50-
<Reference Include="System.Net.Http.dll">
50+
<Reference Include="System.Net.Http">
5151
<HintPath>$(OutputPath)..\v1.0\System.Net.Http.dll</HintPath>
5252
<Private>False</Private>
5353
</Reference>
54-
<Reference Include="System.Runtime.Serialization.dll">
54+
<Reference Include="System.Runtime.Serialization">
5555
<HintPath>$(OutputPath)..\v1.0\System.Runtime.Serialization.dll</HintPath>
5656
<Private>False</Private>
5757
</Reference>
58-
<Reference Include="System.Xml.dll">
58+
<Reference Include="System.Xml">
5959
<HintPath>$(OutputPath)..\v1.0\System.Xml.dll</HintPath>
6060
<Private>False</Private>
6161
</Reference>

src/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\GenerateProfile.cs" />
4040
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\GetNugetPackageBasePath.cs" />
4141
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\Which.cs" />
42+
<Compile Include="Xamarin.Android.Tools.BootstrapTasks\ValueToItems.cs" />
4243
</ItemGroup>
4344
<ItemGroup>
4445
<Content Include="Xamarin.Android.Tools.BootstrapTasks.targets">
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Microsoft.Build.Framework;
5+
using Microsoft.Build.Utilities;
6+
7+
namespace Xamarin.Android.Tools.BootstrapTasks
8+
{
9+
public class ValueToItems : Task
10+
{
11+
[Required]
12+
public string Value { get; set; }
13+
14+
public string Split { get; set; }
15+
16+
public ITaskItem[] Exclude { get; set; }
17+
18+
[Output]
19+
public ITaskItem[] Items { get; set; }
20+
21+
[Output]
22+
public ITaskItem Location { get; set; }
23+
24+
public override bool Execute ()
25+
{
26+
Log.LogMessage (MessageImportance.Low, $"Task {nameof (ValueToItems)}");
27+
Log.LogMessage (MessageImportance.Low, $" {nameof (Value)}: {Value}");
28+
Log.LogMessage (MessageImportance.Low, $" {nameof (Split)}: '{Split}'");
29+
Log.LogMessage (MessageImportance.Low, $" {nameof (Exclude)}:'");
30+
foreach (var e in (Exclude ?? new ITaskItem[0])) {
31+
Log.LogMessage (MessageImportance.Low, $" {e}");
32+
}
33+
34+
var items = new List<ITaskItem> ();
35+
var excludes = Exclude?.Select (e => e.ItemSpec)?.ToList ();
36+
37+
var values = Value.Split (new [] { Split }, StringSplitOptions.RemoveEmptyEntries);
38+
foreach (var v in values) {
39+
if (excludes != null && excludes.Any (e => string.Equals (e, v, StringComparison.OrdinalIgnoreCase)))
40+
continue;
41+
items.Add (new TaskItem (v));
42+
}
43+
44+
Items = items.ToArray ();
45+
46+
Log.LogMessage (MessageImportance.Low, $" [Output] {nameof (Items)}:");
47+
foreach (var e in Items) {
48+
Log.LogMessage (MessageImportance.Low, $" {e}");
49+
}
50+
51+
return !Log.HasLoggedErrors;
52+
}
53+
}
54+
}
55+

src/monodroid/monodroid.projitems

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<PropertyGroup>
4-
<_SupportedAbis>$(AndroidSupportedAbis.Replace(':', ';'))</_SupportedAbis>
5-
</PropertyGroup>
6-
<ItemGroup>
7-
<_MonoRuntime Include="$(_SupportedAbis)" Exclude="@(HostOSName)" />
8-
</ItemGroup>
93
<ItemGroup>
104
<_RequiredProgram Include="xxd" />
115
</ItemGroup>

src/monodroid/monodroid.targets

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.ValueToItems" />
34
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.Which" />
45
<Import Project="monodroid.projitems" />
56
<PropertyGroup>
@@ -8,7 +9,16 @@
89
<ItemGroup>
910
<CFiles Include="jni\**\*.c" />
1011
</ItemGroup>
12+
<Target Name="_GetRuntimes">
13+
<ValueToItems
14+
Value="$(AndroidSupportedAbis)"
15+
Split=":"
16+
Exclude="@(HostOSName)">
17+
<Output TaskParameter="Items" ItemName="_MonoRuntime" />
18+
</ValueToItems>
19+
</Target>
1120
<Target Name="_BuildRuntimes"
21+
DependsOnTargets="_GetRuntimes"
1222
Inputs="@(CFiles);jni\Android.mk"
1323
Outputs="@(_MonoRuntime->'$(OutputPath)\%(Identity)\libmono-android.$(_Conf).so')">
1424
<Which Program="%(_RequiredProgram.Identity)" Required="True" />

0 commit comments

Comments
 (0)