Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 65 additions & 41 deletions Documentation/DevelopmentTips.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,44 @@ within `build-tools/mono-runtimes/obj/$(Configuration)/TARGET`.

If you change sources within `external/mono`, a top-level `make`/`xbuild`
invocation may not rebuild those mono native binaries. To explicitly rebuild
*all* Mono runtimes, use the `ForceBuild` target:
*all* Mono runtimes, you must do two things:

1. Ensure that the timestamp of the HEAD commit in `external/mono` has changed.
2. Use the `ForceBuild` target on `mono-runtimes.mdproj`.

Changing the timestamp of the HEAD commit can be done with `git pull`,
`git commit` or `git commit --amend`. *How* the timestamp changes isn't
important; it needs to change in order for `ForceBuild` to do anything.
(This is admittedly annoying for those working directly on Mono; it requires
an "intermediate" commit in order to trigger a rebuild.)

The `ForceBuild` target can be executed as:

# Build and install all runtimes
$ xbuild /t:ForceBuild build-tools/mono-runtimes/mono-runtimes.mdproj

To build Mono for a specific target, run `make` from the relevant directory
and invoke the `_InstallRuntimes` target. For example, to rebuild
Mono for armeabi-v7a:

$ cd build-tools/mono-runtimes
$ make -C obj/Debug/armeabi-v7a
The `ForceBuild` target will build mono for *all* configured architectures,
then invoke the `_InstallRuntimes` target when all the mono's have finished
building; see the `$(AndroidSupportedHostJitAbis)`,
`$(AndroidSupportedTargetAotAbis)`, and `$(AndroidSupportedTargetJitAbis)`
MSBuild properties within [README.md](../README.md). This may not always be
desirable, for example if you're trying to fix a Mono runtime bug for a
specific ABI, and improving turnaround time is paramount.
(Building for all ABIs can be time consuming.)

To build Mono for a specific target, run `make` from the relevant directory,
where the "relevant directory" is the target of interest within
`build-tools/mono-runtimes/obj/$(Configuration)`. When `make` has completed,
invoke the `_InstallRuntimes` target so that the updated native libraries
are copied into `bin/$(Configuration)/lib`, which will allow subsequent
top-level `make` and [`xabuild`](../tools/xabuild) invocations to use them.

For example, to rebuild Mono for armeabi-v7a:

$ make -C build-tools/mono-runtimes/obj/Debug/armeabi-v7a

# This updates bin/$(Configuration)/lib/xbuild/Xamarin/Android/lib/armeabi-v7a/libmonosgen-2.0.so
$ xbuild /t:_InstallRuntimes
$ xbuild /t:_InstallRuntimes build-tools/mono-runtimes/mono-runtimes.mdproj

# How do I rebuild BCL assemblies?

Expand All @@ -44,6 +68,39 @@ Xamarin.Android SDK directory by using the `_InstallBcl` target:
# This updates bin/$(Configuration)/lib/xbuild-frameworks/MonoAndroid/v1.0/ASSEMBLY.dll
$ xbuild build-tools/mono-runtimes/mono-runtimes.mdproj /t:_InstallBcl

# Update Directory

When a Xamarin.Android app launches on an Android device, and the app was
built in the `Debug` configuration, it will create an "update" directory
during process startup, printing the created directory to `adb logcat`:

W/monodroid( 2796): Creating public update directory: `/data/data/Mono.Android_Tests/files/.__override__`

When the app needs to resolve native libraries and assemblies, it will look
for those files within the update directory *first*. This includes the Mono
runtime library and BCL assemblies.

Note that the update directory is *per-app*. The above mentioned `Mono.Android_Tests`
directory is created when running the
[`Mono.Android-Tests.csproj`](../src/Mono.Android/Test/Mono.Android-Tests.csproj)
unit tests.

The update directory is not used in `Release` configuration builds.
(Note: `Release` configuration for the *app itself*, not for xamarin-android.)

For example, if you're working on a mono/x86 bug and need to quickly update
the app on the device to test `libmonosgen-2.0.so` changes:

$ make -C build-tools/mono-runtimes/obj/Debug/x86 && \
adb push build-tools/mono-runtimes/obj/Debug/x86/mono/mini/.libs/libmonosgen-2.0.so \
/data/data/Mono.Android_Tests/files/.__override__

Alternatively, if you're working on an `mscorlib.dll` bug:

$ make -C external/mono/mcs/class/corlib PROFILE=monodroid && \
adb push external/mono/mcs/class/lib/monodroid/mscorlib.dll \
/data/data/Mono.Android_Tests/files/.__override__

# Unit Tests

The `xamarin-android` repo contains several unit tests:
Expand Down Expand Up @@ -129,39 +186,6 @@ For example:
$ adb shell am instrument -e suite Xamarin.Android.LocaleTests.SatelliteAssemblyTests \
-w "Xamarin.Android.Locale_Tests/xamarin.android.localetests.TestInstrumentation"


# Testing Updated Assemblies

The `xamarin-android` repo does not support [fast deployment][fastdep],
which means that, *normally*, if you wanted to e.g. test a fix within
`Mono.Android.dll` you would need to:

[fastdep]: https://developer.xamarin.com/guides/android/under_the_hood/build_process/#Fast_Deployment

1. Build `src/Mono.Android/Mono.Android.csproj`
2. Rebuild your test project, e.g.
`src/Mono.Android/Test/Mono.Android-Tests.csproj`
3. Reinstall the test project
4. Re-run the test project.

The resulting `.apk`s can be quite big, e.g.
`bin/TestDebug/Mono.Android_Tests-Signed.apk` is 59MB, so steps
(2) through (4) can be annoyingly time consuming.

Fortunately, a key part of fast deployment *is* part of the `xamarin-android`:
an "update directory" is created by `libmono-android*.so` during process
startup, in *non*-`RELEASE` builds. This directory is printed to `adb logcat`:

W/monodroid( 2796): Creating public update directory: `/data/data/Mono.Android_Tests/files/.__override__`

Assemblies located within the "update directory" are used *in preference to*
assemblies located within the executing `.apk`. Assemblies can be `adb push`ed
into the update directory:

adb push bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll /data/data/Mono.Android_Tests/files/.__override__

When the process restarts the new assembly will be used.

# Debugging using lldb

Download a precompiled lldb binary from
Expand Down
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ to provide install instructions to obtain the missing dependency, e.g.:
error : Could not find required program '7za'. Please run: brew install 'p7zip'.

<a name="mono-sdk" />

## Mono MDK

Mono 4.4 or later is required to build on [OS X][osx-mono] and Linux.
Expand All @@ -68,6 +69,7 @@ was first added in Mono 4.4.)
[xmlpeek]: https://msdn.microsoft.com/en-us/library/ff598684.aspx

<a name="jdk" />

## Java Development Kit

The Java Development Kit may be downloaded from the
Expand All @@ -76,6 +78,7 @@ The Java Development Kit may be downloaded from the
[download-jdk]: http://www.oracle.com/technetwork/java/javase/downloads/

<a name="autotools" />

## Autotools

Autotools -- including `autoconf` and `automake` -- are required to build
Expand All @@ -88,6 +91,7 @@ If you run into issues regarding `autoconf` or `automake` try to install it with
brew install automake

<a name="xxd" />

## `xxd`

The [xxd][xxd] utility is used to build [src/monodroid](src/monodroid).
Expand All @@ -98,13 +102,23 @@ install it; it may be part of the [**vim-common** package][sid-vim-common].
[sid-vim-common]: https://packages.debian.org/sid/vim-common

<a name="ndk" />

## Android NDK, SDK

To simplify building Xamarin.Android, important pieces of the Android SDK
and Android NDK will be automatically downloaded and installed from
Google's website. Downloaded files are cached locally, by default into
`$(AndroidToolchainCacheDirectory)`. The Android NDK and SDK will be installed by
default into `$(AndroidToolchainDirectory)`.
*Note*: A xamarin-android checkout maintains *its own* Android NDK + SDK
to ensure consistent builds and build behavior, permitting reproducible
builds and providing greater flexibility around when we need to perform
Android SDK + NDK updates. The Android SDK and NDK are maintained by default
via two directories in your home directory:

* `$(AndroidToolchainCacheDirectory)`: Where downloaded files are cached.
Defaults to the `$HOME/android-archives` directory.
* `$(AndroidToolchainDirectory)`: Where the Android NDK and SDK are installed.
Defaults to the `$HOME/android-toolchain` directory.

Developers may use these directories for their own use, but *please* **DO NOT**
update or alter the contents of the `$(AndroidToolchainDirectory)`, as that may
prevent the xamarin-android build from working as expected.

The files that will be downloaded and installed are controlled by
[build-tools/android-toolchain/android-toolchain.projitems][android-toolchain.projitems]
Expand Down Expand Up @@ -156,6 +170,13 @@ Overridable MSBuild properties include:
The default value is `$(HostOS)`, where `$(HostOS)` is based on probing
various environment variables and filesystem locations.
On OS X, the default would be `Darwin`.

* `$(AndroidSupportedTargetAotAbis)`: The Android ABIs for which to build the
Mono AOT compilers. The AOT compilers are required in order to set the
[`$(AotAssemblies)`][aot-assemblies] app configuration property to True.

[aot-assemblies]: https://developer.xamarin.com/guides/android/under_the_hood/build_process/#AotAssemblies

* `$(AndroidSupportedTargetJitAbis)`: The Android ABIs for which to build the
the Mono JIT for inclusion within apps. This is a `:`-separated list of
ABIs to build. Supported values are:
Expand Down Expand Up @@ -329,6 +350,7 @@ For example, to generate `Mono.Android.dll` for API-19 (Android 4.4):
# creates bin\Debug\lib\xbuild-frameworks\MonoAndroid\v4.4\Mono.Android.dll

<a name="Samples" />

# Samples

The [HelloWorld](samples/HelloWorld) sample may be built with the
Expand Down