When working with Azure Visual Studio Team Services it is common and convenient to use Continuous Integration & Delivery Build and Release service with Hosted agents.
Here we want to build a Xamarin Android application with the VSTS task Xamarin.Android Build task. To do so we will create a build definition using this task.
In most cases everything should work smoothly and you'll be able to build your Xamarin Android project. However, if you need to use the Bundle assemblies into native code option, also named BundleAssemblies in a Xamarin Android application csproj, you'll probably run into some issues making it impossible to successfully build the project.
The errors you'll probably get when building a project with an Hosted agent using the queue named Hosted VS2017 is the following:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets (2176, 3)
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2176,3): Error : Could not find a part of the path 'd:\platforms'.
Process 'msbuild.exe' exited with code '1'.
Source of the errors
By checking in the build logs, we can see that the error occurs when the following build task is triggered: _BuildApkEmbed
This is happening because the Android NDK path is not found and not properly set at an earlier stage:
2017-11-08T20:26:51.8616357Z Android NDK: \
2017-11-08T20:26:51.8616357Z Android SDK: C:\Program Files (x86)\Android\android-sdk\
Howerver the Android NDK is the essential element in this build task.
Solution
In order to resolve this issue, we will have to manually set the Android NDK path. In your build definition, in the VSTS task Xamarin.Android Build task, go to the section named MSBuild Options.
Here we will use Additional Arguments to pass the following additional arguments to MSBuild:
/p:AndroidNdkDirectory="C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b"
As you can see we are providing the proper Android NDK path for the VS2017 Hosted agent.
Save your build definition and queue a new build. You should now have a successful build, with the build task _BuildApkEmbed looking like the following in the logs:
2017-11-09T02:12:14.7934177Z ...
2017-11-09T02:12:15.5271165Z _BuildApkEmbed:
2017-11-09T02:12:15.5281163Z [mkbundle stderr]
2017-11-09T02:12:16.6499807Z [cc stderr]
2017-11-09T02:12:16.6559798Z [LD] C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-ld.exe --shared obj\Release\bundles\armeabi-v7a\temp.o obj\Release\bundles\armeabi-v7a\assemblies.o -o obj\Release\bundles\armeabi-v7a\libmonodroid_bundle_app.so -L C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b\platforms\android-9\arch-arm\usr\lib -lc -lm -ldl -llog -lz
2017-11-09T02:12:16.9183355Z [ld stderr]
2017-11-09T02:12:17.8782862Z _CopyPackage:
2017-11-09T02:12:17.8782862Z ...
To go further
If you try to build with the Hosted agent with VS2015, you'll run into the same kind of issues but with different errors:
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets (1873, 3)
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1873,3): Error : java\lang\Object.class(java\lang : Object.class)
cannot access java.lang.Object
[object Object]
Process 'msbuild.exe' exited with code '1'.
Earlier in the year the build was properly working by using the JDK8 and setting the proper Android NDK path with version r10d:
/p:AndroidNdkDirectory="C:\java\androidsdk\android-ndk-r10d"
Later in the year the Android NDK version has been update on the Hosted agent, to use the version r13b:
/p:AndroidNdkDirectory="C:\java\androidsdk\android-ndk-r13b"
However, after this update it became impossible to generate an apk, worst the build is successful and the error swallowed. If you check at the logs you'll obtain something like this:
2017-11-09T03:24:02.1347738Z ...
2017-11-09T03:24:03.0720360Z _BuildApkEmbed:
2017-11-09T03:24:03.0720360Z [mkbundle stderr]
2017-11-09T03:24:03.1359376Z Error: System.InvalidOperationException: Platform header files for target Arm and API Level 4 was not found. Expected path is "C:\java\androidsdk\android-ndk-r13b\platforms\android-4\arch-arm\usr\include"
2017-11-09T03:24:03.1359376Z at Xamarin.Android.Tasks.NdkUtil.GetNdkPlatformIncludePath(String androidNdkPath, AndroidTargetArch arch, Int32 level)
2017-11-09T03:24:03.1359376Z at Xamarin.Android.Tasks.MakeBundleNativeCodeExternal.DoExecute()
2017-11-09T03:24:03.1359376Z at Xamarin.Android.Tasks.MakeBundleNativeCodeExternal.Execute()
2017-11-09T03:24:03.9240521Z _CopyPackage:
2017-11-09T03:24:03.9240521Z ...
This error appears because of a bug in the Xamarin Android version on the Hosted agent when using the NDK r13b.
Summary
We have seen how to build a Xamarin Android App with the Bundle assemblies into native code option enabled on the Azure VSTS hosted agent VS2017.
Also we tried to cover the main errors we can have when trying to build with the Hosted agent with VS2015.
Please feel free to comment or contact me if you have any question about this article.