Add a new build-tools/mono-runtimes project to build the required Mono
runtimes for Xamarin.Android app execution on Android devices.
Xamarin.Android 6.0 ("cycle 6") includes Mono runtimes compiled for
five architectures:
* armeabi (armv5)
* armeabi-v7a (armv7)
* arm64-v8a (aarch64)
* x86
* x86_64
An additional "host" architecture is also built to build the
"monodroid" profile assemblies such as mscorlib.dll.
In the interest of expediency and not requiring that *six* different
runtimes be built -- which can greatly increase build times and
storage requirements -- the initial xamarin-android open-source build
will only build the armeabi-v7a (armv7) and "host" architectures.
Additionally, the <UnzipDirectoryChildren/> task needed to be altered
to use unzip(1) on OS X instead of using
System.IO.Compression.ZipFile, because the ZipFile implementation
included with Mono 4.4 doesn't respect file attributes such as the +x,
causing all files to be extracted as 644 (rw-r--r--), resulting
in an NDK toolchain which wouldn't work. To resolve this issue,
execution on OS X and Linux now uses unzip(1).
~~ Adding new architectures ~~
To build Mono for a new architecture, edit
build-tools/mono-runtimes/mono-runtimes.projitems and add a new
@(_MonoRuntime) entry for the desired architecture.
TODO: Figure out if there's a reasonable way to "opt-in" or "opt-out"
of CPU architectures so that it isn't an "all or nothing" prospect.
This might be a suspect idea, but lets see if we can make this work.
[The Joel Test: 12 Steps to Better Code][0] outlines 12 steps
to better code. The first two steps are:
1. Do you use source control?
2. Can you make a build in one step?
github is being used for source control, so (1) is handled, but how
simple can we make (2)? How easy can we make it to build
Xamarin.Android upon a fresh checkout?
The ideal to strive for is simple:
Load Xamarin.Android.sln into your IDE and Build the project.
I *know* we're not going to be able to do this, if only because we're
going to be using git submodules, which will require a separate
`git submodule init` invocation [1].
Knowing we can't reach that level of simplicitly doesn't mean we
shouldn't *try* to reach it for all other parts of the build system.
Which brings us to the Android NDK and SDK. The Android NDK will be
required in order to build native code, such as libmonodroid.so, while
the Android SDK will be required in order to compile
Java Callable Wrappers (née Android Callable Wrappers [2]) and
eventual samples and unit tests.
There are three ways we can deal with the Android NDK and SDK:
1. Complicate the "build" process by requiring that developers go to
the Android SDK Download Page [3], download and install
"somewhere" the required bits, and then configure the
Xamarin.Android build to use these bits.
2. Complicate the "build" process by requiring that developers run
the Xamarin Unified Installer [4], let it install everything
required, then configure the Xamarin.Android build to use those
bits.
3. Painstakingly determine which files are actually required, then
automatically download and extract those files into a "well-known"
location known by the Xamarin.Android build process.
(1) and (2) can be infuriating. Let's give (3) a try. :-)
Add a Xamarin.Android.Tools.BootstrapTasks project which contains
MSBuild tasks to facilitate downloading the Android SDK and NDK files.
Add an android-toolchain project which uses
Xamarin.Android.Tools.BootstrapTasks to download a painstakingly
determined set of files and install them "somewhere".
Unfortunately [5] the "somewhere" to download and install these files
needs to be in a known absolute path, so I've arbitrary decided to
download the files into $(HOME)\android-archives and install them into
$(HOME)\android-toolchain. On windows, this is
%HOMEDRIVE%%HOMEPATH%\android-archives and
%HOMEDRIVE%%HOMEPATH%\android-toolchain.
These locations may be modified by creating a
Configuration.Override.props file; see README.md for details.
TL;DR: This setup is able to magically download the Android NDK and
SDK files and install them for later use in a reasonably overridable
location, all within MSBuild.
[0]: http://www.joelonsoftware.com/articles/fog0000000043.html
[1]: Though maybe there's some MSBuild-fu we can use to address that.
[2]: https://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/android_callable_wrappers/
[3]: http://developer.android.com/sdk/index.html
[4]: https://www.xamarin.com/download
[5]: Because I couldn't find a reliable way to use $(SolutionDir) when
only building a project, and relative paths would require an
in-tree installation location, which might not work.