Cross Platform
Android
iOS
Mac
Test Cloud

Build Process

Overview

The Xamarin.Android build process is responsible for gluing everything together: generating Resource.designer.cs, supporting the AndroidAsset, AndroidResource, and other build actions, generating Android-callable wrappers, and generating a .apk for execution on Android devices.

Application Packages

In broad terms, there are two types of Android application packages (.apk files) which the Xamarin.Android build system can generate:

  • Release builds, which are fully self-contained and don't require additional packages in order to execute. These are the packages which would be provided to an App store.
  • Debug builds, which are not.

Not coincidentally, these match the MSBuild Configuration which produces the package. ;-)

Shared Runtime

The shared runtime is a pair of additional Android packages which provide the Base Class Library (mscorlib.dll, etc.) and the Android binding library (Mono.Android.dll, etc.). Debug builds rely upon the shared runtime in lieu of including the Base Class Library and Binding assemblies within the Android application package, allowing the Debug package to be smaller.

The shared runtime may be disabled in Debug builds by setting the $(AndroidUseSharedRuntime) property to False.

Fast Deployment

Fast deployment works in concert with the shared runtime to further shrink the Android application package size. This is done by not bundling the app's assemblies within the package. Instead, they are copied onto the target via adb push. This process speeds up the build/deploy/debug cycle because if only assemblies are changed, the package is not reinstalled. Instead, only the updated assemblies are re-synchronized to the target device.

Fast deployment is known to fail on devices which block adb from synchronizing to the directory /data/data/@PACKAGE_NAME@/files/.__override__.

Fast deployment is enabled by default, and may be disabled in Debug builds by setting the $(EmbedAssembliesIntoApk) property to True.

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.

Build Targets

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

Target NameDescription
Build Builds the package.
Clean Removes all files generated by the build process.
Install Installs the package onto the default device or virtual device.
Uninstall Uninstalls the package from the default device or virtual device.
SignAndroidPackage Creates and signs the package (.apk). Use with /p:Configuration=Release to generate self-contained "Release" packages.
UpdateAndroidResources Updates the Resource.designer.cs file. This target is usually called by the IDE when new resources are added to the project.

Build Properties

MSBuild properties control the behavior of the targets. They are specified within the project file, e.g. MyApp.csproj, within an MSBuild PropertyGroup element.

Property NameDescription
Configuration Specifies the build configuration to use, such as "Debug" or "Release". The Configuration property is used to determine default values for other properties which determine target behavior. Additional configurations may be created within your IDE.

By default, the Debug configuration will result in the Install and SignAndroidPackage targets creating a smaller Android package which requires the presence of other files and packages in order to operate.

The default Release configuration will result in the in the Install and SignAndroidPackage targets creating an Android package which is stand-alone, and may be used without installing any other packages or files.

DebugSymbols A boolean value which determines whether the Android package is debuggable, in combination with the $(DebugType) property. A debuggable package contains debug symbols, sets the //application/@android:debuggable attribute to true, and automatically adds the INTERNET permission so that a debugger can attach to the process. An application is debuggable if DebugSymbols is True and DebugType is either the empty string or Full.
DebugType Specifies the type of debug symbols to generate as part of the build, which also impacts whether the Application is debuggable. Possible values include:
  • Full: Full symbols are generated. If the DebugSymbols MSBuild property is also True, then the Application package is debuggable.
  • PdbOnly: "PDB" symbols are generated. The Application package will not be debuggable.
If DebugType is not set or is the empty string, then the DebugSymbols property controls whether or not th Application is debuggable.

Install Properties

Install properties control the behavior of the Install and Uninstall targets.

Property NameDescription
AdbTarget Specifies the Android target device the Android package may be installed to or removed from. The value of this property is the same as the adb Target Device option:
# Install package onto emulator via -e
# Use `xbuild` on OS X
MSBuild /t:Install ProjectName.csproj /p:AdbTarget=-e

Packaging Properties

Packaging properties control the creation of the Android package, and are used by the Install and SignAndroidPackage targets. The Signing Properties are also relevant when packaing Release applications.

Property NameDescription
AndroidApplication A boolean value that indicates whether the project is for an Android Application (True) or for an Android Library Project (False or not present).

Only one project with <AndroidApplication>True</AndroidApplication> may be present within an Android package. (Unfortunately this is not yet verified, which can result in subtle and bizarre errors regarding Android reosurces.)

AndroidLinkMode Specifies which type of linking should be performed on assemblies contained within the Android package. Only used in Android Application projects. The default value is SdkOnly. 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.

Note: Using an AndroidLinkMode value of Full often results in broken apps, particularly when Reflection is used. Avoid unless you really know what you're doing.

<AndroidLinkMode>SdkOnly</AndroidLinkMode>
AndroidLinkSkip Specifies a semicolon-delimited (;) list of assembly names, without file extensions, of assemblies that should not be linked. Only used within Android Application projects.
<AndroidLinkSkip>Assembly1;Assembly2</AndroidLinkSkip>
AndroidManifest Specifies a filename to use as the template for the app's AndroidManifest.xml. During the build, any other necessary values will be merged into to produce the actual AndroidManifest.xml.

The $(AndroidManifest) must contain the package name in the /manifest/@package attribute.

AndroidUseSharedRuntime A boolean property that is determines whether the shared runtime packages are required in order to run the Application on the target device. Relying on the shared runtime packages allows the Application package to be smaller, speeding up the package creation and deployment process, resulting in a faster build/deploy/debug turnaround cycle.

This property should be True for Debug builds, and False for Release projects.

EmbedAssembliesIntoApk A boolean property that determines whether or not the app's assemblies should be embedded into the Application package.

This property should be True for Release builds and False for Debug builds. It may need to be True in Debug builds if the target device prevents adb from accessing the Application's directory (which is currently true for the Samsung Galaxy S IV).

JavaMaximumHeapSize Specifies the value of the java -Xmx parameter value to use when building the .dex file as part of the packaging process. If not specified, then the -Xmx option is not provided to java.

Specifying this property is necessary if the _CompileDex target throws a java.lang.OutOfMemoryError.

<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
JavaOptions Specifies additional command-line options to pass to java when building the .dex file.
MandroidI18n Specifies the internationalization support included with the Application, such as collation and sorting tables. The value is a comma- or semicolon-separated list of one or more of the following case-insensitive 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].
<MandroidI18n>West</MandroidI18n>

Resource Properties

Resource properties control the generation of the Resource.designer.cs file, which provides access to Android resources.

Property NameDescription
AndroidResgenExtraArgs Specifies additional command-line options to pass to the aapt command when processing Android assets and resources.
AndroidResgenFile Specifies the name of the Resource file to generate. The default template sets this to Resource.designer.cs.
MonoAndroidResourcePrefix Specifies a path prefix that is removed from the start of filenames with a Build action of AndroidResource. This is to allow changing where resources are located.

The default value is Resources. Change this to res for the Java project structure.

Signing Properties

Signing properties control how the Application package is signed so that it may be installed onto an Android device. 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:

Property NameDescription
AndroidKeyStore A boolean value which indicates whether custom signing information should be used. The default value is False, meaning that the default debug-signing key will be used to sign packages.
AndroidSigningKeyAlias Specifies the alias for the key in the keystore. This is the keytool -alias value used when creating the keystore.
AndroidSigningKeyPass Specifies the password of the key within the keystore file. This is the value entered when keytool asks Enter key password for $(AndroidSigningKeyAlias).
AndroidSigningKeyStore Specifies the filename of the keystore file created by keytool. This corresponds to the value provided to the keytool -keystore option.
AndroidSigningStorePass Specifies the password to $(AndroidSigningKeyStore). This is the value provided to keytool when creating the keystore file and asked Enter keystore password:.

For example, consider the following keytool invocation:

$ keytool -genkey -v -keystore filename.keystore -alias keystore.alias -keyalg RSA -keysize 2048 -validity 10000
Enter keystore password: keystore.filename password
Re-enter new password: keystore.filename password
...
Is CN=... correct?
  [no]:  yes

Generating 2,048 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10,000 days
        for: ...
Enter key password for keystore.alias
        (RETURN if same as keystore password): keystore.alias password
[Storing filename.keystore]

To use the keystore generated above, use the property group:

<PropertyGroup>
    <AndroidKeyStore>True</AndroidKeyStore>
    <AndroidSigningKeyStore>filename.keystore</AndroidSigningKeyStore>
    <AndroidSigningStorePass>keystore.filename password</AndroidSigningStorePass>
    <AndroidSigningKeyAlias>keystore.alias</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>keystore.alias password</AndroidSigningKeyPass>
</PropertyGroup>

Build Actions

Build actions are applied to files within the project and control how the file is processed.

AndroidEnvironment

Files with a Build action of AndroidEnvironment are used to initialize environment variables and system properties during process startup. The AndroidEnvironment Build action may be applied to multiple files, and they will be evaluated in no particular order (so don't specify the same environment variable or system property in multiple files).

AndroidJavaSource

Files with a Build action of AndroidJavaSource are Java source code which will be included in the final Android package.

AndroidJavaLibrary

Files with a Build action of AndroidJavaLibrary are Java Archives (.jar files) which will be included in the final Android package.

AndroidResource

All files with an AndroidResource build action are compiled into Android resources during the build process and made accessible via $(AndroidResgenFile).

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

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>
Item Attribute NameDescription
LogicalName Specifies the resource path explicitly. Allows "aliasing" files so that they will be available as multiple distinct resource names.
<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>

AndroidNativeLibrary

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

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

  1. Path "sniffing".
  2. Using the Abi item attribute.

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.

Item Attribute NameDescription
Abi Specifies the ABI of the native library.
<ItemGroup>
  <AndroidNativeLibrary Include="path/to/libfoo.so">
    <Abi>armeabi</Abi>
  </AndroidNativeLibrary>
</ItemGroup>

Content

The normal Content Build action is not supported (as we haven't figured out how to support it without a possibly costly first-run step).

Target Definitions

The Xamarin.Android-specific parts of the build process are defined in $(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.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 Xamarin.Android.CSharp.targets:

<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />

and this file can easily be adapted for other languages.