Xamarin Development on Linux with Jetbrains Rider
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, 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. I wanted to summarize all those things in one article, including some more issues that I encountered.
-  https://rider-support.jetbrains.com/hc/en-us/articles/360000557259
-  https://beyondvelocity.blog/2019/06/02/xamarin-android-on-ubuntu-19-04/
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.
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:
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:
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
Download Android Studio from here:
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.
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:
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.
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
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:
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' ">
After that, I was able to run the app successfully in the Android Emulator.