xamarin-android/Makefile

146 строки
5.0 KiB
Makefile
Исходник Обычный вид История

export OS := $(shell uname)
export OS_ARCH := $(shell uname -m)
export NO_SUDO ?= false
V ?= 0
prefix = /usr/local
[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
CONFIGURATION = Debug
RUNTIME := $(shell if [ -f "`which mono64`" ] ; then echo mono64 ; else echo mono; fi) --debug=casts
[Xamarin.Android-Tests] Split out "full" apps (#146) We're trying to get [`make jenkins`][0] working on Jenkins, and [it's failing][1], as one might expect when a particular repo and associated build system has never been run on Jenkins before: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? This error occurs while building `src/Mono.Android/Test/Mono.Android-Tests.csproj`, and happens because the `Xamarin.Android.NUnitLite.dll` assembly isn't referenced... because it isn't *found*: Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved This returns us to a long-standing issue which I thought was mentioned in a commit somewhere, but I can't find at present: MSBuild doesn't support updating the assembly resolution directories *while MSBuild is running*. For example, we build `Xamarin.Android.NUniteLite.dll` into `bin/$(Configuration/lib/xbuild-frameworks/MonoAndroid/v1.0`, but "normal Xamarin.Android referencing projects" don't use a `@(ProjectReference)` to `Xamarin.Android.NUnitLite.csproj`, but instead a `@(Reference)` to the assembly: <!-- src/Mono.Android/Test/Mono.Android-Tests.csproj --> <Reference Include="Xamarin.Android.NUnitLite" /> The *requirement* for a "proper" Xamarin.Android SDK install is that `Xamarin.Android.NUnitLite.dll` can be found through a normal `@(Reference)`. In order to satisfy this requirement, we need to tell MSBuild where to find it, which can be with `xbuild` via the `$MSBuildExtensionsPath` and `$XBUILD_FRAMEWORK_FOLDERS_PATH` *environment variables*. *Environment variables*. MSBuild doesn't provide a way to update environment variables, short of writing a new Task which calls `Environment.SetEnvironmentVariable()`, and while [this works][2], it doesn't *actually* work [^3]. The short of all this is that it isn't possible, *within a single `xbuild` invocation*, to both build the Xamarin.Android SDK "environment" *and use that environment* as intended for "normal" apps. The fix, as is often the case, is to bend with the wind. Instead of requiring the impossible, move `src/Mono.Android/Test/Mono.Android-Tests.csproj` into a *new* `Xamarin.Android-Tests.sln` solution, *out of* `Xamarin.Android.sln`. This allows building `Xamarin.Android.sln` without error in a pristine environment -- that is, one that doesn't already have a system-wide Xamarin.Android install -- and separately building the tests by using `tools/scripts/xabuild`, which *can* export environment variables to manipulate `xbuild` behavior so that things Just Work™. Building `Mono.Android-Tests.csproj` and similar projects (`HelloWorld.csproj`!) can be done by using the new `make all-tests` make target. [0]: https://github.com/xamarin/xamarin-android/commit/a16673d3eb2c4945c3a74f5f8154603d7658fc9a [1]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/20/console [2]: https://github.com/xamarin/xamarin-android/pull/147 [^3]: [PR #147][2] isn't viable because of [xbuild's `AsssemblyResolver`][4]. There's no way to clear/invalidate `target_framework_cache`. The idea of PR #147 was to "hack things up" so that `Xamarin.Android.NuniteLite.dll` would be properly resolved during the build of `Mono.Android-Tests.csproj` *when building everything*. The problem is *this can't work*, because `xbuild` has a "target framework cache," with no way to invalidate it, and the cache is populated the first time the target framework is used. Due to build ordering issues, this first use is *before* `Xamarin.Android.NunitLite.dll` was built, and thus it doesn't exist in the cache. The result: Task "ResolveAssemblyReference" .... TargetFrameworkDirectories: /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/ ... Primary Reference System.Xml Reference System.Xml resolved to /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/System.Xml.dll. CopyLocal = False ... Primary Reference Xamarin.Android.NUnitLite Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved For searchpath {TargetFrameworkDirectory} Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/, assembly named 'Xamarin.Android.NUnitLite' not found. ... Consequently, the `mcs` invocation is missing a `/reference:path/to/Xamarin.Android.NUniteLite.dll`, and compilation fails: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? ...plus 29 others... [4]: https://github.com/mono/mono/blob/dd8aadf/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs#L131
2016-08-08 23:46:13 +03:00
SOLUTION = Xamarin.Android.sln
TEST_TARGETS = build-tools/scripts/RunTests.targets
[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
ifneq ($(V),0)
MONO_OPTIONS += --debug
endif
ifneq ($(MONO_OPTIONS),)
export MONO_OPTIONS
endif
include build-tools/scripts/msbuild.mk
[Xamarin.Android.Build.Utilities] Add AndroidVersions (#599) Commit 8e7d37bb is a sign of duplication: in order to use a `Mono.Android.dll` binding assembly, not only do we need to *build* the binding assembly, but we *also* need to update `Xamarin.Android.Build.Utilities.dll` to "know" about the new binding version (to map API level to `$(TargetFrameworkVersion)`). Even "better" (worse), if the new API level is a *preview*, there is no *consistent* API level. For example, with API-O, `android.jar` isn't at `$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`, where `@API_LEVEL@` is 26 (because various codepaths require that the "api level" be an integer). Instead, it's installed at `$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where `O` is the "id" of the preview API level. This "id" is "leaky", in turn requiring that `Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the mappings. Even "better" (worse), if we *forget* to cross all our our 't's and dot all of our 'i's, we'll have a binding assembly which can't be used. (Which is why we needed commit 8e7d37bb; without it, the API-O binding can't be used!) This is all obviously madness. ;-) Clean this mess up: 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml` file within the `$(TargetFrameworkVersion)` directory. This will contain all the information needed to map Android API levels to Ids and Android OS versions and `$(TargetFrameworkVersion)` values. ```xml <AndroidApiInfo> <Id>10</Id> <Level>10</Level> <Name>Gingerbread</Name> <Version>v2.3</Version> </AndroidApiInfo> ``` 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type which looks for and parses these new `AndroidApiInfo.xml` files. 3. Fixup all the other places using `AndroidVersion.KnownVersions` and related members to instead use `AndroidVersions`. 4. Remove all the old APIs which rely on hardcoded data. The advantage to all this is that we can support new API level bindings by just building a new `Mono.Android.dll` and placing an `AndroidApiInfo.xml` into the appropriate location (next to `Mono.Android.dll`). No further code changes would be required. Related: The build system still has a nasy habit of using system-wide directories to resolve files we'd really rather it not, e.g. in [xamarin-android/master build #503][m503]: [m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it. Target _GetReferenceAssemblyPaths: Task "GetReferenceAssemblyPaths" Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks' Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0' Done executing task "GetReferenceAssemblyPaths" Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj". Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it. Target _SetLatestTargetFrameworkVersion: Task "ResolveSdks" ReferenceAssemblyPaths: /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/ Note the use of the path `/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`. This *was* "fine" -- if undesirable -- but with the introduction of `AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks directory, everything falls apart, becuase the system install *does not have* the `AndroidApiInfo.xml` files, so *NO API LEVELS ARE FOUND*. Oops. The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`, and the sanest way to do *that* is to use `tools/scripts/xabuild` for the primary build. Unfortunately, using `xabuild` for the primary build breaks the `msbuild`-based build, as it can't resolve the `.NETFramework,Version=v4.6.1` framework. Context: https://github.com/xamarin/xamarin-android/pull/599#issuecomment-319801330 Split the difference here by introducing `$(_SLN_BUILD)`: use `xabuild` when building with `xbuild`, and continue using `msbuild` when building with `msbuild`.
2017-08-23 14:19:11 +03:00
ifeq ($(USE_MSBUILD),1)
_SLN_BUILD = $(MSBUILD)
else # $(MSBUILD) != 1
_SLN_BUILD = MSBUILD="$(MSBUILD)" tools/scripts/xabuild
endif # $(USE_MSBUILD) == 1
[Xamarin.Android-Tests] Split out "full" apps (#146) We're trying to get [`make jenkins`][0] working on Jenkins, and [it's failing][1], as one might expect when a particular repo and associated build system has never been run on Jenkins before: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? This error occurs while building `src/Mono.Android/Test/Mono.Android-Tests.csproj`, and happens because the `Xamarin.Android.NUnitLite.dll` assembly isn't referenced... because it isn't *found*: Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved This returns us to a long-standing issue which I thought was mentioned in a commit somewhere, but I can't find at present: MSBuild doesn't support updating the assembly resolution directories *while MSBuild is running*. For example, we build `Xamarin.Android.NUniteLite.dll` into `bin/$(Configuration/lib/xbuild-frameworks/MonoAndroid/v1.0`, but "normal Xamarin.Android referencing projects" don't use a `@(ProjectReference)` to `Xamarin.Android.NUnitLite.csproj`, but instead a `@(Reference)` to the assembly: <!-- src/Mono.Android/Test/Mono.Android-Tests.csproj --> <Reference Include="Xamarin.Android.NUnitLite" /> The *requirement* for a "proper" Xamarin.Android SDK install is that `Xamarin.Android.NUnitLite.dll` can be found through a normal `@(Reference)`. In order to satisfy this requirement, we need to tell MSBuild where to find it, which can be with `xbuild` via the `$MSBuildExtensionsPath` and `$XBUILD_FRAMEWORK_FOLDERS_PATH` *environment variables*. *Environment variables*. MSBuild doesn't provide a way to update environment variables, short of writing a new Task which calls `Environment.SetEnvironmentVariable()`, and while [this works][2], it doesn't *actually* work [^3]. The short of all this is that it isn't possible, *within a single `xbuild` invocation*, to both build the Xamarin.Android SDK "environment" *and use that environment* as intended for "normal" apps. The fix, as is often the case, is to bend with the wind. Instead of requiring the impossible, move `src/Mono.Android/Test/Mono.Android-Tests.csproj` into a *new* `Xamarin.Android-Tests.sln` solution, *out of* `Xamarin.Android.sln`. This allows building `Xamarin.Android.sln` without error in a pristine environment -- that is, one that doesn't already have a system-wide Xamarin.Android install -- and separately building the tests by using `tools/scripts/xabuild`, which *can* export environment variables to manipulate `xbuild` behavior so that things Just Work™. Building `Mono.Android-Tests.csproj` and similar projects (`HelloWorld.csproj`!) can be done by using the new `make all-tests` make target. [0]: https://github.com/xamarin/xamarin-android/commit/a16673d3eb2c4945c3a74f5f8154603d7658fc9a [1]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/20/console [2]: https://github.com/xamarin/xamarin-android/pull/147 [^3]: [PR #147][2] isn't viable because of [xbuild's `AsssemblyResolver`][4]. There's no way to clear/invalidate `target_framework_cache`. The idea of PR #147 was to "hack things up" so that `Xamarin.Android.NuniteLite.dll` would be properly resolved during the build of `Mono.Android-Tests.csproj` *when building everything*. The problem is *this can't work*, because `xbuild` has a "target framework cache," with no way to invalidate it, and the cache is populated the first time the target framework is used. Due to build ordering issues, this first use is *before* `Xamarin.Android.NunitLite.dll` was built, and thus it doesn't exist in the cache. The result: Task "ResolveAssemblyReference" .... TargetFrameworkDirectories: /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/ ... Primary Reference System.Xml Reference System.Xml resolved to /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/System.Xml.dll. CopyLocal = False ... Primary Reference Xamarin.Android.NUnitLite Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved For searchpath {TargetFrameworkDirectory} Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/, assembly named 'Xamarin.Android.NUnitLite' not found. ... Consequently, the `mcs` invocation is missing a `/reference:path/to/Xamarin.Android.NUniteLite.dll`, and compilation fails: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? ...plus 29 others... [4]: https://github.com/mono/mono/blob/dd8aadf/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs#L131
2016-08-08 23:46:13 +03:00
all::
[Xamarin.Android.Build.Utilities] Add AndroidVersions (#599) Commit 8e7d37bb is a sign of duplication: in order to use a `Mono.Android.dll` binding assembly, not only do we need to *build* the binding assembly, but we *also* need to update `Xamarin.Android.Build.Utilities.dll` to "know" about the new binding version (to map API level to `$(TargetFrameworkVersion)`). Even "better" (worse), if the new API level is a *preview*, there is no *consistent* API level. For example, with API-O, `android.jar` isn't at `$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`, where `@API_LEVEL@` is 26 (because various codepaths require that the "api level" be an integer). Instead, it's installed at `$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where `O` is the "id" of the preview API level. This "id" is "leaky", in turn requiring that `Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the mappings. Even "better" (worse), if we *forget* to cross all our our 't's and dot all of our 'i's, we'll have a binding assembly which can't be used. (Which is why we needed commit 8e7d37bb; without it, the API-O binding can't be used!) This is all obviously madness. ;-) Clean this mess up: 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml` file within the `$(TargetFrameworkVersion)` directory. This will contain all the information needed to map Android API levels to Ids and Android OS versions and `$(TargetFrameworkVersion)` values. ```xml <AndroidApiInfo> <Id>10</Id> <Level>10</Level> <Name>Gingerbread</Name> <Version>v2.3</Version> </AndroidApiInfo> ``` 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type which looks for and parses these new `AndroidApiInfo.xml` files. 3. Fixup all the other places using `AndroidVersion.KnownVersions` and related members to instead use `AndroidVersions`. 4. Remove all the old APIs which rely on hardcoded data. The advantage to all this is that we can support new API level bindings by just building a new `Mono.Android.dll` and placing an `AndroidApiInfo.xml` into the appropriate location (next to `Mono.Android.dll`). No further code changes would be required. Related: The build system still has a nasy habit of using system-wide directories to resolve files we'd really rather it not, e.g. in [xamarin-android/master build #503][m503]: [m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it. Target _GetReferenceAssemblyPaths: Task "GetReferenceAssemblyPaths" Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks' Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0' Done executing task "GetReferenceAssemblyPaths" Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj". Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it. Target _SetLatestTargetFrameworkVersion: Task "ResolveSdks" ReferenceAssemblyPaths: /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/ Note the use of the path `/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`. This *was* "fine" -- if undesirable -- but with the introduction of `AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks directory, everything falls apart, becuase the system install *does not have* the `AndroidApiInfo.xml` files, so *NO API LEVELS ARE FOUND*. Oops. The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`, and the sanest way to do *that* is to use `tools/scripts/xabuild` for the primary build. Unfortunately, using `xabuild` for the primary build breaks the `msbuild`-based build, as it can't resolve the `.NETFramework,Version=v4.6.1` framework. Context: https://github.com/xamarin/xamarin-android/pull/599#issuecomment-319801330 Split the difference here by introducing `$(_SLN_BUILD)`: use `xabuild` when building with `xbuild`, and continue using `msbuild` when building with `msbuild`.
2017-08-23 14:19:11 +03:00
$(_SLN_BUILD) $(MSBUILD_FLAGS) $(SOLUTION)
[Xamarin.Android-Tests] Split out "full" apps (#146) We're trying to get [`make jenkins`][0] working on Jenkins, and [it's failing][1], as one might expect when a particular repo and associated build system has never been run on Jenkins before: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? This error occurs while building `src/Mono.Android/Test/Mono.Android-Tests.csproj`, and happens because the `Xamarin.Android.NUnitLite.dll` assembly isn't referenced... because it isn't *found*: Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved This returns us to a long-standing issue which I thought was mentioned in a commit somewhere, but I can't find at present: MSBuild doesn't support updating the assembly resolution directories *while MSBuild is running*. For example, we build `Xamarin.Android.NUniteLite.dll` into `bin/$(Configuration/lib/xbuild-frameworks/MonoAndroid/v1.0`, but "normal Xamarin.Android referencing projects" don't use a `@(ProjectReference)` to `Xamarin.Android.NUnitLite.csproj`, but instead a `@(Reference)` to the assembly: <!-- src/Mono.Android/Test/Mono.Android-Tests.csproj --> <Reference Include="Xamarin.Android.NUnitLite" /> The *requirement* for a "proper" Xamarin.Android SDK install is that `Xamarin.Android.NUnitLite.dll` can be found through a normal `@(Reference)`. In order to satisfy this requirement, we need to tell MSBuild where to find it, which can be with `xbuild` via the `$MSBuildExtensionsPath` and `$XBUILD_FRAMEWORK_FOLDERS_PATH` *environment variables*. *Environment variables*. MSBuild doesn't provide a way to update environment variables, short of writing a new Task which calls `Environment.SetEnvironmentVariable()`, and while [this works][2], it doesn't *actually* work [^3]. The short of all this is that it isn't possible, *within a single `xbuild` invocation*, to both build the Xamarin.Android SDK "environment" *and use that environment* as intended for "normal" apps. The fix, as is often the case, is to bend with the wind. Instead of requiring the impossible, move `src/Mono.Android/Test/Mono.Android-Tests.csproj` into a *new* `Xamarin.Android-Tests.sln` solution, *out of* `Xamarin.Android.sln`. This allows building `Xamarin.Android.sln` without error in a pristine environment -- that is, one that doesn't already have a system-wide Xamarin.Android install -- and separately building the tests by using `tools/scripts/xabuild`, which *can* export environment variables to manipulate `xbuild` behavior so that things Just Work™. Building `Mono.Android-Tests.csproj` and similar projects (`HelloWorld.csproj`!) can be done by using the new `make all-tests` make target. [0]: https://github.com/xamarin/xamarin-android/commit/a16673d3eb2c4945c3a74f5f8154603d7658fc9a [1]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/20/console [2]: https://github.com/xamarin/xamarin-android/pull/147 [^3]: [PR #147][2] isn't viable because of [xbuild's `AsssemblyResolver`][4]. There's no way to clear/invalidate `target_framework_cache`. The idea of PR #147 was to "hack things up" so that `Xamarin.Android.NuniteLite.dll` would be properly resolved during the build of `Mono.Android-Tests.csproj` *when building everything*. The problem is *this can't work*, because `xbuild` has a "target framework cache," with no way to invalidate it, and the cache is populated the first time the target framework is used. Due to build ordering issues, this first use is *before* `Xamarin.Android.NunitLite.dll` was built, and thus it doesn't exist in the cache. The result: Task "ResolveAssemblyReference" .... TargetFrameworkDirectories: /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/ ... Primary Reference System.Xml Reference System.Xml resolved to /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/System.Xml.dll. CopyLocal = False ... Primary Reference Xamarin.Android.NUnitLite Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved For searchpath {TargetFrameworkDirectory} Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/, assembly named 'Xamarin.Android.NUnitLite' not found. ... Consequently, the `mcs` invocation is missing a `/reference:path/to/Xamarin.Android.NUniteLite.dll`, and compilation fails: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? ...plus 29 others... [4]: https://github.com/mono/mono/blob/dd8aadf/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs#L131
2016-08-08 23:46:13 +03:00
all-tests::
MSBUILD="$(MSBUILD)" tools/scripts/xabuild $(MSBUILD_FLAGS) Xamarin.Android-Tests.sln
install::
@if [ ! -d "bin/$(CONFIGURATION)" ]; then \
echo "run 'make all' before you execute 'make install'!"; \
exit 1; \
fi
[structure] Rework installation directory structure (#704) Context: https://github.com/xamarin/xamarin-android/pull/253#discussion_r82862993 The *intention* is that Jenkins-produced `oss-xamarin.android*.zip` artifacts be usable on Windows, so that side-by-side testing can be performed without replacing the system installation. Usage is in [UsingJenkinsBuildArtifacts.md](Documentation/UsingJenkinsBuildArtifacts). This isn't *entirely* the case. It was *apparently* the case at the time of commit 87ca2737, but things have bitrotten since. For example, following the 87ca2737 instructions would currently result in an XA0020 `Could not find monodroid` error, because `class-parse.exe` wasn't where Windows expects it to be (it was in `lib/mandroid`, not `lib/xbuild/Xamarin/Android`). This needs to be fixed. Additionally, PR #253 mentions that, for filesystem organization, it would be useful if the macOS/Linux directory structure -- `$prefix/bin`, `$prefix/lib/mandroid`, `$prefix/lib/xbuild/Xamarin/Android`, `$prefix/lib/xbuild-frameworks` -- more closely resembled the Windows directory structure of `$MSBuild` and `$ReferenceAssemblies` (as seen in `.vsix` files). This would turn macOS/Linux into using `$xa_prefix/xbuild` and `$xa_prefix/xbuild-frameworks` directories. `$prefix/bin` would only contain `xabuild`. What is currently in `$prefix/lib/mandroid` would be merged with `$xa_prefix/xbuild/Xamarin/Android`. `$xa_prefix` would `$prefix/lib/xamarin.android`. This would turn the current macOS structure: $prefix/bin/xabuild $prefix/bin/generator $prefix/bin/cross-arm $prefix/lib/mandroid/generator.exe $prefix/lib/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets Into: $prefix/bin/xabuild $prefix/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xamarin.android/xbuild/Xamarin/Android/generator.exe $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/cross-arm Other notes: * The `bundle-*.zip` filename has been has been changed to include a *hash* of the contents of various files, in particular `build-tools\mono-runtimes.*`. This was instigated via a conversation with @kumpera about making the filename more "idiot-proof": `mono-runtimes.props` contains *compiler flags*, and if any of those change, then *logically* the bundle should differ as well, as the mono runtimes may differ in significant ways. In theory, the `-vXX` version should be used to track this, but this is a manual change, easy to overlook. The new `-hHASH` part of the filename should be more automagic. The new `<HashFileContents/>` task in `xa-prep-tasks.dll` is responsible for creating the hash value. * `Configuration.Java.Interop.Override.props` was moved into `build-tools/scripts`, because that would cleanup the root directory a bit. * OS-specific binaries are now placed into `$prefix/lib/xamarin.android/xbuild/Xamarin/Android/$(HostOS)`. On a theoretical plus side, this means that the same build directory can contain OS-specific binaries for multiple operating systems. (I don't know if anyone shares a build tree between e.g. macOS and Linux, but if anyone *does*...) Unfortunately this requires a workaround for an `xbuild` bug: `%(_LlvmRuntime.InstallPath)` and `%(_MonoCrossRuntime.InstallPath)` *cannot* use MSBuild properties, e.g. `<InstallPath>$(HostOS)/</InstallPath>` doesn't work as desired; it's instead treated literally. Special-case `%(InstallPath)` until we fully migrate to MSBuild. * `$(MonoAndroidToolsDirectory)` should be considered *dead*, along with `$(MonoAndroidBinDirectory)`, as these should now *always* be the same directory as where `Xamarin.Android.Build.Tasks.dll` is located, or a `$(HostOS)` sub-directory. * `Xamarin.ProjectTools.csproj` needed to be updated to ensure that the build order was correct. * Remove all `[Obsolete]` and unreferenced members from `Xamarin.Android.Build.Utilities.dll`. There's too much in there, and it makes my head hurt trying to understand the interrelationships between it all. If it's not used, it's gone. * The changes to `src/monodroid/jni/Android.mk` are...weird. The removal of `-I$(topdir)/libmonodroid/zip`/etc. is to reduce use of non-existent paths, as `$(topdir)` isn't defined, so that's *actually* `-I/libmonodroid/zip`, which is nonsensical. So far, so good. What's *odd* is the addition of `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`: This is needed so that `external/mono/support/zlib-helper.c` exports `CreateZStream` and related symbols, otherwise we get a unit test failure in `GzipStreamTest.Compression` due to an `EntryPointNotFoundException`, because `CreateZStream` isn't exported/public. What's odd here is that I don't understand what caused this behavior to change. Previous builds exported `CreateZStream`, otherwise the tests would fail, and I don't understand how any of the other changes in this PR would be at fault, though that's certainly the most plausible explanation. Regardless, `-Ijni` *first* (due to adding `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`) is the desired behavior, so that `jni/config.h` is included, thus ensuring that `MONO_API` has the required definition when building `zlib-helper.c`.
2017-07-28 16:36:32 +03:00
-mkdir -p "$(prefix)/bin"
-mkdir -p "$(prefix)/lib/mono/xbuild-frameworks"
-mkdir -p "$(prefix)/lib/xamarin.android"
-mkdir -p "$(prefix)/lib/mono/xbuild/Xamarin/"
[structure] Rework installation directory structure (#704) Context: https://github.com/xamarin/xamarin-android/pull/253#discussion_r82862993 The *intention* is that Jenkins-produced `oss-xamarin.android*.zip` artifacts be usable on Windows, so that side-by-side testing can be performed without replacing the system installation. Usage is in [UsingJenkinsBuildArtifacts.md](Documentation/UsingJenkinsBuildArtifacts). This isn't *entirely* the case. It was *apparently* the case at the time of commit 87ca2737, but things have bitrotten since. For example, following the 87ca2737 instructions would currently result in an XA0020 `Could not find monodroid` error, because `class-parse.exe` wasn't where Windows expects it to be (it was in `lib/mandroid`, not `lib/xbuild/Xamarin/Android`). This needs to be fixed. Additionally, PR #253 mentions that, for filesystem organization, it would be useful if the macOS/Linux directory structure -- `$prefix/bin`, `$prefix/lib/mandroid`, `$prefix/lib/xbuild/Xamarin/Android`, `$prefix/lib/xbuild-frameworks` -- more closely resembled the Windows directory structure of `$MSBuild` and `$ReferenceAssemblies` (as seen in `.vsix` files). This would turn macOS/Linux into using `$xa_prefix/xbuild` and `$xa_prefix/xbuild-frameworks` directories. `$prefix/bin` would only contain `xabuild`. What is currently in `$prefix/lib/mandroid` would be merged with `$xa_prefix/xbuild/Xamarin/Android`. `$xa_prefix` would `$prefix/lib/xamarin.android`. This would turn the current macOS structure: $prefix/bin/xabuild $prefix/bin/generator $prefix/bin/cross-arm $prefix/lib/mandroid/generator.exe $prefix/lib/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets Into: $prefix/bin/xabuild $prefix/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xamarin.android/xbuild/Xamarin/Android/generator.exe $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/cross-arm Other notes: * The `bundle-*.zip` filename has been has been changed to include a *hash* of the contents of various files, in particular `build-tools\mono-runtimes.*`. This was instigated via a conversation with @kumpera about making the filename more "idiot-proof": `mono-runtimes.props` contains *compiler flags*, and if any of those change, then *logically* the bundle should differ as well, as the mono runtimes may differ in significant ways. In theory, the `-vXX` version should be used to track this, but this is a manual change, easy to overlook. The new `-hHASH` part of the filename should be more automagic. The new `<HashFileContents/>` task in `xa-prep-tasks.dll` is responsible for creating the hash value. * `Configuration.Java.Interop.Override.props` was moved into `build-tools/scripts`, because that would cleanup the root directory a bit. * OS-specific binaries are now placed into `$prefix/lib/xamarin.android/xbuild/Xamarin/Android/$(HostOS)`. On a theoretical plus side, this means that the same build directory can contain OS-specific binaries for multiple operating systems. (I don't know if anyone shares a build tree between e.g. macOS and Linux, but if anyone *does*...) Unfortunately this requires a workaround for an `xbuild` bug: `%(_LlvmRuntime.InstallPath)` and `%(_MonoCrossRuntime.InstallPath)` *cannot* use MSBuild properties, e.g. `<InstallPath>$(HostOS)/</InstallPath>` doesn't work as desired; it's instead treated literally. Special-case `%(InstallPath)` until we fully migrate to MSBuild. * `$(MonoAndroidToolsDirectory)` should be considered *dead*, along with `$(MonoAndroidBinDirectory)`, as these should now *always* be the same directory as where `Xamarin.Android.Build.Tasks.dll` is located, or a `$(HostOS)` sub-directory. * `Xamarin.ProjectTools.csproj` needed to be updated to ensure that the build order was correct. * Remove all `[Obsolete]` and unreferenced members from `Xamarin.Android.Build.Utilities.dll`. There's too much in there, and it makes my head hurt trying to understand the interrelationships between it all. If it's not used, it's gone. * The changes to `src/monodroid/jni/Android.mk` are...weird. The removal of `-I$(topdir)/libmonodroid/zip`/etc. is to reduce use of non-existent paths, as `$(topdir)` isn't defined, so that's *actually* `-I/libmonodroid/zip`, which is nonsensical. So far, so good. What's *odd* is the addition of `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`: This is needed so that `external/mono/support/zlib-helper.c` exports `CreateZStream` and related symbols, otherwise we get a unit test failure in `GzipStreamTest.Compression` due to an `EntryPointNotFoundException`, because `CreateZStream` isn't exported/public. What's odd here is that I don't understand what caused this behavior to change. Previous builds exported `CreateZStream`, otherwise the tests would fail, and I don't understand how any of the other changes in this PR would be at fault, though that's certainly the most plausible explanation. Regardless, `-Ijni` *first* (due to adding `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`) is the desired behavior, so that `jni/config.h` is included, thus ensuring that `MONO_API` has the required definition when building `zlib-helper.c`.
2017-07-28 16:36:32 +03:00
cp -a "bin/$(CONFIGURATION)/lib/xamarin.android/." "$(prefix)/lib/xamarin.android/"
-rm -rf "$(prefix)/lib/mono/xbuild/Xamarin/Android"
-rm -rf "$(prefix)/lib/mono/xbuild-frameworks/MonoAndroid"
[structure] Rework installation directory structure (#704) Context: https://github.com/xamarin/xamarin-android/pull/253#discussion_r82862993 The *intention* is that Jenkins-produced `oss-xamarin.android*.zip` artifacts be usable on Windows, so that side-by-side testing can be performed without replacing the system installation. Usage is in [UsingJenkinsBuildArtifacts.md](Documentation/UsingJenkinsBuildArtifacts). This isn't *entirely* the case. It was *apparently* the case at the time of commit 87ca2737, but things have bitrotten since. For example, following the 87ca2737 instructions would currently result in an XA0020 `Could not find monodroid` error, because `class-parse.exe` wasn't where Windows expects it to be (it was in `lib/mandroid`, not `lib/xbuild/Xamarin/Android`). This needs to be fixed. Additionally, PR #253 mentions that, for filesystem organization, it would be useful if the macOS/Linux directory structure -- `$prefix/bin`, `$prefix/lib/mandroid`, `$prefix/lib/xbuild/Xamarin/Android`, `$prefix/lib/xbuild-frameworks` -- more closely resembled the Windows directory structure of `$MSBuild` and `$ReferenceAssemblies` (as seen in `.vsix` files). This would turn macOS/Linux into using `$xa_prefix/xbuild` and `$xa_prefix/xbuild-frameworks` directories. `$prefix/bin` would only contain `xabuild`. What is currently in `$prefix/lib/mandroid` would be merged with `$xa_prefix/xbuild/Xamarin/Android`. `$xa_prefix` would `$prefix/lib/xamarin.android`. This would turn the current macOS structure: $prefix/bin/xabuild $prefix/bin/generator $prefix/bin/cross-arm $prefix/lib/mandroid/generator.exe $prefix/lib/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets Into: $prefix/bin/xabuild $prefix/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xamarin.android/xbuild/Xamarin/Android/generator.exe $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/cross-arm Other notes: * The `bundle-*.zip` filename has been has been changed to include a *hash* of the contents of various files, in particular `build-tools\mono-runtimes.*`. This was instigated via a conversation with @kumpera about making the filename more "idiot-proof": `mono-runtimes.props` contains *compiler flags*, and if any of those change, then *logically* the bundle should differ as well, as the mono runtimes may differ in significant ways. In theory, the `-vXX` version should be used to track this, but this is a manual change, easy to overlook. The new `-hHASH` part of the filename should be more automagic. The new `<HashFileContents/>` task in `xa-prep-tasks.dll` is responsible for creating the hash value. * `Configuration.Java.Interop.Override.props` was moved into `build-tools/scripts`, because that would cleanup the root directory a bit. * OS-specific binaries are now placed into `$prefix/lib/xamarin.android/xbuild/Xamarin/Android/$(HostOS)`. On a theoretical plus side, this means that the same build directory can contain OS-specific binaries for multiple operating systems. (I don't know if anyone shares a build tree between e.g. macOS and Linux, but if anyone *does*...) Unfortunately this requires a workaround for an `xbuild` bug: `%(_LlvmRuntime.InstallPath)` and `%(_MonoCrossRuntime.InstallPath)` *cannot* use MSBuild properties, e.g. `<InstallPath>$(HostOS)/</InstallPath>` doesn't work as desired; it's instead treated literally. Special-case `%(InstallPath)` until we fully migrate to MSBuild. * `$(MonoAndroidToolsDirectory)` should be considered *dead*, along with `$(MonoAndroidBinDirectory)`, as these should now *always* be the same directory as where `Xamarin.Android.Build.Tasks.dll` is located, or a `$(HostOS)` sub-directory. * `Xamarin.ProjectTools.csproj` needed to be updated to ensure that the build order was correct. * Remove all `[Obsolete]` and unreferenced members from `Xamarin.Android.Build.Utilities.dll`. There's too much in there, and it makes my head hurt trying to understand the interrelationships between it all. If it's not used, it's gone. * The changes to `src/monodroid/jni/Android.mk` are...weird. The removal of `-I$(topdir)/libmonodroid/zip`/etc. is to reduce use of non-existent paths, as `$(topdir)` isn't defined, so that's *actually* `-I/libmonodroid/zip`, which is nonsensical. So far, so good. What's *odd* is the addition of `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`: This is needed so that `external/mono/support/zlib-helper.c` exports `CreateZStream` and related symbols, otherwise we get a unit test failure in `GzipStreamTest.Compression` due to an `EntryPointNotFoundException`, because `CreateZStream` isn't exported/public. What's odd here is that I don't understand what caused this behavior to change. Previous builds exported `CreateZStream`, otherwise the tests would fail, and I don't understand how any of the other changes in this PR would be at fault, though that's certainly the most plausible explanation. Regardless, `-Ijni` *first* (due to adding `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`) is the desired behavior, so that `jni/config.h` is included, thus ensuring that `MONO_API` has the required definition when building `zlib-helper.c`.
2017-07-28 16:36:32 +03:00
ln -s "$(prefix)/lib/xamarin.android/xbuild/Xamarin/Android/" "$(prefix)/lib/mono/xbuild/Xamarin/Android"
ln -s "$(prefix)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/" "$(prefix)/lib/mono/xbuild-frameworks/MonoAndroid"
if [ ! -e "$(prefix)/bin/mono" ]; then \
cp tools/scripts/xabuild "$(prefix)/bin/xabuild"; \
fi
uninstall::
rm -rf "$(prefix)/lib/xamarin.android/" "$(prefix)/bin/xabuild"
rm "$(prefix)/lib/mono/xbuild/Xamarin/Android"
rm "$(prefix)/lib/mono/xbuild-frameworks/MonoAndroid"
ifeq ($(OS),Linux)
export LINUX_DISTRO := $(shell lsb_release -i -s || true)
export LINUX_DISTRO_RELEASE := $(shell lsb_release -r -s || true)
prepare:: linux-prepare
endif # $(OS)=Linux
[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
prepare:: prepare-msbuild
linux-prepare::
BINFMT_MISC_TROUBLE="cli win" \
BINFMT_WARN=no ; \
for m in $BINFMT_MISC_TROUBLE; do \
if [ -f /proc/sys/fs/binfmt_misc/$$m ]; then \
BINFMT_WARN=yes ; \
fi ; \
done ; \
if [ "x$$BINFMT_WARN" = "xyes" ]; then \
cat Documentation/binfmt_misc-warning-Linux.txt ; \
fi; \
if [ -f build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO).sh ]; then \
sh build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO).sh; \
elif [ -f build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO)-$(LINUX_DISTRO_RELEASE).sh ]; then \
sh build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO)-$(LINUX_DISTRO_RELEASE).sh; \
fi; \
[xa-prep-tasks] Use the Mono bundle (#162) Context: https://github.com/xamarin/xamarin-android/commit/fbfd676c102c63e4e06e750857b178725e33450c Stage 3 of the cunning plan is to (attempt to) use the mono bundle introduced in commit fbfd676c. This "simple" desire (ha!) re-raises the architectural project dependency issue "solved" in fbfd676c, but first, a simple question: What should download the mono bundle? There are two plausible answers: 1. `make prepare` can (somehow) handle it. 2. MSBuild can (somehow) handle it. Both are plausible. The problem with using `make` targets (1) is there is increased potential for "duplication" -- duplication of the bundle filename, downloading it, and extracting it. Plus, `make` isn't "Windows friendly", in that GNU make isn't (normally) present with Visual Studio. (`NMAKE` is, but the Makefiles in this project are not compatible with `NMAKE`.) Which brings us to MSBuild (2): can it handle the task? To tackle that, we need to be able to have an MSBuild task project which has *no dependencies*, so that it can download and extract the mono bundle *before anything else runs*, as it may be downloading contents which mean that other projects don't *need* to run. The need for a "pre-bootstrap" task assembly -- called `xa-prep-tasks` -- thus "undoes" *some* of the logic regarding `libzip-windows.mdproj` and the `<Zip/>` task from fbfd676c: it isn't *possible* to rely on `libzip` from a "pre-build" state, as `libzip` is one of the things in the mono bundle, so now we need *two* "bootstrap" task assemblies: one without a `libzip` dependency -- `xa-prep-tasks.dll` -- and one *with* a `libzip` dependency -- `Xamarin.Android.Tools.BootstrapTasks.dll` Move tasks which don't currently require `libzip` -- or won't in the future, or laziness -- from `Xamarin.Android.Tools.BootstrapTasks.dll` and move them into `xa-prep-tasks.dll`. With that architectural compromise in place, add `xa-prep-tasks` as a `@(ProjectReference)` to various projects to help ensure it's built *first*, and rearchitect `bundle.mdproj` so that `xa-prep-tasks.targets` and `bundle.targets` can use the same targets to compute the bundle filename, now in `build-tools/bundle/bundle-path.targets`. Add a post-build step to `xa-prep-tasks.csproj` which downloads and extracts the expected mono bundle. One "problem" (feature?) is that the new `<SystemUnzip/>` task doesn't report errors as errors when unzip'ing the file. This turns out to be fine here because when downloading the mono bundle from Azure we don't get a 404 *anyway* -- Azure instead returns an XML document containing an error message (wat?!). We can thus ignore most error handling entirely...though we're *also* ignoring any checking for invalid downloads, which is something we should address in the future. Update the varioous project files so that they won't attempt to rebuild binaries that were present in the mono bundle.
2016-08-16 23:02:48 +03:00
# $(call GetPath,path)
GetPath = $(shell $(MSBUILD) $(MSBUILD_FLAGS) /p:DoNotLoadOSProperties=True /nologo /v:minimal /t:Get$(1)FullPath build-tools/scripts/Paths.targets | tr -d '[[:space:]]' )
[build] Support building *from clean* with `msbuild` (#355) Context: https://github.com/xamarin/xamarin-android/commit/b1f1370896047966319655ea2b19a6a243719742 Context: https://github.com/xamarin/xamarin-android/commit/452d405e32e0b92dc1958f8ee3b101aae35ec859 Context: https://github.com/xamarin/xamarin-android/commit/9a50c668a4466915f07efd2fd0794b39ed84ba8c Context: https://github.com/xamarin/xamarin-android/commit/b89dc15d9bfeb2e6e03efbeb8e50895c372dbc5b The `xamarin-android` repo [can't be built with msbuild][0]: src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj(348,3): error MSB4019: The imported project ".../bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. ... src/Mono.Posix/Mono.Posix.csproj(236,3): error MSB4019: The imported project ".../bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. ... src/Mono.Data.Sqlite/Mono.Data.Sqlite.csproj(183,3): error MSB4019: The imported project ".../bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. Plus various other similar and different errors. This is a bit of a problem as I'd like to build everthing with MSBuild, particularly with a view toward future/eventual IDE integration, but if things don't build with MSBuild *at all*... That's a bit of a pickle. But first, about those above errors...what's going on? The short version is that `xbuild` has a "feature" that `msbuild` lacks, and it's a feature that has been inadvertently relied on: `xbuild` loads projects lazily. This requires elaboration. :-) A "solution" is a graph of projects with various dependencies, as specified by the `.sln` file and MSBuild `@(ProjectReference)` items. Reading this graph requires parsing the e.g. `.csproj` files to read the `@(ProjectReference)` items to construct the graph so that projects can be built in the proper order. This is where `xbuild` and `msbuild` appear to differ: * `xbuild` appears to use a "normal" XML parser to read project files when constructing the project graph. * `msbuild` appears to "fully load" the project files into an internal object instance for further processing. The difference between these approaches is visible when a project file `<Import/>`s a file...which doesn't (yet!) exist. Case in point: `Mono.Posix.csproj` needs to be a "normal" Xamarin.Android project file, using the normal Xamarin.Android build process, so that Android native libraries can be embedded into `Mono.Posix.dll` for use by end-user applications. To do so, it needs to `<Import/>` the Xamarin.Android MSBuild targets: <Import Project="$(OutputPath)\..\..\..\xbuild\Xamarin\Android\Xamarin.Android.CSharp.targets" /> In a clean build tree -- e.g. immediately after checkout -- *the above file does not exist*. `Xamarin.Android.CSharp.targets` is installed into the above directory by `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj` (via `%(None.CopyToOutputDirectory)` set to `PreserveNewest`), which means that `Xamarin.Android.CSharp.targets` won't be available for processing by `Mono.Posix.csproj` until *after* `Xamarin.Android.Build.Tasks.csproj` has been built. Under `xbuild`, this Just Works™: `Mono.Posix.csproj` has a `@(ProjectReference)` to `Xamarin.Android.Build.Tasks.csproj`, so `xbuild` loads `Mono.Posix.csproj` into an XML parser, extracts the `@(ProjectReference)` items, and continues on its merry way *without* evaluating the `<Import/>`s within `Mono.Posix.csproj`. Under `msbuild`, this fails horrifically: `Xamarin.Android.CSharp.targets` isn't in the expected directory, and `msbuild` reports an MSB4019 error. MSBuild attempts to continue (why?!), but nothing can actually build sanely. There are two plausible fixes for this scenario: 1. Add a layer of indirection! 2. Abuse `make prepare`. For option (1), see e.g. (b1f13708) `build-tools/mono-runtimes/mono-runtimes.mdproj` and `build-tools/mono-runtimes/mono-runtimes.targets`, in which the `Build` target is altered so that nothing is done if the outputs already exist; otherwise the `<MSBuild/>` task is used to invoke the `ForceBuild` target. A similar thing could plausibly be done for `Mono.Posix.csproj`, by creating a "proxy" project which is used by `@(ProjectReference)` for determining the dependency graph, and the "proxy" project then delegates to the "real" project. I don't personally like this idea, as I'm not sure what it looks like from the IDE. There would now be two projects instead of one for *each* MSB4019 error, and there are *10* MSB4019 errors (now). Option (2) involves altering `make prepare` so that when `msbuild` is used, we explicitly build a set of projects *before* `Xamarin.Android.sln` is built. This allows us to manually intervene and build projects in an order which will appease `msbuild`s "eager" resolving and loading of all referenced files. This also works, is much simpler, and means we *don't* need to introduce 10 additional project files simply to appease MSBuild. Perhaps not surprisingly, that conceptual change -- the introduction of `make prepare-msbuild` -- is *tiny* in this patch. Then we have other `xbuild`-vs-`msbuild`-isms. Bump to Java.Interop/65a0157f, as that commit is needed to build cleanly with `msbuild`. `android-toolchain.targets` can't use `$(_Toolchain)` because then `%(_NdkToolchain.Identity)` isn't properly batched into the `<Exec/>`. The result is a build error when invoking `make-standalone-toolchain.sh` when it's invoked an additional time, but without a corresponding `@(_NdkToolchain)`, so the command line is just completely bizarro and fails. `Mono.Data.Sqlite.csproj` and `Mono.Posix.csproj` need to set `$(NoStdLib)` to True so that MSBuild doesn't add the *system* `mscorlib.dll` when building the assemblies. When `$(NoStdLib)` is False, the `<Csc/>` task is executed referencing *two* `mscorlib.dll` assemblies, and things go badly from there. `System.Drawing.Primitives.csproj` *does* properly set `$(NoStdLib)` to True, but then it *also* set it to False in the Debug and Release sections (?!). Remove the extra -- and wrong! -- overrides. `Xamarin.Android.Build.Tasks.targets` needs to provide `$(CscToolPath)` and `$(CscToolExe)` to the `<Csc/>` task. Otherwise, `msbuild` defaults to trying to invoke `csc.exe`, which doesn't exist on mono 4.6, breaking the `_BuildMonoSymbolicate` target. Finally, `System.Runtime`... We have a bit of a history of adding a `@(Reference)` to `System.Runtime` (452d405e) and removing that same reference (9a50c668, b89dc15d). The short version is that `xbuild` errors if `System.Runtime` is referenced, while `msbuild` errors if `System.Runtime` *isn't* referenced. #facepalm "Fix" this by altering `$(MSBUILD_FLAGS)` so that when building with `xbuild` the `$(_XABuildingWithXBuild)` property is True. We can then make the `@(Reference)`s to `System.Runtime` conditional on our *not* building with `xbuild`. (This might mean we don't build from the IDE until it uses `msbuild`; I haven't tested this.) [0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-msbuild/87/consoleText
2017-01-10 19:16:40 +03:00
MSBUILD_PREPARE_PROJS = \
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
[build] Fix `make prepare` ordering (#937) @clancey was trying to build xamarin-android, which failed: $ make prepare ./build-tools/scripts/generate-os-info Configuration.OperatingSystem.props xbuild /p:Configuration=Debug /p:_DebugFileExt=.pdb build-tools/dependencies/dependencies.mdproj ... warning : Referenced Project ../../external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Xamarin.Android.Tools.AndroidSdk.csproj not found, ignoring. ... Xamarin.Android.BuildTools.PrepTasks/JdkInfo.cs(9,23): error CS0234: The type or namespace name 'Tools' does not exist in the namespace 'Xamarin.Android' (are you missing an assembly reference?) The problem is that `make prepare-deps`, which builds `build-tools/dependencies/dependencies.mdproj`, implicitly builds `build-tools/xa-prep-tasks/xa-prep-tasks.csproj`, which in turn depends on `external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Xamarin.Android.Tools.AndroidSdk.csproj`, which is only reliably created by `make prepare-external`s `git submodule update --init --recursive`. Unfortunately, `make prepare-external` wasn't invoked until *after* `make prepare-deps`, meaning there is no way for `make prepare` to actually work on a clean install! (This works on Jenkins because Jenkins automatically checks out all submodules, so it never encounters this "clean checkout" scenario.) Reorder the targets that `make prepare` executes so that `make prepare-external` is run *before* `make prepare-deps`, ensuring that git submodules exist before we attempt to use them.
2017-10-17 18:14:59 +03:00
prepare-external:
2016-04-20 04:30:00 +03:00
git submodule update --init --recursive
[Xamarin.Android-Tests] Split out "full" apps (#146) We're trying to get [`make jenkins`][0] working on Jenkins, and [it's failing][1], as one might expect when a particular repo and associated build system has never been run on Jenkins before: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? This error occurs while building `src/Mono.Android/Test/Mono.Android-Tests.csproj`, and happens because the `Xamarin.Android.NUnitLite.dll` assembly isn't referenced... because it isn't *found*: Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved This returns us to a long-standing issue which I thought was mentioned in a commit somewhere, but I can't find at present: MSBuild doesn't support updating the assembly resolution directories *while MSBuild is running*. For example, we build `Xamarin.Android.NUniteLite.dll` into `bin/$(Configuration/lib/xbuild-frameworks/MonoAndroid/v1.0`, but "normal Xamarin.Android referencing projects" don't use a `@(ProjectReference)` to `Xamarin.Android.NUnitLite.csproj`, but instead a `@(Reference)` to the assembly: <!-- src/Mono.Android/Test/Mono.Android-Tests.csproj --> <Reference Include="Xamarin.Android.NUnitLite" /> The *requirement* for a "proper" Xamarin.Android SDK install is that `Xamarin.Android.NUnitLite.dll` can be found through a normal `@(Reference)`. In order to satisfy this requirement, we need to tell MSBuild where to find it, which can be with `xbuild` via the `$MSBuildExtensionsPath` and `$XBUILD_FRAMEWORK_FOLDERS_PATH` *environment variables*. *Environment variables*. MSBuild doesn't provide a way to update environment variables, short of writing a new Task which calls `Environment.SetEnvironmentVariable()`, and while [this works][2], it doesn't *actually* work [^3]. The short of all this is that it isn't possible, *within a single `xbuild` invocation*, to both build the Xamarin.Android SDK "environment" *and use that environment* as intended for "normal" apps. The fix, as is often the case, is to bend with the wind. Instead of requiring the impossible, move `src/Mono.Android/Test/Mono.Android-Tests.csproj` into a *new* `Xamarin.Android-Tests.sln` solution, *out of* `Xamarin.Android.sln`. This allows building `Xamarin.Android.sln` without error in a pristine environment -- that is, one that doesn't already have a system-wide Xamarin.Android install -- and separately building the tests by using `tools/scripts/xabuild`, which *can* export environment variables to manipulate `xbuild` behavior so that things Just Work™. Building `Mono.Android-Tests.csproj` and similar projects (`HelloWorld.csproj`!) can be done by using the new `make all-tests` make target. [0]: https://github.com/xamarin/xamarin-android/commit/a16673d3eb2c4945c3a74f5f8154603d7658fc9a [1]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/20/console [2]: https://github.com/xamarin/xamarin-android/pull/147 [^3]: [PR #147][2] isn't viable because of [xbuild's `AsssemblyResolver`][4]. There's no way to clear/invalidate `target_framework_cache`. The idea of PR #147 was to "hack things up" so that `Xamarin.Android.NuniteLite.dll` would be properly resolved during the build of `Mono.Android-Tests.csproj` *when building everything*. The problem is *this can't work*, because `xbuild` has a "target framework cache," with no way to invalidate it, and the cache is populated the first time the target framework is used. Due to build ordering issues, this first use is *before* `Xamarin.Android.NunitLite.dll` was built, and thus it doesn't exist in the cache. The result: Task "ResolveAssemblyReference" .... TargetFrameworkDirectories: /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/ ... Primary Reference System.Xml Reference System.Xml resolved to /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/System.Xml.dll. CopyLocal = False ... Primary Reference Xamarin.Android.NUnitLite Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved For searchpath {TargetFrameworkDirectory} Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/, assembly named 'Xamarin.Android.NUnitLite' not found. ... Consequently, the `mcs` invocation is missing a `/reference:path/to/Xamarin.Android.NUniteLite.dll`, and compilation fails: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? ...plus 29 others... [4]: https://github.com/mono/mono/blob/dd8aadf/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs#L131
2016-08-08 23:46:13 +03:00
nuget restore $(SOLUTION)
nuget restore Xamarin.Android-Tests.sln
[build] Prepare Java.Interop for all $(CONFIGURATIONS) [Java.Interop/7d9d72a5][ji7], pulled in via 59518692, has an interesting semantic change: when building the Release configuration: # Assume a clean build tree... make prepare all CONFIGURATIONS=Release Java.Interop now requires that `external/Java.Interop/bin/BuildRelease/JdkInfo.props` exist. (*Previously*, the Release configuration would use the `…/BuildDebug/JdkInfo.props` file.) Unfortunately, xamarin-android wasn't updated accordingly. As such, if *only* the Release configuration is built -- not Debug *and* Release, as Jenkins does -- then xamarin-android doesn't build: xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.csproj: error : …/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.csproj: Java.Interop.targets: Project file could not be imported, it was being imported by …/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.csproj: …/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.targets could not import "$(JNIEnvGenPath)\JdkInfo.props" `$(JNIEnvGenPath)` is now `bin/Build$(Configuration)`, whereas before it was always `bin/BuildDebug`, so the above error occurs because `external/Java.Interop/bin/BuildRelease/JdkInfo.props` doesn't exist. Fix the `make prepare` target so that *all* `$(CONFIGURATIONS)` values are configured for Java.Interop, not just the Debug configuration. This should allow Release-only builds to work. [ji7]: https://github.com/xamarin/Java.Interop/commit/7d9d72a538c4d7b9058e8e002c7c7138c16f425b
2017-09-07 03:22:24 +03:00
$(foreach conf, $(CONFIGURATIONS), \
(cd external/xamarin-android-tools && make prepare CONFIGURATION=$(conf)) && \
(cd $(call GetPath,JavaInterop) && make prepare CONFIGURATION=$(conf)) && \
(cd $(call GetPath,JavaInterop) && make bin/Build$(conf)/JdkInfo.props CONFIGURATION=$(conf)) && ) \
[build] Prepare Java.Interop for all $(CONFIGURATIONS) [Java.Interop/7d9d72a5][ji7], pulled in via 59518692, has an interesting semantic change: when building the Release configuration: # Assume a clean build tree... make prepare all CONFIGURATIONS=Release Java.Interop now requires that `external/Java.Interop/bin/BuildRelease/JdkInfo.props` exist. (*Previously*, the Release configuration would use the `…/BuildDebug/JdkInfo.props` file.) Unfortunately, xamarin-android wasn't updated accordingly. As such, if *only* the Release configuration is built -- not Debug *and* Release, as Jenkins does -- then xamarin-android doesn't build: xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.csproj: error : …/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.csproj: Java.Interop.targets: Project file could not be imported, it was being imported by …/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.csproj: …/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop.targets could not import "$(JNIEnvGenPath)\JdkInfo.props" `$(JNIEnvGenPath)` is now `bin/Build$(Configuration)`, whereas before it was always `bin/BuildDebug`, so the above error occurs because `external/Java.Interop/bin/BuildRelease/JdkInfo.props` doesn't exist. Fix the `make prepare` target so that *all* `$(CONFIGURATIONS)` values are configured for Java.Interop, not just the Debug configuration. This should allow Release-only builds to work. [ji7]: https://github.com/xamarin/Java.Interop/commit/7d9d72a538c4d7b9058e8e002c7c7138c16f425b
2017-09-07 03:22:24 +03:00
true
[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
[build] Fix `make prepare` ordering (#937) @clancey was trying to build xamarin-android, which failed: $ make prepare ./build-tools/scripts/generate-os-info Configuration.OperatingSystem.props xbuild /p:Configuration=Debug /p:_DebugFileExt=.pdb build-tools/dependencies/dependencies.mdproj ... warning : Referenced Project ../../external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Xamarin.Android.Tools.AndroidSdk.csproj not found, ignoring. ... Xamarin.Android.BuildTools.PrepTasks/JdkInfo.cs(9,23): error CS0234: The type or namespace name 'Tools' does not exist in the namespace 'Xamarin.Android' (are you missing an assembly reference?) The problem is that `make prepare-deps`, which builds `build-tools/dependencies/dependencies.mdproj`, implicitly builds `build-tools/xa-prep-tasks/xa-prep-tasks.csproj`, which in turn depends on `external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Xamarin.Android.Tools.AndroidSdk.csproj`, which is only reliably created by `make prepare-external`s `git submodule update --init --recursive`. Unfortunately, `make prepare-external` wasn't invoked until *after* `make prepare-deps`, meaning there is no way for `make prepare` to actually work on a clean install! (This works on Jenkins because Jenkins automatically checks out all submodules, so it never encounters this "clean checkout" scenario.) Reorder the targets that `make prepare` executes so that `make prepare-external` is run *before* `make prepare-deps`, ensuring that git submodules exist before we attempt to use them.
2017-10-17 18:14:59 +03:00
prepare-deps: prepare-external
./build-tools/scripts/generate-os-info Configuration.OperatingSystem.props
$(MSBUILD) $(MSBUILD_FLAGS) build-tools/dependencies/dependencies.mdproj
prepare-props: prepare-deps
[structure] Rework installation directory structure (#704) Context: https://github.com/xamarin/xamarin-android/pull/253#discussion_r82862993 The *intention* is that Jenkins-produced `oss-xamarin.android*.zip` artifacts be usable on Windows, so that side-by-side testing can be performed without replacing the system installation. Usage is in [UsingJenkinsBuildArtifacts.md](Documentation/UsingJenkinsBuildArtifacts). This isn't *entirely* the case. It was *apparently* the case at the time of commit 87ca2737, but things have bitrotten since. For example, following the 87ca2737 instructions would currently result in an XA0020 `Could not find monodroid` error, because `class-parse.exe` wasn't where Windows expects it to be (it was in `lib/mandroid`, not `lib/xbuild/Xamarin/Android`). This needs to be fixed. Additionally, PR #253 mentions that, for filesystem organization, it would be useful if the macOS/Linux directory structure -- `$prefix/bin`, `$prefix/lib/mandroid`, `$prefix/lib/xbuild/Xamarin/Android`, `$prefix/lib/xbuild-frameworks` -- more closely resembled the Windows directory structure of `$MSBuild` and `$ReferenceAssemblies` (as seen in `.vsix` files). This would turn macOS/Linux into using `$xa_prefix/xbuild` and `$xa_prefix/xbuild-frameworks` directories. `$prefix/bin` would only contain `xabuild`. What is currently in `$prefix/lib/mandroid` would be merged with `$xa_prefix/xbuild/Xamarin/Android`. `$xa_prefix` would `$prefix/lib/xamarin.android`. This would turn the current macOS structure: $prefix/bin/xabuild $prefix/bin/generator $prefix/bin/cross-arm $prefix/lib/mandroid/generator.exe $prefix/lib/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets Into: $prefix/bin/xabuild $prefix/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll $prefix/lib/xamarin.android/xbuild/Xamarin/Android/generator.exe $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets $prefix/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/cross-arm Other notes: * The `bundle-*.zip` filename has been has been changed to include a *hash* of the contents of various files, in particular `build-tools\mono-runtimes.*`. This was instigated via a conversation with @kumpera about making the filename more "idiot-proof": `mono-runtimes.props` contains *compiler flags*, and if any of those change, then *logically* the bundle should differ as well, as the mono runtimes may differ in significant ways. In theory, the `-vXX` version should be used to track this, but this is a manual change, easy to overlook. The new `-hHASH` part of the filename should be more automagic. The new `<HashFileContents/>` task in `xa-prep-tasks.dll` is responsible for creating the hash value. * `Configuration.Java.Interop.Override.props` was moved into `build-tools/scripts`, because that would cleanup the root directory a bit. * OS-specific binaries are now placed into `$prefix/lib/xamarin.android/xbuild/Xamarin/Android/$(HostOS)`. On a theoretical plus side, this means that the same build directory can contain OS-specific binaries for multiple operating systems. (I don't know if anyone shares a build tree between e.g. macOS and Linux, but if anyone *does*...) Unfortunately this requires a workaround for an `xbuild` bug: `%(_LlvmRuntime.InstallPath)` and `%(_MonoCrossRuntime.InstallPath)` *cannot* use MSBuild properties, e.g. `<InstallPath>$(HostOS)/</InstallPath>` doesn't work as desired; it's instead treated literally. Special-case `%(InstallPath)` until we fully migrate to MSBuild. * `$(MonoAndroidToolsDirectory)` should be considered *dead*, along with `$(MonoAndroidBinDirectory)`, as these should now *always* be the same directory as where `Xamarin.Android.Build.Tasks.dll` is located, or a `$(HostOS)` sub-directory. * `Xamarin.ProjectTools.csproj` needed to be updated to ensure that the build order was correct. * Remove all `[Obsolete]` and unreferenced members from `Xamarin.Android.Build.Utilities.dll`. There's too much in there, and it makes my head hurt trying to understand the interrelationships between it all. If it's not used, it's gone. * The changes to `src/monodroid/jni/Android.mk` are...weird. The removal of `-I$(topdir)/libmonodroid/zip`/etc. is to reduce use of non-existent paths, as `$(topdir)` isn't defined, so that's *actually* `-I/libmonodroid/zip`, which is nonsensical. So far, so good. What's *odd* is the addition of `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`: This is needed so that `external/mono/support/zlib-helper.c` exports `CreateZStream` and related symbols, otherwise we get a unit test failure in `GzipStreamTest.Compression` due to an `EntryPointNotFoundException`, because `CreateZStream` isn't exported/public. What's odd here is that I don't understand what caused this behavior to change. Previous builds exported `CreateZStream`, otherwise the tests would fail, and I don't understand how any of the other changes in this PR would be at fault, though that's certainly the most plausible explanation. Regardless, `-Ijni` *first* (due to adding `$(LOCAL_PATH)` to `$(LOCAL_C_INCLUDES)`) is the desired behavior, so that `jni/config.h` is included, thus ensuring that `MONO_API` has the required definition when building `zlib-helper.c`.
2017-07-28 16:36:32 +03:00
cp build-tools/scripts/Configuration.Java.Interop.Override.props external/Java.Interop/Configuration.Override.props
cp $(call GetPath,MonoSource)/mcs/class/msfinal.pub .
[build] Auto-Provision Dependencies (#447) The #runtime team is requesting that Xamarin.Android support "auto-provisioning": the ability to track dependency *versions*, and if there is a "version mismatch", *install* a dependency that satisfies the minimum. The primary use case is Mono itself: there is a desire to build xamarin-android *itself* against mono/master, to see what breaks. (Does the C# compiler break things? Does the JIT hang? etc.) Extend the existing `@(RequiredProgram)` infrastructure to attempt to support this: * `%(RequiredProgram.MinimumVersion)`: The minimum program version that is supported. * `%(RequiredProgram.MaximumVersion)`: The maximum program version that is supported. * `%(RequiredProgram.CurrentVersionCommand)`: A command to execute to obtain the current program version. Defaults to `%(RequiredProgram.Identity) --version`. * `%(RequiredProgram.MinimumUrl)`: URL to download "something" to use to obtain a version of the program that satisfies `%(MinimumVersion)`. * `%(RequiredProgram.Install)`: Command to execute which installs the minimum version of the program. `%(RequiredProgram.CurrentVersionCommand)`, `%(RequiredProgram.MinimumUrl)`, and `%(RequiredProgram.Install)` can all be "overridden" for platform-specific values by prefixing the value with `$(HostOSName)` and/or `$(HostOS)`. Thus, macOS-specific values can be stored into e.g. `%(RequiredProgram.DarwinMinimumUrl)` and `%(RequiredProgram.DarwinInstall)`. Auto-Provisioning is controlled by the new `$(AutoProvision)` property, which can be provided in `Configuration.Override.props`. It defaults to `False`. If the `$(AutoProvisionUsesSudo)` MSBuild property is True, then `sudo` is used to invoke all install commands.
2017-02-16 19:37:28 +03:00
prepare-msbuild: prepare-props
ifeq ($(USE_MSBUILD),1)
[build] Support building *from clean* with `msbuild` (#355) Context: https://github.com/xamarin/xamarin-android/commit/b1f1370896047966319655ea2b19a6a243719742 Context: https://github.com/xamarin/xamarin-android/commit/452d405e32e0b92dc1958f8ee3b101aae35ec859 Context: https://github.com/xamarin/xamarin-android/commit/9a50c668a4466915f07efd2fd0794b39ed84ba8c Context: https://github.com/xamarin/xamarin-android/commit/b89dc15d9bfeb2e6e03efbeb8e50895c372dbc5b The `xamarin-android` repo [can't be built with msbuild][0]: src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj(348,3): error MSB4019: The imported project ".../bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. ... src/Mono.Posix/Mono.Posix.csproj(236,3): error MSB4019: The imported project ".../bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. ... src/Mono.Data.Sqlite/Mono.Data.Sqlite.csproj(183,3): error MSB4019: The imported project ".../bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. Plus various other similar and different errors. This is a bit of a problem as I'd like to build everthing with MSBuild, particularly with a view toward future/eventual IDE integration, but if things don't build with MSBuild *at all*... That's a bit of a pickle. But first, about those above errors...what's going on? The short version is that `xbuild` has a "feature" that `msbuild` lacks, and it's a feature that has been inadvertently relied on: `xbuild` loads projects lazily. This requires elaboration. :-) A "solution" is a graph of projects with various dependencies, as specified by the `.sln` file and MSBuild `@(ProjectReference)` items. Reading this graph requires parsing the e.g. `.csproj` files to read the `@(ProjectReference)` items to construct the graph so that projects can be built in the proper order. This is where `xbuild` and `msbuild` appear to differ: * `xbuild` appears to use a "normal" XML parser to read project files when constructing the project graph. * `msbuild` appears to "fully load" the project files into an internal object instance for further processing. The difference between these approaches is visible when a project file `<Import/>`s a file...which doesn't (yet!) exist. Case in point: `Mono.Posix.csproj` needs to be a "normal" Xamarin.Android project file, using the normal Xamarin.Android build process, so that Android native libraries can be embedded into `Mono.Posix.dll` for use by end-user applications. To do so, it needs to `<Import/>` the Xamarin.Android MSBuild targets: <Import Project="$(OutputPath)\..\..\..\xbuild\Xamarin\Android\Xamarin.Android.CSharp.targets" /> In a clean build tree -- e.g. immediately after checkout -- *the above file does not exist*. `Xamarin.Android.CSharp.targets` is installed into the above directory by `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj` (via `%(None.CopyToOutputDirectory)` set to `PreserveNewest`), which means that `Xamarin.Android.CSharp.targets` won't be available for processing by `Mono.Posix.csproj` until *after* `Xamarin.Android.Build.Tasks.csproj` has been built. Under `xbuild`, this Just Works™: `Mono.Posix.csproj` has a `@(ProjectReference)` to `Xamarin.Android.Build.Tasks.csproj`, so `xbuild` loads `Mono.Posix.csproj` into an XML parser, extracts the `@(ProjectReference)` items, and continues on its merry way *without* evaluating the `<Import/>`s within `Mono.Posix.csproj`. Under `msbuild`, this fails horrifically: `Xamarin.Android.CSharp.targets` isn't in the expected directory, and `msbuild` reports an MSB4019 error. MSBuild attempts to continue (why?!), but nothing can actually build sanely. There are two plausible fixes for this scenario: 1. Add a layer of indirection! 2. Abuse `make prepare`. For option (1), see e.g. (b1f13708) `build-tools/mono-runtimes/mono-runtimes.mdproj` and `build-tools/mono-runtimes/mono-runtimes.targets`, in which the `Build` target is altered so that nothing is done if the outputs already exist; otherwise the `<MSBuild/>` task is used to invoke the `ForceBuild` target. A similar thing could plausibly be done for `Mono.Posix.csproj`, by creating a "proxy" project which is used by `@(ProjectReference)` for determining the dependency graph, and the "proxy" project then delegates to the "real" project. I don't personally like this idea, as I'm not sure what it looks like from the IDE. There would now be two projects instead of one for *each* MSB4019 error, and there are *10* MSB4019 errors (now). Option (2) involves altering `make prepare` so that when `msbuild` is used, we explicitly build a set of projects *before* `Xamarin.Android.sln` is built. This allows us to manually intervene and build projects in an order which will appease `msbuild`s "eager" resolving and loading of all referenced files. This also works, is much simpler, and means we *don't* need to introduce 10 additional project files simply to appease MSBuild. Perhaps not surprisingly, that conceptual change -- the introduction of `make prepare-msbuild` -- is *tiny* in this patch. Then we have other `xbuild`-vs-`msbuild`-isms. Bump to Java.Interop/65a0157f, as that commit is needed to build cleanly with `msbuild`. `android-toolchain.targets` can't use `$(_Toolchain)` because then `%(_NdkToolchain.Identity)` isn't properly batched into the `<Exec/>`. The result is a build error when invoking `make-standalone-toolchain.sh` when it's invoked an additional time, but without a corresponding `@(_NdkToolchain)`, so the command line is just completely bizarro and fails. `Mono.Data.Sqlite.csproj` and `Mono.Posix.csproj` need to set `$(NoStdLib)` to True so that MSBuild doesn't add the *system* `mscorlib.dll` when building the assemblies. When `$(NoStdLib)` is False, the `<Csc/>` task is executed referencing *two* `mscorlib.dll` assemblies, and things go badly from there. `System.Drawing.Primitives.csproj` *does* properly set `$(NoStdLib)` to True, but then it *also* set it to False in the Debug and Release sections (?!). Remove the extra -- and wrong! -- overrides. `Xamarin.Android.Build.Tasks.targets` needs to provide `$(CscToolPath)` and `$(CscToolExe)` to the `<Csc/>` task. Otherwise, `msbuild` defaults to trying to invoke `csc.exe`, which doesn't exist on mono 4.6, breaking the `_BuildMonoSymbolicate` target. Finally, `System.Runtime`... We have a bit of a history of adding a `@(Reference)` to `System.Runtime` (452d405e) and removing that same reference (9a50c668, b89dc15d). The short version is that `xbuild` errors if `System.Runtime` is referenced, while `msbuild` errors if `System.Runtime` *isn't* referenced. #facepalm "Fix" this by altering `$(MSBUILD_FLAGS)` so that when building with `xbuild` the `$(_XABuildingWithXBuild)` property is True. We can then make the `@(Reference)`s to `System.Runtime` conditional on our *not* building with `xbuild`. (This might mean we don't build from the IDE until it uses `msbuild`; I haven't tested this.) [0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-msbuild/87/consoleText
2017-01-10 19:16:40 +03:00
for proj in $(MSBUILD_PREPARE_PROJS); do \
$(MSBUILD) $(MSBUILD_FLAGS) "$$proj"; \
done
endif # msbuild
[build] Add `make prepare-image-dependencies` target. (#979) We are investigating building Xamarin.Android atop Visual Studio Team System (VSTS) in addition to our current Jenkins setup, and one of the issues we're running into is "bootstrapping": VSTS is configured to create a "fresh" VM for each build. **Pro**: It should allow builds to be more reliable, as previous build artifacts won't be present, and thus won't cause/hide errors. **Con**: *Previous build artifacts are not present*. Previous build artifacts such as *downloading and extracting* the Android NDK & SDK, using `brew` to install dependencies, building MXE... Ensuring that the dependencies are installed through `make prepare` can be quite time consuming. What we want is a way to ensure that the "build image" -- *what's already installed* when the VM boots -- contains all of our desired dependencies. Furthermore, we *don't* want to have the responsible parties checkout and build xamarin-android in order to determine what the dependencies should be. Attempt to square this circle by adding a new `make prepare-image-dependencies` target, which processes `@(AndroidSdkItem)`, `@(AndroidNdkItem)`, `@(AntItem)`, and `@(RequiredProgram)` to create a `prepare-image-dependencies.sh` script which will download and install the required dependencies. The generated shell script does *not* take the state of the machine running `make prepare-image-dependencies` into consideration. This allows the target to be executed on one machine, and the output run on another. $ make prepare-image-dependencies # creates `prepare-image-dependencies.sh` *Note*: `make prepare-image-dependencies` does not currently deal with MXE. (Building MXE on the VSTS VM is *very* time consuming, so it's something we need to take care of. It is not *yet* dealt with.)
2017-10-27 03:12:18 +03:00
prepare-image-dependencies:
$(MSBUILD) $(MSBUILD_FLAGS) build-tools/scripts/PrepareImageDependencies.targets /t:PrepareImageDependencies \
/p:AndroidSupportedHostJitAbis=mxe-Win32:mxe-Win64
[build] Install mono in `make prepare-image-dependencies` I have been told that the `prepare-image-dependencies.sh` script should also install `mono`, to ensure that the required mono exists. Add a `@PKG_URLS@` variable to `prepare-image-dependencies.sh.in` to support downloading and installing our minimum specified mono version. Additionally, I discovered that `xbuild` bugs are still around; I just keep forgetting their specifics. Case in point: [Jenkins build #712][xa712] uploaded [`prepare-image-dependencies.sh`][sh], and it's not good: [xa712]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/ [sh]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/712/Azure/processDownloadRequest/xamarin-android/prepare-image-dependencies.sh https://dl.google.com/android/repository/build-tools_r26.0.1-macosx.zip sdk/build-tools\$(XABuildToolsFolder) ... https://dl.google.com/android/repository/android-15_r03.zip sdk/platforms\android-15 MSBuild properties contained within item metadata -- specifically `%(AndroidSdkItem.DestDir)` -- aren't fully expanded, resulting in the above value of `$(XABuildToolsFolder)`, which *should* be `26.0.1`. Similarly, some install paths are using `\` (backslash) when they should contain `/` (forward slash). Jenkins has been updated to explicitly use `msbuild`: $ make prepare-image-dependencies MSBUILD=msbuild However, `\r` characters now appear in `prepare-image-dependencies.sh`. Fix this by having the `PrepareImageDependencies` target emit the MSBuild-generated file into an intermediate file, then fix it up using **tr**(1). Finally, correct the `brew install` command so that any errors are ignored, for if a brew package is already installed, re-installing it will result in an error.
2017-10-27 23:34:28 +03:00
cat bin/Build$(CONFIGURATION)/prepare-image-dependencies.sh | tr -d '\r' > prepare-image-dependencies.sh
[build] Add `make prepare-image-dependencies` target. (#979) We are investigating building Xamarin.Android atop Visual Studio Team System (VSTS) in addition to our current Jenkins setup, and one of the issues we're running into is "bootstrapping": VSTS is configured to create a "fresh" VM for each build. **Pro**: It should allow builds to be more reliable, as previous build artifacts won't be present, and thus won't cause/hide errors. **Con**: *Previous build artifacts are not present*. Previous build artifacts such as *downloading and extracting* the Android NDK & SDK, using `brew` to install dependencies, building MXE... Ensuring that the dependencies are installed through `make prepare` can be quite time consuming. What we want is a way to ensure that the "build image" -- *what's already installed* when the VM boots -- contains all of our desired dependencies. Furthermore, we *don't* want to have the responsible parties checkout and build xamarin-android in order to determine what the dependencies should be. Attempt to square this circle by adding a new `make prepare-image-dependencies` target, which processes `@(AndroidSdkItem)`, `@(AndroidNdkItem)`, `@(AntItem)`, and `@(RequiredProgram)` to create a `prepare-image-dependencies.sh` script which will download and install the required dependencies. The generated shell script does *not* take the state of the machine running `make prepare-image-dependencies` into consideration. This allows the target to be executed on one machine, and the output run on another. $ make prepare-image-dependencies # creates `prepare-image-dependencies.sh` *Note*: `make prepare-image-dependencies` does not currently deal with MXE. (Building MXE on the VSTS VM is *very* time consuming, so it's something we need to take care of. It is not *yet* dealt with.)
2017-10-27 03:12:18 +03:00
[build] Add `make jenkins` target. (#116) The `make jenkins` [^0] target is for use by Continuous Integration machines, to build *everything* [^1]. This is expected to take an eternity. Think *hours*. $ time make jenkins ... real 130m11.608s user 97m22.220s sys 18m20.522s Of particular note is that the above "everything" includes *Release configuration builds* of everything, which is something that didn't actually work before. (Oops.) Bump Java.Interop so that it supports building the Release configuration, update Xamarin.Android.sln so that all required projects are part of the Release configuration, and update Xamarin.Android.Build.Tasks.csproj so that `JCW_ONLY_TYPE_NAMES` isn't defined, as this was preventing compilation. Fix **strip**(1) use: `mono-runtimes.targets` was trying to use `strip -S` on macOS, but the value of `%(_MonoRuntime.Strip)` was quoted, and thus attempted to execute `"strip -S" ...`, which failed. Move the `-S` into a new `%(_MonoRuntime.StripFlags)` value. Fixup `mono-runtimes.targets` and related files so that `$(MonoSourceFullPath)` is used instead of a relative path. This helps alleviate the "mental math" of determining the relative path to the Mono checkout. Plus, the Mono checkout is supposed to be overridable, e.g. commit d205cab2, and using `$(MonoSourceFullPath)` supports that. Download and install `android.jar` for all supported API levels. Fix the `Mono.Android.csproj` build so that `Mono.Android.dll` is stored in a per-API-level intermediate directory. Otherwise, if e.g. API-10 is built after API-23, the API-23 version will be installed, but the JCW build will fail. Additionally, API-24 requires using `javac -source 1.8 -target 1.8`, not 1.6. Fix `Mono.Android/metadata` to use the correct `merge.SourceFile` filename of `Profiles/api-24.xml.in`. Without that fix, API-24 won't build because `NumericShaper.GetContextualShaper()` is emitted twice, and the C# compiler doesn't like that. Disable use of `-lz` when building for Windows. Windows doesn't contain a `Z.DLL` to link against. [^0]: https://en.wikipedia.org/wiki/Leeroy_Jenkins [^1]: https://www.youtube.com/watch?v=hooKVstzbz0
2016-07-18 15:42:39 +03:00
include build-tools/scripts/BuildEverything.mk
include tests/api-compatibility/api-compatibility.mk
[build] Add `make jenkins` target. (#116) The `make jenkins` [^0] target is for use by Continuous Integration machines, to build *everything* [^1]. This is expected to take an eternity. Think *hours*. $ time make jenkins ... real 130m11.608s user 97m22.220s sys 18m20.522s Of particular note is that the above "everything" includes *Release configuration builds* of everything, which is something that didn't actually work before. (Oops.) Bump Java.Interop so that it supports building the Release configuration, update Xamarin.Android.sln so that all required projects are part of the Release configuration, and update Xamarin.Android.Build.Tasks.csproj so that `JCW_ONLY_TYPE_NAMES` isn't defined, as this was preventing compilation. Fix **strip**(1) use: `mono-runtimes.targets` was trying to use `strip -S` on macOS, but the value of `%(_MonoRuntime.Strip)` was quoted, and thus attempted to execute `"strip -S" ...`, which failed. Move the `-S` into a new `%(_MonoRuntime.StripFlags)` value. Fixup `mono-runtimes.targets` and related files so that `$(MonoSourceFullPath)` is used instead of a relative path. This helps alleviate the "mental math" of determining the relative path to the Mono checkout. Plus, the Mono checkout is supposed to be overridable, e.g. commit d205cab2, and using `$(MonoSourceFullPath)` supports that. Download and install `android.jar` for all supported API levels. Fix the `Mono.Android.csproj` build so that `Mono.Android.dll` is stored in a per-API-level intermediate directory. Otherwise, if e.g. API-10 is built after API-23, the API-23 version will be installed, but the JCW build will fail. Additionally, API-24 requires using `javac -source 1.8 -target 1.8`, not 1.6. Fix `Mono.Android/metadata` to use the correct `merge.SourceFile` filename of `Profiles/api-24.xml.in`. Without that fix, API-24 won't build because `NumericShaper.GetContextualShaper()` is emitted twice, and the C# compiler doesn't like that. Disable use of `-lz` when building for Windows. Windows doesn't contain a `Z.DLL` to link against. [^0]: https://en.wikipedia.org/wiki/Leeroy_Jenkins [^1]: https://www.youtube.com/watch?v=hooKVstzbz0
2016-07-18 15:42:39 +03:00
run-all-tests:
$(MSBUILD) $(MSBUILD_FLAGS) $(TEST_TARGETS) /t:RunAllTests
$(MAKE) run-api-compatibility-tests
[tests] Add Configuration info to test names Context: 0077d151 Context: d1d9820a A "funny" thing happened when commit e9daf5ea didn't build on Jenkins: I realized that not all tests were run in all configurations. From commit d1d9820a: > Why are some tests Debug-only and some aren't? The answer: time, primarily. Why run tests multiple times, when they can be potentially time-consuming? While tests can be slow, they're not always *that* slow -- except for `Xamarin.Android.Build.Tests` and the BCL tests -- and even there, program behavior can alter between Debug and Release configurations. See in particular commit 0077d151, in which the BCL tests are run only in the Debug configuration because tests *failed* when run in the Release configuration. The desire, then, is to run *all* tests in both Debug and Release configurations. Yes, it'll take longer! So what! (Within reason: `Xamarin.Android.Build.Tests` should only be run once!) However, this raises two problems: 1. Filename collisions 2. Jenkins unit test display Until now, all tests wrote files into a filename that didn't include the Configuration, e.g. `TestResult-Mono.Android_Tests.xml`. If we did run these tests twice, the second test invocation would overwrite the first test invocation. This isn't desirable. Then there's the display on Jenkins: if we did have e.g. `TestResult-Mono.Android_Tests-Debug.xml` and `TestResult-Mono.Android_Tests-Release.xml`, how will Jenkins display that information? I haven't tested, but I would assume that one of two things will occur, assuming reasonable Jenkins behavior: 1. Each test will be listed twice, e.g. ApplicationContextIsApp ApplicationContextIsApp 2. They'll be "merged" into a single entry. Neither of these behaviors is desirable: if Debug passes but Release fails, we need to be able to differentiate between them. Neither of these possible renderings allows us to tell which configuration fails. Solve both of these problems by introducing a new `<RenameTestCases/>` task. This task takes three values of importance: ```xml <RenameTestCases Configuration="CONFIGURATION" SourceFile="SOURCE" DestinationFolder="DESTINATION" /> ``` The `<RenameTestCases/>` task will read in `SOURCE`, and if `SOURCE` is an XML file which we determine is NUnit2-formatted XML (root element of `<test-case/>`), we will update every `//test-case/@name` value so that it ends with ` / CONFIGURATION`. The updated XML is then written to the `DESTINATION` directory, with a filename that contains `CONFIGURATION`, and `SOURCE` is deleted. Thus, if we have a Debug-configuration `TestResult-Mono.Android_Tests.xml` file with XML fragment: ```xml <test-case name="Mono.Android_Tests, Android.AppTests.ApplicationTest.ApplicationContextIsApp" ... /> ``` then `<RenameTestCases/>` will create the file `TestResult-Mono.Android_Tests-Debug.xml` file with XML fragment: ```xml <test-case name="Mono.Android_Tests, Android.AppTests.ApplicationTest.ApplicationContextIsApp / Debug" ... /> ``` This allows us to run tests in both Debug and Release configurations while not inadvertently overwriting the `TestResults*.xml` files that Jenkins reads, and ensuring that the Jenkins test result output is rendered in a meaningfully useful fashion. Aside: when updating `//test-case/@name`, the resulting value *cannot* end in `)`. If it does, then the `(root)` package name issue fixed in commit 23b2642e reappears for the `generator` unit tests. **Completely random aside about the state of `xbuild`**: A development version of `<RenameTestCases/>` was "saner", using `ITaskItem[]` and not string: ```csharp partial class RenameTestCases { public ITaskItem[] SourceFiles {get; set;} // vs. // public string SourceFile {get; set;} } ``` The problem is that the above, while entirely reasonable, did not work at all correctly with `xbuild`: ```xml <RenameTestCases SourceFiles="%(TestApk.ResultsPath)" /> ``` Under `xbuild`, MSBuild properties would not be expanded, e.g. `RenameTestCases.SourceFiles` would get a "bizarro" value of e.g. `$(OutputPath)Mono.Android_Tests-Signed.apk`, which is *useless* and would result in `FileNotFoundException`s. MSBuild proper, of course, worked as desired. TODO: Once this is merged, update the Jenkins Configuration page so that instead of: make run-all-tests V=1 || exit 1 it instead runs both Debug and Release configuration tests: make run-all-tests SKIP_NUNIT_TESTS=1 V=1 || exit 1 make run-all-tests CONFIGURATION=Release V=1 || exit 1 Note that `$(SKIP_NUNIT_TESTS)` is specified so that we only run the lengthy (1+hr!) `Xamarin.Android.Build.Tests` tests in the Release configuration, not the Debug + Release configurations.
2017-10-11 00:59:42 +03:00
[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
clean:
[Xamarin.Android-Tests] Split out "full" apps (#146) We're trying to get [`make jenkins`][0] working on Jenkins, and [it's failing][1], as one might expect when a particular repo and associated build system has never been run on Jenkins before: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? This error occurs while building `src/Mono.Android/Test/Mono.Android-Tests.csproj`, and happens because the `Xamarin.Android.NUnitLite.dll` assembly isn't referenced... because it isn't *found*: Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved This returns us to a long-standing issue which I thought was mentioned in a commit somewhere, but I can't find at present: MSBuild doesn't support updating the assembly resolution directories *while MSBuild is running*. For example, we build `Xamarin.Android.NUniteLite.dll` into `bin/$(Configuration/lib/xbuild-frameworks/MonoAndroid/v1.0`, but "normal Xamarin.Android referencing projects" don't use a `@(ProjectReference)` to `Xamarin.Android.NUnitLite.csproj`, but instead a `@(Reference)` to the assembly: <!-- src/Mono.Android/Test/Mono.Android-Tests.csproj --> <Reference Include="Xamarin.Android.NUnitLite" /> The *requirement* for a "proper" Xamarin.Android SDK install is that `Xamarin.Android.NUnitLite.dll` can be found through a normal `@(Reference)`. In order to satisfy this requirement, we need to tell MSBuild where to find it, which can be with `xbuild` via the `$MSBuildExtensionsPath` and `$XBUILD_FRAMEWORK_FOLDERS_PATH` *environment variables*. *Environment variables*. MSBuild doesn't provide a way to update environment variables, short of writing a new Task which calls `Environment.SetEnvironmentVariable()`, and while [this works][2], it doesn't *actually* work [^3]. The short of all this is that it isn't possible, *within a single `xbuild` invocation*, to both build the Xamarin.Android SDK "environment" *and use that environment* as intended for "normal" apps. The fix, as is often the case, is to bend with the wind. Instead of requiring the impossible, move `src/Mono.Android/Test/Mono.Android-Tests.csproj` into a *new* `Xamarin.Android-Tests.sln` solution, *out of* `Xamarin.Android.sln`. This allows building `Xamarin.Android.sln` without error in a pristine environment -- that is, one that doesn't already have a system-wide Xamarin.Android install -- and separately building the tests by using `tools/scripts/xabuild`, which *can* export environment variables to manipulate `xbuild` behavior so that things Just Work™. Building `Mono.Android-Tests.csproj` and similar projects (`HelloWorld.csproj`!) can be done by using the new `make all-tests` make target. [0]: https://github.com/xamarin/xamarin-android/commit/a16673d3eb2c4945c3a74f5f8154603d7658fc9a [1]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/20/console [2]: https://github.com/xamarin/xamarin-android/pull/147 [^3]: [PR #147][2] isn't viable because of [xbuild's `AsssemblyResolver`][4]. There's no way to clear/invalidate `target_framework_cache`. The idea of PR #147 was to "hack things up" so that `Xamarin.Android.NuniteLite.dll` would be properly resolved during the build of `Mono.Android-Tests.csproj` *when building everything*. The problem is *this can't work*, because `xbuild` has a "target framework cache," with no way to invalidate it, and the cache is populated the first time the target framework is used. Due to build ordering issues, this first use is *before* `Xamarin.Android.NunitLite.dll` was built, and thus it doesn't exist in the cache. The result: Task "ResolveAssemblyReference" .... TargetFrameworkDirectories: /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0 /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/ ... Primary Reference System.Xml Reference System.Xml resolved to /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/System.Xml.dll. CopyLocal = False ... Primary Reference Xamarin.Android.NUnitLite Microsoft.Common.targets: warning : Reference 'Xamarin.Android.NUnitLite' not resolved For searchpath {TargetFrameworkDirectory} Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0, assembly named 'Xamarin.Android.NUnitLite' not found. Considered target framework dir /Volumes/Seagate4TB/work/xamarin-android/bin/Debug/lib/xbuild-frameworks/MonoAndroid/v1.0/Facades/, assembly named 'Xamarin.Android.NUnitLite' not found. ... Consequently, the `mcs` invocation is missing a `/reference:path/to/Xamarin.Android.NUniteLite.dll`, and compilation fails: Android.App/ApplicationTest.cs(9,7): error CS0246: The type or namespace name `NUnit' could not be found. Are you missing an assembly reference? ...plus 29 others... [4]: https://github.com/mono/mono/blob/dd8aadf/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs#L131
2016-08-08 23:46:13 +03:00
$(MSBUILD) $(MSBUILD_FLAGS) /t:Clean Xamarin.Android.sln
tools/scripts/xabuild $(MSBUILD_FLAGS) /t:Clean Xamarin.Android-Tests.sln
[Xamarin.Android.Build.Tasks] First Pass at adding Unit tests for the MSBuild Tasks (#26) This commit adds basic support for the MSBuild Unit Tests. The goal of these tests is to ensure that the build of an android applicaition works consistently on all the supported platforms. The basic layout of a Unit test is as follows [Test] public void BuildReleaseApplication () { var proj = new XamarinAndroidApplicationProject () { IsRelease = true, }; using (var b = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name))) { Assert.IsTrue (b.Build (proj), "Build should have succeeded."); } } It is a standard Unit test. First we create a XamarinAndroidApplicatonProject and set its properties. You can use the proj to add new source files, references, assets, resources and nuget packages. By default you will get a standard "HelloWorld" android application. Once you have the project you will need to create either a Apk or Dll builder via the helper methods CreateApkBuilder CreateDllBuilder CreateApkBuilder will create an apk and by default will execute the `SignAndroidPackage` build target. the CreateDllBuilder will produce a dll. The source files are created in a temp directory relative to the build output of the unit tests. By default this is src/Xamarin.Android.Build.Tasks/UnitTests/Xamarin.Android.Build.Tests/bin/$(Configuraiton)/temp Once you have a builder you can then call Build passing in the project. There are also methods available for Clean and Save. Running any of these will cause the Unit test to shell out to xbuild/msbuild and attempt to build the project. Test results are written to a build.log file. If a unit test passes then the test directory is removed. If a test fails the directory and the build.log will be left in place for investigation.
2016-05-12 21:54:03 +03:00
distclean:
# It may fail if we're cleaning a half-built tree, no harm done if we ignore it
-$(MAKE) clean
git clean -xdff
git submodule foreach git clean -xdff
run-nunit-tests:
ifeq ($(SKIP_NUNIT_TESTS),)
$(MSBUILD) $(MSBUILD_FLAGS) $(TEST_TARGETS) /t:RunNUnitTests
[tests] Add Configuration info to test names Context: 0077d151 Context: d1d9820a A "funny" thing happened when commit e9daf5ea didn't build on Jenkins: I realized that not all tests were run in all configurations. From commit d1d9820a: > Why are some tests Debug-only and some aren't? The answer: time, primarily. Why run tests multiple times, when they can be potentially time-consuming? While tests can be slow, they're not always *that* slow -- except for `Xamarin.Android.Build.Tests` and the BCL tests -- and even there, program behavior can alter between Debug and Release configurations. See in particular commit 0077d151, in which the BCL tests are run only in the Debug configuration because tests *failed* when run in the Release configuration. The desire, then, is to run *all* tests in both Debug and Release configurations. Yes, it'll take longer! So what! (Within reason: `Xamarin.Android.Build.Tests` should only be run once!) However, this raises two problems: 1. Filename collisions 2. Jenkins unit test display Until now, all tests wrote files into a filename that didn't include the Configuration, e.g. `TestResult-Mono.Android_Tests.xml`. If we did run these tests twice, the second test invocation would overwrite the first test invocation. This isn't desirable. Then there's the display on Jenkins: if we did have e.g. `TestResult-Mono.Android_Tests-Debug.xml` and `TestResult-Mono.Android_Tests-Release.xml`, how will Jenkins display that information? I haven't tested, but I would assume that one of two things will occur, assuming reasonable Jenkins behavior: 1. Each test will be listed twice, e.g. ApplicationContextIsApp ApplicationContextIsApp 2. They'll be "merged" into a single entry. Neither of these behaviors is desirable: if Debug passes but Release fails, we need to be able to differentiate between them. Neither of these possible renderings allows us to tell which configuration fails. Solve both of these problems by introducing a new `<RenameTestCases/>` task. This task takes three values of importance: ```xml <RenameTestCases Configuration="CONFIGURATION" SourceFile="SOURCE" DestinationFolder="DESTINATION" /> ``` The `<RenameTestCases/>` task will read in `SOURCE`, and if `SOURCE` is an XML file which we determine is NUnit2-formatted XML (root element of `<test-case/>`), we will update every `//test-case/@name` value so that it ends with ` / CONFIGURATION`. The updated XML is then written to the `DESTINATION` directory, with a filename that contains `CONFIGURATION`, and `SOURCE` is deleted. Thus, if we have a Debug-configuration `TestResult-Mono.Android_Tests.xml` file with XML fragment: ```xml <test-case name="Mono.Android_Tests, Android.AppTests.ApplicationTest.ApplicationContextIsApp" ... /> ``` then `<RenameTestCases/>` will create the file `TestResult-Mono.Android_Tests-Debug.xml` file with XML fragment: ```xml <test-case name="Mono.Android_Tests, Android.AppTests.ApplicationTest.ApplicationContextIsApp / Debug" ... /> ``` This allows us to run tests in both Debug and Release configurations while not inadvertently overwriting the `TestResults*.xml` files that Jenkins reads, and ensuring that the Jenkins test result output is rendered in a meaningfully useful fashion. Aside: when updating `//test-case/@name`, the resulting value *cannot* end in `)`. If it does, then the `(root)` package name issue fixed in commit 23b2642e reappears for the `generator` unit tests. **Completely random aside about the state of `xbuild`**: A development version of `<RenameTestCases/>` was "saner", using `ITaskItem[]` and not string: ```csharp partial class RenameTestCases { public ITaskItem[] SourceFiles {get; set;} // vs. // public string SourceFile {get; set;} } ``` The problem is that the above, while entirely reasonable, did not work at all correctly with `xbuild`: ```xml <RenameTestCases SourceFiles="%(TestApk.ResultsPath)" /> ``` Under `xbuild`, MSBuild properties would not be expanded, e.g. `RenameTestCases.SourceFiles` would get a "bizarro" value of e.g. `$(OutputPath)Mono.Android_Tests-Signed.apk`, which is *useless* and would result in `FileNotFoundException`s. MSBuild proper, of course, worked as desired. TODO: Once this is merged, update the Jenkins Configuration page so that instead of: make run-all-tests V=1 || exit 1 it instead runs both Debug and Release configuration tests: make run-all-tests SKIP_NUNIT_TESTS=1 V=1 || exit 1 make run-all-tests CONFIGURATION=Release V=1 || exit 1 Note that `$(SKIP_NUNIT_TESTS)` is specified so that we only run the lengthy (1+hr!) `Xamarin.Android.Build.Tests` tests in the Release configuration, not the Debug + Release configurations.
2017-10-11 00:59:42 +03:00
endif # $(SKIP_NUNIT_TESTS) == ''
[Mono.Android-Test] Import Mono.Android tests from monodroid/9c5b3712 (#32) Import monodroid/tests/runtime from monodroid/9c5b3712. Add a toplevel `make run-apk-tests` target to "full stack" tests, in which a .apk is created, installed, and executed on an attached Android device. `make run-apk-tests` requires that `adb` be in $PATH, and uses GNU make(1) features, and... Additionally, tools/scripts/xabuild *must* be used to execute the `SignAndroidPackage` target, to ensure that the local/"in tree" assemblies are used. There is no "within xbuild" facility to alter where target framework assemblies are resolved from, i.e no MSBuild properties currently control the resolution order, only environment variables, and MSBuild can't *set* environment variables... The $(ADB_TARGET) variable can be used to control on which target Android device the tests will be installed and executed on: # Install & run tests on *only* connected USB device $ make run-apk-tests ADB_TARGET=-d # Install & run tests on *only* connected emulator $ make run-apk-tests ADB_TARGET=-e # Install & run tests on specified device, listed via `adb devices`. $ make run-apk-tests ADB_TARGET="-s 036533824381cfcb" Sorry potential/future Windows developers. *Running* tests will require manual testing or running on OS X or Linux for now... Note: These tests DO NOT PASS. In fact, they *crash*: $ make run-apk-tests ... Target RunTests: Executing: "$HOME/android-toolchain/sdk/platform-tools/adb" shell am instrument -w Mono.Android_Tests/xamarin.android.runtimetests.TestInstrumentation INSTRUMENTATION_RESULT: shortMsg=Process crashed. INSTRUMENTATION_CODE: 0 $ adb logcat ... E mono : Unhandled Exception: E mono : System.ObjectDisposedException: Cannot access a disposed object. E mono : Object name: 'System.Net.Sockets.Socket'. E mono : at System.Net.Sockets.Socket.ThrowIfDisposedAndClosed () <0xa93923f0 + 0x00054> in <filename unknown>:0 E mono : at System.Net.Sockets.Socket.AcceptAsync (System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8f9680 + 0x0001b> in <filename unknown>:0 E mono : at System.Net.EndPointListener.Accept (System.Net.Sockets.Socket socket, System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8f95d0 + 0x0003f> in <filename unknown>:0 E mono : at System.Net.EndPointListener.ProcessAccept (System.Net.Sockets.SocketAsyncEventArgs args) <0x9b8e0340 + 0x0007f> in <filename unknown>:0 E mono : at System.Net.EndPointListener.OnAccept (System.Object sender, System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8e0310 + 0x00017> in <filename unknown>:0 E mono : at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted (System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8e02c8 + 0x0003b> in <filename unknown>:0 E mono : at System.Net.Sockets.SocketAsyncEventArgs.Complete () <0x9b8e02a0 + 0x0001f> in <filename unknown>:0 E mono : at System.Net.Sockets.Socket.<AcceptAsyncCallback>m__0 (System.IAsyncResult ares) <0x9b8dfd40 + 0x002af> in <filename unknown>:0 E mono : at System.Net.Sockets.SocketAsyncResult+<Complete>c__AnonStorey0.<>m__0 (System.Object _) <0xa892f720 + 0x0002b> in <filename unknown>:0 E mono : at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0xa938f6b8 + 0x0002f> in <filename unknown>:0 E mono : at System.Threading.ThreadPoolWorkQueue.Dispatch () <0xa938e358 + 0x001bb> in <filename unknown>:0 E mono : at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0xa938e1a8 + 0x00007> in <filename unknown>:0 Looks like a Socket and/or ThreadPool bug in mono.
2016-05-16 21:55:13 +03:00
[tests] Run the Java.Interop unit tests (#565) Bump to Java.Interop/master/8d7060d1 Bump to cecil/master/5f93431f We'd like to run the Java.Interop unit tests as part of the xamarin-android `make run-all-tests` target, for two rasons: 1. An extra layer of sanity checking, and 2. Some of the Java.Interop tests require an Android SDK. In particular, the `ParameterFixupTests.XmlDeclaration_FixedUpFromDocumentation()` test from `Xamarin.Android.Tools.Bytecode-Tests.dll` attempts to read Android documentation from `$ANDROID_SDK_PATH` to test parameter name fixups. However, Java.Interop doesn't install -- and thus can't readily require -- an Android SDK, meaning this test is never executed as part of the Java.Interop Jenkins process. That test *can* be readily executed in xamarin-android, as it *does* install an Android SDK, and thus its presence can be assumed. Add a new `make run-ji-tests` target which runs the Java.Interop unit tests, copying their test output into the same directory that the other `TestResult-*.xml` files are placed, so that Jenkins can pick them up for display. Within the `make run-ji-tests` target, export the `ANDROID_SDK_PATH` environment variable so that *all* the `Xamarin.Android.Tools.Bytecode-Tests.dll` tests can execute. Which introduces two problems: 1. The `Xamarin.Android.Tools.Bytecode-Tests.dll` tests require that `$ANDROID_SDK_PATH` contain documentation...which we're not currently installing. 2. The Java.Interop tests still fail, due to parameter name changes, as those tests were originally using API-18 docs. Result: the `ParameterFixupTest` tests fail. :-( Fix this conundrum by instaslling `docs-24_r01.zip` within `$(AndroidSdkDirectory)`, allowing the tests to execute as intended, and by updating to Java.Interop/master/8d7060d1, which updates the expected parameter name output.
2017-04-21 15:11:40 +03:00
run-ji-tests:
$(MSBUILD) $(MSBUILD_FLAGS) $(TEST_TARGETS) /t:RunJavaInteropTests
[Mono.Android-Test] Import Mono.Android tests from monodroid/9c5b3712 (#32) Import monodroid/tests/runtime from monodroid/9c5b3712. Add a toplevel `make run-apk-tests` target to "full stack" tests, in which a .apk is created, installed, and executed on an attached Android device. `make run-apk-tests` requires that `adb` be in $PATH, and uses GNU make(1) features, and... Additionally, tools/scripts/xabuild *must* be used to execute the `SignAndroidPackage` target, to ensure that the local/"in tree" assemblies are used. There is no "within xbuild" facility to alter where target framework assemblies are resolved from, i.e no MSBuild properties currently control the resolution order, only environment variables, and MSBuild can't *set* environment variables... The $(ADB_TARGET) variable can be used to control on which target Android device the tests will be installed and executed on: # Install & run tests on *only* connected USB device $ make run-apk-tests ADB_TARGET=-d # Install & run tests on *only* connected emulator $ make run-apk-tests ADB_TARGET=-e # Install & run tests on specified device, listed via `adb devices`. $ make run-apk-tests ADB_TARGET="-s 036533824381cfcb" Sorry potential/future Windows developers. *Running* tests will require manual testing or running on OS X or Linux for now... Note: These tests DO NOT PASS. In fact, they *crash*: $ make run-apk-tests ... Target RunTests: Executing: "$HOME/android-toolchain/sdk/platform-tools/adb" shell am instrument -w Mono.Android_Tests/xamarin.android.runtimetests.TestInstrumentation INSTRUMENTATION_RESULT: shortMsg=Process crashed. INSTRUMENTATION_CODE: 0 $ adb logcat ... E mono : Unhandled Exception: E mono : System.ObjectDisposedException: Cannot access a disposed object. E mono : Object name: 'System.Net.Sockets.Socket'. E mono : at System.Net.Sockets.Socket.ThrowIfDisposedAndClosed () <0xa93923f0 + 0x00054> in <filename unknown>:0 E mono : at System.Net.Sockets.Socket.AcceptAsync (System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8f9680 + 0x0001b> in <filename unknown>:0 E mono : at System.Net.EndPointListener.Accept (System.Net.Sockets.Socket socket, System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8f95d0 + 0x0003f> in <filename unknown>:0 E mono : at System.Net.EndPointListener.ProcessAccept (System.Net.Sockets.SocketAsyncEventArgs args) <0x9b8e0340 + 0x0007f> in <filename unknown>:0 E mono : at System.Net.EndPointListener.OnAccept (System.Object sender, System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8e0310 + 0x00017> in <filename unknown>:0 E mono : at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted (System.Net.Sockets.SocketAsyncEventArgs e) <0x9b8e02c8 + 0x0003b> in <filename unknown>:0 E mono : at System.Net.Sockets.SocketAsyncEventArgs.Complete () <0x9b8e02a0 + 0x0001f> in <filename unknown>:0 E mono : at System.Net.Sockets.Socket.<AcceptAsyncCallback>m__0 (System.IAsyncResult ares) <0x9b8dfd40 + 0x002af> in <filename unknown>:0 E mono : at System.Net.Sockets.SocketAsyncResult+<Complete>c__AnonStorey0.<>m__0 (System.Object _) <0xa892f720 + 0x0002b> in <filename unknown>:0 E mono : at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0xa938f6b8 + 0x0002f> in <filename unknown>:0 E mono : at System.Threading.ThreadPoolWorkQueue.Dispatch () <0xa938e358 + 0x001bb> in <filename unknown>:0 E mono : at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0xa938e1a8 + 0x00007> in <filename unknown>:0 Looks like a Socket and/or ThreadPool bug in mono.
2016-05-16 21:55:13 +03:00
run-apk-tests:
$(MSBUILD) $(MSBUILD_FLAGS) $(TEST_TARGETS) /t:RunApkTests
include build-tools/scripts/runtime-helpers.mk