xamarin-android/Configuration.Override.prop...

59 строки
2.4 KiB
Plaintext
Исходник Обычный вид История

[android-toolchain] Permit zero-configuration builds. 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.
2016-04-19 03:33:04 +03:00
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- The default Android API level to bind in src/Mono.Android -->
<AndroidApiLevel>23</AndroidApiLevel>
<!-- The Xamarin.Android $(TargetFrameworkVersion) value that corresponds to $(AndroidApiLevel) -->
<AndroidFrameworkVersion>v6.0</AndroidFrameworkVersion>
<!--
[build] Allow building with `msbuild`. (#74) 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, in that `@(_MonoRuntime)` would contain a *single* item with the literal value `$(AndroidSupportedAbis.Split(':'))` (argh!). Fortunately, there's a "cute" workaround: using `.Split()` within an item's `Include` attribute doesn't work, but using `.Split()` within a property group declaration *does* work: <PropertyGroup> <_SupportedAbis>$(AndroidSupportedAbis.Split(':'))</_SupportedAbis> </PropertyGroup> <ItemGroup> <_MonoRuntime Include="$(_SupportedAbis)" Exclude="@(HostOSName)" /> </ItemGroup> <!-- @(_MonoRuntime) is `armeabi-v7a` by default --> This implies that a property value isn't limited to string values, but (as here) can be string *arrays*, which is interesting. ~~~ All that aside, while exploring the proper fix for (3) (it took a remarkably long time to run across it), I decided to reconsider the property and item arrangement here. The prior approach was to have a single `$(AndroidSupportedAbis)` MSBuild property which controlled *both* Android target ABIs and host ABIs. This worked...but wasn't entirely scalable (separate moving parts need to be kept in sync). Additionally, we need to add AOT cross-compiler support, which logically would be controlled by the same/similar mechanism, so a value of "build everything" would start to look insane: msbuild /p:AndroidSupportedAbis=armeabi:armeabi-v7a:arm64-v8a:x86:x86_64:host-Darwin:host-Win64:cross-Darwin-arm:cross-Darwin-arm64:cross-Darwin-x86:cross-Darwin-x86_64:cross-Win64-arm:cross-Win64-arm64:cross-Win64-x86:cross-Win64-x86_64 And that's assuming I'm not missing anything, or that we don't add MIPS support in the future, or... Blech. Furthermore, Xamarin.Android *already* uses [`$(AndroidSupportedAbis)` in its build system][0], which means a top-level override of `$(AndroidSupportedAbis)` would also impact all projects which build `.apk` files, e.g. `src/Mono.Android/Test/Mono.Android-Tests.csproj`, which might not be desirable. In short, I think we're overloading "Android supported ABIs," and it should be split up into smaller, easier to rationalize, chunks. Thus, leave `$(AndroidSupportedAbis)` to Xamarin.Android's tasks, and replace it with *two* new properties: * `$(AndroidSupportedHostJitAbis)`: The "host" ABIs to build. * `$(AndroidSupportedTargetJitAbis)`: The "target" ABIs to build. AOT support, when added, would use a new `$(AndroidSupportedHostAotAbis)` property, thus keeping the set of acceptable values small and more easily rationalizable. Finally, "split up" these new Abis properties into corresponding Abi item groups, to allow consistent and reusable "mapping" of ABI names to filesystem locations, etc. The new `@(AndroidSupportedHostAotAbi)` and `@(AndroidSupportedTargetJitAbi)` item groups are derived from their corresponding values. (Note singular from plural in naming.) [0]: https://developer.xamarin.com/guides/android/under_the_hood/build_process/#AndroidSupportedAbis
2016-06-15 14:05:59 +03:00
Colon-separated list of ABIs to build the mono JIT for.
Supported ABIs include:
- armeabi
- armeabi-v7a
- arm64-v8a
- x86
- x86_64
Note: Why colon? Because comma `,` and semicolon `;` can't be specified on the command-line.
-->
[build] Allow building with `msbuild`. (#74) 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, in that `@(_MonoRuntime)` would contain a *single* item with the literal value `$(AndroidSupportedAbis.Split(':'))` (argh!). Fortunately, there's a "cute" workaround: using `.Split()` within an item's `Include` attribute doesn't work, but using `.Split()` within a property group declaration *does* work: <PropertyGroup> <_SupportedAbis>$(AndroidSupportedAbis.Split(':'))</_SupportedAbis> </PropertyGroup> <ItemGroup> <_MonoRuntime Include="$(_SupportedAbis)" Exclude="@(HostOSName)" /> </ItemGroup> <!-- @(_MonoRuntime) is `armeabi-v7a` by default --> This implies that a property value isn't limited to string values, but (as here) can be string *arrays*, which is interesting. ~~~ All that aside, while exploring the proper fix for (3) (it took a remarkably long time to run across it), I decided to reconsider the property and item arrangement here. The prior approach was to have a single `$(AndroidSupportedAbis)` MSBuild property which controlled *both* Android target ABIs and host ABIs. This worked...but wasn't entirely scalable (separate moving parts need to be kept in sync). Additionally, we need to add AOT cross-compiler support, which logically would be controlled by the same/similar mechanism, so a value of "build everything" would start to look insane: msbuild /p:AndroidSupportedAbis=armeabi:armeabi-v7a:arm64-v8a:x86:x86_64:host-Darwin:host-Win64:cross-Darwin-arm:cross-Darwin-arm64:cross-Darwin-x86:cross-Darwin-x86_64:cross-Win64-arm:cross-Win64-arm64:cross-Win64-x86:cross-Win64-x86_64 And that's assuming I'm not missing anything, or that we don't add MIPS support in the future, or... Blech. Furthermore, Xamarin.Android *already* uses [`$(AndroidSupportedAbis)` in its build system][0], which means a top-level override of `$(AndroidSupportedAbis)` would also impact all projects which build `.apk` files, e.g. `src/Mono.Android/Test/Mono.Android-Tests.csproj`, which might not be desirable. In short, I think we're overloading "Android supported ABIs," and it should be split up into smaller, easier to rationalize, chunks. Thus, leave `$(AndroidSupportedAbis)` to Xamarin.Android's tasks, and replace it with *two* new properties: * `$(AndroidSupportedHostJitAbis)`: The "host" ABIs to build. * `$(AndroidSupportedTargetJitAbis)`: The "target" ABIs to build. AOT support, when added, would use a new `$(AndroidSupportedHostAotAbis)` property, thus keeping the set of acceptable values small and more easily rationalizable. Finally, "split up" these new Abis properties into corresponding Abi item groups, to allow consistent and reusable "mapping" of ABI names to filesystem locations, etc. The new `@(AndroidSupportedHostAotAbi)` and `@(AndroidSupportedTargetJitAbi)` item groups are derived from their corresponding values. (Note singular from plural in naming.) [0]: https://developer.xamarin.com/guides/android/under_the_hood/build_process/#AndroidSupportedAbis
2016-06-15 14:05:59 +03:00
<AndroidSupportedTargetJitAbis>armeabi:armeabi-v7a:arm64-v8a:x86:x86_64</AndroidSupportedTargetJitAbis>
[mono-runtimes] Build AOT+LLVM cross-compilers (#125) The commit implements building of LLVM and cross-compilers to support Xamarin.Android/Mono AOT. LLVM and cross-compilers can be built for both the host platform (Linux and OS/X at the moment) as well as cross-compiled for 32-bit and 64-bit Windows platforms. Windows builds are done with MXE toolchain on OS/X and with the packaged mingw-w64 toolchain on Linux (tested on Ubuntu 16.04 ONLY). Also introducing a new set of MSBuild properties that contain information about the host system. Some of those properties (HostOS, HostCC, HostCXX for instance) have been moved from Configuration.props to better support auto-detection. A new script, build-tools/scripts/generate-os-info, is invoked as part of `make prepare` to generate file that contains the new properties. The generated file is required for the build to work and is also host-specific (it mustn't be moved between different machines) Cross compiler builds require access to a configured Mono build tree, in order to generate C structure offsets header file that is used by the AOT compilers to properly generate AOT-ed binaries. Therefore, even if a JIT target is not enabled in the configuration, enabling a cross-compiler for some target will configure Mono for that JIT target but it will NOT build it, to save time. To facilitate this, the _MonoRuntimes items defined in build-tools/mono-runtimes/mono-runtimes.projitems gain an additional metadata item called `DoBuild` which will be set to `true` if the runtime actually needs to be built, as opposed to just configured. MXE builds are disabled on Linux as mingw-w64 works just fine. A `make prepare` warning is issued for Linux hosts which have the binfmt_misc module enabled and either Wine of Mono (cli) registered as PE32/PE32+ binary interpreters. In such instance building of the Windows cross-compilers will fail because Autotools determine whether software is being cross compiled by building a test program and attempting to execute it. In normal circumstances such an attempt will fail, but with Windows cross-compilation and either Wine or Mono registered to handle the PE32 executables this attempt will succeed thus causing the cross compilation detection to fail. Currently to build cross compilers on Linux you need to generate the C structure offsets header file on OS/X and copy the resulting headers to appropriate places on Linux. The header files should be placed in build-tools/mono-runtimes/obj/Debug/cross-*/ directories. The header files are: {cross-arm,cross-arm-win}/aarch64-v8a-linux-android.h {cross-arm64,cross-arm64-win}/armv5-none-linux-androideabi.h {cross-x86,cross-x86-win}/i686-none-linux-android.h {cross-x86_64,cross-x86_64-win}/x86_64-none-linux-android.h Offsets header generation doesn't work on Linux atm because of missing support for it in the Mono utility used to generate the offsets. Hopefully this limitation will be removed in the near future and a start-to-end build of everything will be possible on Linux. It is now mandatory to run at least `make prepare-props` before Xamarin.Android can be built. The target generates the OS-specific props file which is required by the build. `make prepare` depends on the target.
2016-07-26 16:27:31 +03:00
<!--
Colon-separated list of ABIs to build AOT cross-compilers for. Note that there is no configuration
to build the armeabi-v7a cross-compiler. This is intentional as the ARMv6 cross-compiler takes care
of that target as well.
There doesn't need to be any parity between the AOT targets and the JIT ABIs above.
Supported targets are:
- armeabi
- win-armeabi
- arm64
- win-arm64
- x86
- win-x86
- x86_64
- win-x86_64
-->
<AndroidSupportedTargetAotAbis>armeabi:win-armeabi:arm64:win-arm64:x86:win-x86:x86_64:win-x86_64</AndroidSupportedTargetAotAbis>
[build] Allow building with `msbuild`. (#74) 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, in that `@(_MonoRuntime)` would contain a *single* item with the literal value `$(AndroidSupportedAbis.Split(':'))` (argh!). Fortunately, there's a "cute" workaround: using `.Split()` within an item's `Include` attribute doesn't work, but using `.Split()` within a property group declaration *does* work: <PropertyGroup> <_SupportedAbis>$(AndroidSupportedAbis.Split(':'))</_SupportedAbis> </PropertyGroup> <ItemGroup> <_MonoRuntime Include="$(_SupportedAbis)" Exclude="@(HostOSName)" /> </ItemGroup> <!-- @(_MonoRuntime) is `armeabi-v7a` by default --> This implies that a property value isn't limited to string values, but (as here) can be string *arrays*, which is interesting. ~~~ All that aside, while exploring the proper fix for (3) (it took a remarkably long time to run across it), I decided to reconsider the property and item arrangement here. The prior approach was to have a single `$(AndroidSupportedAbis)` MSBuild property which controlled *both* Android target ABIs and host ABIs. This worked...but wasn't entirely scalable (separate moving parts need to be kept in sync). Additionally, we need to add AOT cross-compiler support, which logically would be controlled by the same/similar mechanism, so a value of "build everything" would start to look insane: msbuild /p:AndroidSupportedAbis=armeabi:armeabi-v7a:arm64-v8a:x86:x86_64:host-Darwin:host-Win64:cross-Darwin-arm:cross-Darwin-arm64:cross-Darwin-x86:cross-Darwin-x86_64:cross-Win64-arm:cross-Win64-arm64:cross-Win64-x86:cross-Win64-x86_64 And that's assuming I'm not missing anything, or that we don't add MIPS support in the future, or... Blech. Furthermore, Xamarin.Android *already* uses [`$(AndroidSupportedAbis)` in its build system][0], which means a top-level override of `$(AndroidSupportedAbis)` would also impact all projects which build `.apk` files, e.g. `src/Mono.Android/Test/Mono.Android-Tests.csproj`, which might not be desirable. In short, I think we're overloading "Android supported ABIs," and it should be split up into smaller, easier to rationalize, chunks. Thus, leave `$(AndroidSupportedAbis)` to Xamarin.Android's tasks, and replace it with *two* new properties: * `$(AndroidSupportedHostJitAbis)`: The "host" ABIs to build. * `$(AndroidSupportedTargetJitAbis)`: The "target" ABIs to build. AOT support, when added, would use a new `$(AndroidSupportedHostAotAbis)` property, thus keeping the set of acceptable values small and more easily rationalizable. Finally, "split up" these new Abis properties into corresponding Abi item groups, to allow consistent and reusable "mapping" of ABI names to filesystem locations, etc. The new `@(AndroidSupportedHostAotAbi)` and `@(AndroidSupportedTargetJitAbi)` item groups are derived from their corresponding values. (Note singular from plural in naming.) [0]: https://developer.xamarin.com/guides/android/under_the_hood/build_process/#AndroidSupportedAbis
2016-06-15 14:05:59 +03:00
<!--
Colon-separated list of ABIs to build a "host" mono JIT for.
The host JIT is used for the Xamarin Studio Designer, among other things.
Supported ABIs include:
- Darwin
- Linux
- mxe-Win64
Note: Why colon? Because comma `,` and semicolon `;` can't be specified on the command-line.
-->
<AndroidSupportedHostJitAbis>Darwin:mxe-Win64</AndroidSupportedHostJitAbis>
<!-- C and C++ compilers to emit host-native binaries -->
<HostCc>clang</HostCc>
<HostCxx>clang++</HostCxx>
[android-toolchain] Permit zero-configuration builds. 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.
2016-04-19 03:33:04 +03:00
<!-- These must be FULL PATHS -->
<AndroidToolchainCacheDirectory>$(HOME)\android-archives</AndroidToolchainCacheDirectory>
<AndroidToolchainDirectory>$(HOME)\android-toolchain</AndroidToolchainDirectory>
[mxe] Add Windows cross-compiler support. (#55) Certain Xamarin.Android features require that Mono be built for Windows, e.g. the [AOT compilers][aot] require a build of mono that executes on Windows to generate the AOT native libraries. Unfortunately, building Mono on Windows continues to be a massive PITA. (Autotools on Windows requires Cygwin/mingw, running shell scripts on Windows is painfully slow, it's all brittle, etc.) To work around this pain, we instead build the Mono/Windows binaries on OS X, via [MXE][mxe], which produces a gcc-based cross-compiler which generates Windows binaries and is executable from Unix. This in turn requires that we have MXE, so add a `_CreateMxeToolchains` target to `android-toolchain.targets` which will build MXE. The installation prefix for MXE can be overridden via the new `$(AndroidMxeInstallPrefix)` MSBuild property; it defaults to `$HOME/android-toolchain/mxe`. Rework the `$(AndroidSupportedAbis)` MSBuild property so that it must include the "host" ABI, and add support for a new `host-win64` value which will use MXE to generate 64-bit Windows binaries for libmonosgen-2.0.dll and libMonoPosixHelper.dll. We can't always process `host-$(HostOS)` because of an xbuild bug. The scenario is that if you want to just build `host-win64`, the obvious thing to do is: cd build-tools/mono-runtimes xbuild /p:AndroidSupportedAbis=host-win64 Alas, if `host-$(HostOS)` is always processed, this inexplicably causes `host-$(HostOS)` to be re-rebuilt, which (1) is a waste of time, and (2) fails -- inexplicably -- in the `_BuildRuntimes` target because make(1) thinks that the configure flags have somehow changed, which currently makes no sense at all. (When can we move to MSBuild?) Changing `$(AndroidSupportedAbis)` so that `host-$(HostOS)` is explicitly processed instead of implicitly processed allows working around the above xbuild bug, as `host-$(HostOS)` won't be implicitly processed on every build, but only when required. Additionally, we add a new <Which/> MSBuild task so that we can determine if a particular program is in `$PATH`. This is useful because listing requirements within README.md is a road to pain -- e.g. xxd(1) is required to build `src/monodroid` but if it's missing it'll still *build* but you'll instead get a *linker* failure because the `monodroid_config` and `monodroid_machine_config` symbols aren't present. Building MXE requires that even more programs be present within $PATH, so explicitly check for these so that *useful* error messages can be generated instead of obscure ones. Finally, a note about autotools and generating Windows native libraries: creation of `.dll` files *requires* that an appropriate objdump be present so it can determine if e.g. `libkernel32.a` is an import library or an archive. If `x86_64-w64-mingw32.static-objdump` isn't found -- e.g. because $PATH doesn't contain it -- then no `.dll` files will be created, and much head scratching will occur. To rectify this, override the OBJDUMP and DLLTOOL values when invoking `configure` so that that full paths are used and `$PATH` use is reduced. (Who wants `x86_64-w64-mingw32.static-objdump` in `$PATH`?) [aot]: https://developer.xamarin.com/releases/android/xamarin.android_5/xamarin.android_5.1/#AOT_Support [mxe]: http://mxe.cc/
2016-06-07 00:12:49 +03:00
<AndroidMxeInstallPrefix>$(AndroidToolchainDirectory)\mxe</AndroidMxeInstallPrefix>
[android-toolchain] Permit zero-configuration builds. 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.
2016-04-19 03:33:04 +03:00
</PropertyGroup>
</Project>