TTY

← All Articles

Xamarin Development on Linux with Jetbrains Rider

Sept. 5, 2019

Introduction

Developing Xamarin apps on Linux is not officially supported, so there's a fair bit of tinkering necessary.

For writing this guide is used mainly two resources: First is an article provided by a Jetbrains employee[1], describing the process for setting everything up on Ubuntu 16.04. Second article is more up-to-date and was written for Ubuntu 19.04[2]. I wanted to summarize all those things in one article, including some more issues that I encountered.

This guide is written for Ubuntu 19.04. If you use another distribution, package names and repositories may be different.

Setting up the development environment

.NET Core SDK

Install it by following instructions from the official website. I picked .NET Core 2.2, which is, at the time of this writing, the latest release.

https://dotnet.microsoft.com/download/linux-package-manager/ubuntu19-04/sdk-current

Mono

First of all, the mono version that comes in the standard Ubuntu repositories is too old, you'll have to add the mono repository by following the steps on the mono website:

https://www.mono-project.com/download/stable/#download-lin-ubuntu

After adding the repository, install mono by running the following command:

sudo apt install mono-devel

Oracle JDK 8

There's a neat script for installing Java, you can get it by either downloading it, or by cloning the repository:

git clone https://github.com/chrishantha/install-java.git

Download the official zip from Oracle:

https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

For whatever devilish reason, you'll need an Oracle account to do this. Install it then using:

sudo ./install-java.sh -f jdk-8u221-linux-x64.tar.gz

Android Studio

Download Android Studio from here:

https://developer.android.com/studio/index.html

It's just an archive, extract it and start bin/studio.sh. It will download a bunch of stuff when you run it the first time.

I also downloaded the Android 9 SDK (API Level 28), which is what I'm compiling against.

Xamarin.Android

Go to https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-linux/ and look for the permalink called "Last stable build". There has not been a successful build for a while, so it's quite a bit behind the Windows version. Click the section called "Azure Artifacts" and then download a file called: 

xamarin-android/xamarin.android-oss_v9.2.99.172_Linux-x86_64_master_d33bbd8e-Debug.tar.bz2

I downloaded the debug version, I have not tried using the release version.

Create the directories:

sudo mkdir /usr/lib/xamarin.android
sudo mkdir /usr/lib/mono/xbuild/Xamarin/

Unzip the file you just downloaded and navigate into it. Then run:

sudo cp -a "bin/Debug/lib/xamarin.android/." "/usr/lib/xamarin.android/"

Now, the following:

rm -rf "/usr/lib/mono/xbuild/Xamarin/Android"
rm -rf "/usr/lib/mono/xbuild-frameworks/MonoAndroid"
sudo ln -s "/usr/lib/xamarin.android/xbuild/Xamarin/Android/" "/usr/lib/mono/xbuild/Xamarin/Android"
sudo ln -s "/usr/lib/xamarin.android/xbuild-frameworks/MonoAndroid/" "/usr/lib/mono/xbuild-frameworks/MonoAndroid"

The original guide also recommended making changes to the Android project file (.csproj), however, these are not working and don't appear to be necessary anymore.

Fix missing libzip.so.4

Next, I encountered the following build error:

 Xamarin.Android.Common.targets(1411, 2): [MSB4018] The "ResolveLibraryProjectImports" task failed unexpectedly.
System.DllNotFoundException: libzip.so.4
at (wrapper managed-to-native) Xamarin.Tools.Zip.Native.zip_source_function_create(Xamarin.Tools.Zip.Native/zip_source_callback,intptr,Xamarin.Tools.Zip.Native/zip_error_t&)
at Xamarin.Tools.Zip.ZipArchive..ctor (System.IO.Stream stream, Xamarin.Tools.Zip.IPlatformOptions options, Xamarin.Tools.Zip.OpenFlags flags) [0x00051] in <fe80d09f7fed4508a2ed5a9a9da8eb9b>:0
at Xamarin.Tools.Zip.UnixZipArchive..ctor (System.IO.Stream stream, Xamarin.Tools.Zip.UnixPlatformOptions options, Xamarin.Tools.Zip.OpenFlags flags) [0x00000] in <fe80d09f7fed4508a2ed5a9a9da8eb9b>:0
at Xamarin.Tools.Zip.ZipArchive.CreateInstanceFromStream (System.IO.Stream stream, Xamarin.Tools.Zip.OpenFlags flags, Xamarin.Tools.Zip.IPlatformOptions options) [0x0001a] in <fe80d09f7fed4508a2ed5a9a9da8eb9b>:0
at Xamarin.Tools.Zip.ZipArchive.Open (System.IO.Stream stream, Xamarin.Tools.Zip.IPlatformOptions options) [0x00001] in <fe80d09f7fed4508a2ed5a9a9da8eb9b>:0
at Xamarin.Android.Tasks.ResolveLibraryProjectImports.Extract (Java.Interop.Tools.Cecil.DirectoryAssemblyResolver res, System.Collections.Generic.ICollection`1[T] jars, System.Collections.Generic.ICollection`1[T] resolvedResourceDirectories, System.Collections.Generic.ICollection`1[T] resolvedAssetDirectories, System.Collections.Generic.ICollection`1[T] resolvedEnvironments) [0x006c9] in <ae9c238b57ad42d0b8bdfdb2cbc714a7>:0
at Xamarin.Android.Tasks.ResolveLibraryProjectImports.Execute () [0x000a4] in <ae9c238b57ad42d0b8bdfdb2cbc714a7>:0
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute () [0x00029] in <18acf4ba42414d46aa6ba7c7ca733b1f>:0
at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask (Microsoft.Build.BackEnd.ITaskExecutionHost taskExecutionHost, Microsoft.Build.BackEnd.Logging.TaskLoggingContext taskLoggingContext, Microsoft.Build.BackEnd.TaskHost taskHost, Microsoft.Build.BackEnd.ItemBucket bucket, Microsoft.Build.BackEnd.TaskExecutionMode howToExecuteTask) [0x002a9] in <18acf4ba42414d46aa6ba7c7ca733b1f>:0
 

Here's how to solve this:

sudo apt-get install libzip-dev
cd /usr/lib/x86_64-linux-gnu/
sudo ln -s libzip.so.5.0 libzip.so.4

Resource file missing

Next up, I got the following error:

Source file '/home/acu/RiderProjects/App1/App1/App1.Android/Resources/Resource.Designer.cs' could not be found.

Nasty error, what I figured out is that this problem happens because Linux is case sensitive (Windows isn't).

In the Android project file there's the following line:

<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>

And a bit further down in the same file, there's the following:

<Compile Include="Resources\Resource.Designer.cs" />

As far as the Linux file system is concerned, Resource.Designer.cs and Resource.designer.cs are different files. You can fix the casing in either line - and the error's gone.

And that's it, now I was able to compile the Android project successfully.j

Jetbrains Rider Setup

In the settings, under Build, Execution, Deployment -> Android I have set the following:

Android SDK Location/home/<username>/Android/Sdk
Android NDK Location/home/<username>/Android/Sdk/ndk/20.0.5594570
Java Development Kit Location/usr/lib/jvm/jdk1.8.0_221

The location of the Android SDK/NDK was automatically picked by Android Studio, so it's likely you will find them in the same place.

Getting it running in an Emulator

Next thing you'll probably try is running the Android app inside an emulator. First time I tried it I got this error:

Xamarin.Android.Common.targets(3438, 3): [ADB0000] /usr/lib/mono/xbuild/Xamarin/Android/Xamarin.Android.Common.targets(3438,3): error ADB0000: The command `"/home/acu/Android/Sdk/platform-tools/adb" -s emulator-5554 install -r "bin/Debug/com.companyname.App1-Signed.apk"` exited with code 1:
adb: failed to install bin/Debug/com.companyname.App1-Signed.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
Performing Streamed Install

INSTALL_FAILED_NO_MATCHING_ABIS tells me that it didn't compile the app for the architecture needed by the Emulator. Visual Studio provides a user interface for setting the architectures, but Jetbrains Rider doesn't have that unfortunately. So, once again, back to editing the project file by hand.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
[...]
<AndroidSupportedAbis>arm64-v8a;armeabi-v7a;x86;x86_64</AndroidSupportedAbis>
</PropertyGroup>

After that, I was able to run the app successfully in the Android Emulator.

← All Articles