Cross Platform
Android
iOS
Mac

Build Process

Overview

How does everything fit together?

  1. As a pre-build step, aresgen.exe is run against a res Resources directory in order to generate an Resources.designer.cs file containing Android resource identifiers. See the Resources Design section for more details.
  2. Managed code is compiled into a .NET assembly.
  3. Android-callable wrappers and generated based on the contents of assemblies referenced by the Application project, and the Android callable wrappers are included in the final .apk.

Once the Android .apk package is built and signed, it can be installed onto the emulator or target device.

MSBuild Projects

The Xamarin.Android build process is based on MSBuild, which is also the project file format used by Xamarin Studio and Visual Studio. Ordinarily users will not need to edit the MSBuild files by hand - the IDE creates fully functional projects and updates them with any changes made, and automatically invoke build targets as needed.

Advanced users may wish to do things not supported by the IDE's GUI, so the build process is customisable by editing the project file directly. This page documents only the Xamarin.Android-specific features and customizations - many more things are possible with the normal MSBuild items, properties and targets.

Target Definitions

The Xamarin.Android-specific parts of the build process are defined in Novell.MonoDroid.Common.targets, but normal language-specific targets such as Microsoft.CSharp.targets are also required to build the assembly.

The following build properties must be set before importing any language targets:

<PropertyGroup>
  <TargetFrameworkIdentifier>MonoDroid</TargetFrameworkIdentifier>
  <MonoDroidVersion>v1.0</MonoDroidVersion>
  <TargetFrameworkVersion>v2.2</TargetFrameworkVersion>
</PropertyGroup>

All these these targets and properties can be included for C# by importing Novell.MonoDroid.CSharp.targets:

<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />

and this file can easily be adapted for other languages.

Build Targets

The following build targets are defined for Xamarin.Android projects:

Build: Builds the package.

Clean: Removes all files generated by the build process.

UpdateAndroidResources: Updates the resgen file.

SignAndroidPackage: Signs the package.

Install: Installs the package onto the default device or virtual device. The AdbTarget property can be used to specify on which device the application should be installed:

# Install package onto emulator
# Use `xbuild` on OS X
MSBuild /t:Install ProjectName.csproj /p:AdbTarget=-e

Uninstall: Uninstalls the package from the default device or virtual device.

App Packaging

If the AndroidApplication property is True, the project is treated as an application project, and the mandroid.exe tool is used to produce a package from the compiled dll and the android resources. If not, the project is treated as a library.

The AndroidManifest property specifies a file that will be used as a template for the app's manifest. The only value it must contain is the package name, which is required by the build process. During the build, any other necessary values will be merged into the template to produce the actual manifest. If the DebugSymbols boolean property is set to true, the INTERNET permission will be added in order to allow the app to connect to the Xamarin.Android debugger. The MandroidExtraArgs property can be used to pass additional command-line arguments to mandroid.exe, if needed.

The app package is created in the project's output directory.

Shared Runtime

Xamarin.Android provides two ways to package your application. For Release builds, your application should include the Mono runtime in your package, creating a stand-alone package. For Debug builds and during development, you can rely on the Mono shared runtime, which allows the Mono runtime to be reused by all packages that need it, saving space, smaller packages, and a faster build/deploy/debug turnaround cycle.

This is controlled via AndroidUseSharedRuntime:

<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>

If not specified, the default is True.

Linking

Linking scans your application to see which parts of the class libraries you actually use, and tries to remove parts of the libraries that you don't use, resulting in much smaller packages. This is controlled via AndroidLinkMode, with the default of SdkOnly:

<AndroidLinkMode>SdkOnly</AndroidLinkMode>

Valid values are:

  • None - No linking will be attempted.
  • SdkOnly - Linking will be performed on the base class libraries only, not user's assemblies.
  • Full - Linking will be performed on base class libraries and user assemblies.

If an assembly should not be linked, it can be skipped by using the AndroidLinkSkip property:

<AndroidLinkSkip>Assembly1;Assembly2</AndroidLinkSkip>

The AssemblyLinkSkip value is a semicolon-separated list of assembly names, without file extensions.

Internationalization Support

By default, Xamarin.Android only includes a limited list of collation tables and Encodings. In order to include additional data into your application, you can use the MandroidI18n property:

<MandroidI18n>West</MandroidI18n>

MandroidI18n specifies a comma separated list of one or more of the following values:

  • None: Include no additional encodings.
  • All: Include all available encodings.
  • CJK: Include Chinese, Japanese, and Korean encodings such as Japanese (EUC) [enc-jp, CP51932], Japanese (Shift-JIS) [iso-2022-jp, shift_jis, CP932], Japanese (JIS) [CP50220], Chinese Simplified (GB2312) [gb2312, CP936], Korean (UHC) [ks_c_5601-1987, CP949], Korean (EUC) [euc-kr, CP51949], Chinese Traditional (Big5) [big5, CP950], and Chinese Simplified (GB18030) [GB18030, CP54936].
  • MidEast: Include Middle-Eastern encodings such as Turkish (Windows) [iso-8859-9, CP1254], Hebrew (Windows) [windows-1255, CP1255], Arabic (Windows) [windows-1256, CP1256], Arabic (ISO) [iso-8859-6, CP28596], Hebrew (ISO) [iso-8859-8, CP28598], Latin 5 (ISO) [iso-8859-9, CP28599], and Hebrew (Iso Alternative) [iso-8859-8, CP38598].
  • Other: Include Other encodings such as Cyrillic (Windows) [CP1251], Baltic (Windows) [iso-8859-4, CP1257], Vietnamese (Windows) [CP1258], Cyrillic (KOI8-R) [koi8-r, CP1251], Ukrainian (KOI8-U) [koi8-u, CP1251], Baltic (ISO) [iso-8859-4, CP1257], Cyrillic (ISO) [iso-8859-5, CP1251], ISCII Davenagari [x-iscii-de, CP57002], ISCII Bengali [x-iscii-be, CP57003], ISCII Tamil [x-iscii-ta, CP57004], ISCII Telugu [x-iscii-te, CP57005], ISCII Assamese [x-iscii-as, CP57006], ISCII Oriya [x-iscii-or, CP57007], ISCII Kannada [x-iscii-ka, CP57008], ISCII Malayalam [x-iscii-ma, CP57009], ISCII Gujarati [x-iscii-gu, CP57010], ISCII Punjabi [x-iscii-pa, CP57011], and Thai (Windows) [CP874].
  • Rare: Include Rare encodings such as IBM EBCDIC (Turkish) [CP1026], IBM EBCDIC (Open Systems Latin 1) [CP1047], IBM EBCDIC (US-Canada with Euro) [CP1140], IBM EBCDIC (Germany with Euro) [CP1141], IBM EBCDIC (Denmark/Norway with Euro) [CP1142], IBM EBCDIC (Finland/Sweden with Euro) [CP1143], IBM EBCDIC (Italy with Euro) [CP1144], IBM EBCDIC (Latin America/Spain with Euro) [CP1145], IBM EBCDIC (United Kingdom with Euro) [CP1146], IBM EBCDIC (France with Euro) [CP1147], IBM EBCDIC (International with Euro) [CP1148], IBM EBCDIC (Icelandic with Euro) [CP1149], IBM EBCDIC (Germany) [CP20273], IBM EBCDIC (Denmark/Norway) [CP20277], IBM EBCDIC (Finland/Sweden) [CP20278], IBM EBCDIC (Italy) [CP20280], IBM EBCDIC (Latin America/Spain) [CP20284], IBM EBCDIC (United Kingdom) [CP20285], IBM EBCDIC (Japanese Katakana Extended) [CP20290], IBM EBCDIC (France) [CP20297], IBM EBCDIC (Arabic) [CP20420], IBM EBCDIC (Hebrew) [CP20424], IBM EBCDIC (Icelandic) [CP20871], IBM EBCDIC (Cyrillic - Serbian, Bulgarian) [CP21025], IBM EBCDIC (US-Canada) [CP37], IBM EBCDIC (International) [CP500], Arabic (ASMO 708) [CP708], Central European (DOS) [CP852], Cyrillic (DOS) [CP855], Turkish (DOS) [CP857], Western European (DOS with Euro) [CP858], Hebrew (DOS) [CP862], Arabic (DOS) [CP864], Russian (DOS) [CP866], Greek (DOS) [CP869], IBM EBCDIC (Latin 2) [CP870], and IBM EBCDIC (Greek) [CP875].
  • West: Include Western encodings such as Western European (Mac) [macintosh, CP10000], Icelandic (Mac) [x-mac-icelandic, CP10079], Central European (Windows) [iso-8859-2, CP1250], Western European (Windows) [iso-8859-1, CP1252], Greek (Windows) [iso-8859-7, CP1253], Central European (ISO) [iso-8859-2, CP28592], Latin 3 (ISO) [iso-8859-3, CP28593], Greek (ISO) [iso-8859-7, CP28597], Latin 9 (ISO) [iso-8859-15, CP28605], OEM United States [CP437], Western European (DOS) [CP850], Portuguese (DOS) [CP860], Icelandic (DOS) [CP861], French Canadian (DOS) [CP863], and Nordic (DOS) [CP865].

Mandroid Arguments

If you need to provide additional arguments to mandroid.exe (e.g. to increase verbosity, etc.), specify a MandroidExtraArgs property group:

<PropertyGroup>
  <MandroidExtraArgs>-v</MandroidExtraArgs>
</PropertyGroup>

See mandroid.exe --help for a full listing of supported arguments.

Java Interop Support

Java source files (.java files) should have their Build action set to AndroidJavaSource, and Java archives (.jar files) should have their Build action set to AndroidJavaLibrary. Doing so will result in the sources and libraries being included into the final .apk.

Native Library Support

Native libraries are added to the build by setting their Build Action to AndroidNativeLibrary.

Note that since Android supports multiple Application Binary Interfaces (ABIs), mandroid must know which ABI the native library is built for. There are two ways this can be done:

  1. Path "sniffing"
  2. Using a //AndroidNativeLibrary/Abi element within the project file

With path sniffing, the parent directory name of the native library is used to specify the ABI that the library targets. Thus, if you add lib/armeabi/libfoo.so to the build, then the ABI will be "sniffed" as armeabi.

Alternatively, you can edit your project file to explicitly specify the ABI to use:

<ItemGroup>
    <AndroidNativeLibrary Include="path/to/libfoo.so">
        <Abi>armeabi</Abi>
    </AndroidNativeLibrary>
</ItemGroup>

Resgen

If the project includes the AndroidResgenFile property, then aresgen.exe will be run on the processed resources, generating a file containing a class with all the resource IDs. By default, new projects specify this in order to generate an R.cs file in the project root:

<PropertyGroup>
  <AndroidResgenFile>R.cs</AndroidResgenFile>
</PropertyGroup>
<ItemGroup>
  <Compile Include="R.cs" />
</ItemGroup>

Potentially, different resgen files could be generated and included for different configurations.

Resources

All files with an AndroidResource build action are compiled into Android resources during the build process:

<ItemGroup>
  <AndroidResource Include="Resources/values/strings.xml" />
</ItemGroup>

The effective path of the compiled Android resource is the file's relative path within the project directory. Any semicolon-separated values specified in the project's MonoAndroidResourcePrefix property are removed from the beginning of the calculated paths, in order to allow users to structure their resources away from their code files. This property's value defaults to "Resources", hence the effective path of the above resource would be "values/strings.xml".

Most users will not need to change any properties, and can simply place all resource files in the Resources directory and its subdirectories.

More advanced users might perhaps wish to have different resources used in different configurations but with the same effective path. This can be achieved by having multiple resource directories and having files with the same relative paths within these different directories, and using MSBuild conditions to conditionally include different files in different configurations. For example:

<ItemGroup Condition="'$(Configuration)'!='Debug'">
  <AndroidResource Include="Resources/values/strings.xml" />
</ItemGroup>
<ItemGroup  Condition="'$(Configuration)'=='Debug'">
  <AndroidResource Include="Resources-Debug/values/strings.xml"/>
</ItemGroup>
<PropertyGroup>
  <MonoAndroidResourcePrefix>Resources;Resources-Debug<MonoAndroidResourcePrefix>
</PropertyGroup>

For more granular control, the LogicalName item metadata can be used to specify the resource path explicitly, as with .NET EmbeddedResource files:

<ItemGroup Condition="'$(Configuration)'!='Debug'">
  <AndroidResource Include="Resources/values/strings.xml"/>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
  <AndroidResource Include="Resources-Debug/values/strings.xml">
    <LogicalName>values/strings.xml</LogicalName>
  </AndroidResource>
</ItemGroup>

Signing

In order to run on an Android device, packages must be signed. In order to allow quicker build iteration, the Xamarin.Android tasks do not sign packages during the build process, because signing is quite slow. Instead, they are signed (if necessary) before installation or during export, by the IDE or the Install build target. Invoking the SignAndroidPackage target will produce a package with the "-Signed.apk" suffix in the output directory.

By default, the signing target generates a new debug-signing key if necessary. If you wish to use a specific key, for example on a build server, the following MSBuild properties can be used:

<PropertyGroup>
    <AndroidKeyStore>True</AndroidKeyStore>
    <AndroidSigningKeyStore>filename.keystore</AndroidSigningKeyStore>
    <AndroidSigningStorePass>keystore.filename password</AndroidSigningStorePass>
    <AndroidSigningKeyAlias>keystore.alias</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>keystore.alias.password</AndroidSigningKeyPass>
</PropertyGroup>
  • AndroidKeyStore: Must be a non-empty string in order for the following properties to be used.
  • AndroidSigningKeyStore: the key store filename
  • AndroidSigningStorePass: the password for the key store
  • AndroidSigningKeyAlias: the alias of the key in the store
  • AndroidSigningKeyPass: the password of the key in the store

For example, consider the following keytool invocation:

keytool -genkey -v -keystore filename.keystore -alias keystore.alias -keyalg RSA -keysize 2048 -validity 10000

Since the keytool command specifies -alias keystore.alias, then the element will be:

<AndroidSigningKeyAlias>keystore.alias</AndroidSigningKeyAlias>

The first thing that the keytool command asks is the password:

Enter keystore password:

The value entered here should be used in the element.

At the end of keytool execution, it will prompt:

Enter key password for <keystore.alias>
(RETURN if same as keystore password)

The value entered here should be used as the element value. If no value is entered, then should have the same value as the element.