How to compile a Xamarin.Mac Application on Azure DevOps?

Homepage How to compile a Xamarin.Mac Application on Azure DevOps?

As you’ll gather from the previous articles in this series – Why Try Azure DevOps? and Azure DevOps: Ten Steps to Create Your First Pipeline – Azure DevOps is very flexible and there is no shortage of documentation. 

You’ll also understand that – being a Microsoft product – all of the publisher’s technologies are present on Azure DevOps and many tutorials/documentations are available to help you get going: UWP, WPF, WinFormXamarin.Android and Xamarin.iOS (the latter two my obvious favorites). 

Unfortunately, though, one is missing: Xamarin.Mac. 

Being an enterprise developer, I enjoy developing cross-platform desktop applications for Windows and MacOS. Further, since I’m particularly interested in the DevOps part, I’d like to be able to compile my Windows app and MacOS app in the same way via Azure DevOps. 

But how can I know if there’s nothing that allows me to do so? 

As you can see in the image above, there are no Xamarin or MacOS tasks planned for Xamarin.Mac.

So, if we’re going to do this, we’re going to have to find a way to complete this compilation without the out-of-the-box tools directly available on Azure DevOps.

How Does Visual Studio for Mac Compile a Xamarin.Mac App?

If you look at the app’s compilation logs (I advise you to go into “verbose” mode in Visual Studio for Mac settings) you can see that Mono uses MSBuild to compile the app:

This fits our use well since MSBuild is a basic command of the .NET environment, so there is a good chance that we can reproduce this compilation very easily on a Mac on Azure DevOps.

How Do I Replicate this Process on Azure DevOps?

As we have seen, Visual Studio for Mac uses an MSBuild command with Mono to compile the Xamarin.Mac app on MacOS. Fortunately for us, this task already exists on Azure DevOps:

The documentation for this one is available from Microsoft.

This is really straightforward:

Now, all we have to do is launch our pipeline to see if everything is going well: if so, then we now have a fully functional MacOS application compiled directly by Azure DevOps!

But watch out because one last problem remains: recovering the application.

How do I recover my Xamarin.Mac app?

You might think it’s an easy fix. You could push it into Azure’s artefacts and then manually download it from the interface, for example, or you might prefer to upload it to an Azure Storage or FTP.

Unfortunately for us, it’s not that simple.

If you have the misfortune of sending the MacOS app “MyApp.app” to a machine that doesn’t manage reading/writing and execution attributes, such as a Windows machine, you’ll see this error appear:

This can be more than a little annoying when you want to run the application! But why does this problem emerge at all?
Well, it’s simply because the execution attributes are lost by switching to Windows. When the app returns to MacOS, it no longer owns them and can no longer run in a classic way.

Retain the execution attributes

The easiest way to overcome this error is to store your application in a container capable of retaining these attributes: compressing it in Tar, for example, is a good way to do this.

Don’t forget the Signature Case

We have just compiled an application but it is not yet signed. Without this signature, every MacOS X launch will display a window like this:

This can easily scare away users who might be afraid to run your app on their computer. To avoid the window, add security and prevent someone from changing your app, it is necessary that it be signed. Hence, we’re going to do what’s necessary to make your application as secure as possible.

The first step is to activate the signature of the application in the properties of the project. Visit the “Mac Signing” menu:

This is where we will be able to choose the identity of the developer as well as the provisioning profile necessary to sign our application. You’ll find yourself facing this page:

Check the first Sign the application bundle box to access the rest.

If the identity or provisioning profile is not selectable in this window, you must install it on your system. Once done, be sure to restart Visual Studio which sometimes struggles with the installation of new certificates.

Once the changes are made, try compiling the Xamarin.Mac app locally – everything should work smoothly on your machine.

But be aware: there are still a few things to do on the Azure DevOps side. As in the previous article in this series on iOS, we need to add the “p12” file and the “provisionprofile” to the secure file library.

For this part, follow the “Signature of the application” procedure below:

 

From here you should be able to compile and sign your application directly from Azure DevOps.

Create a DMG for a Simplified Installation

Now that we’ve compiled our Xamarin.Mac app and it’s correctly signed we need to be able to easily install our application on customer machines.

By default, Visual Studio for Mac is able to generate an installation package as per those for large applications such as Oracle’s Office Pack or Virtual Box. Here’s an example:

But this kind of installation is cumbersome and useful only when independent tasks (file creation, file copy, etc.) are required to install or uninstall the software, and this is not always the case for smaller applications.

Note that PKG and DMG are only required if you don’t want to go through the Mac AppStore. As this is often the case, let’s see how to generate this famous DMG (the equivalent of ISO file for Windows – more details here).

Any MacOS machine can create using the pre-installed tools of DMG files:

What we want to do here is to allow the user to place the application directly in the application folder of the target computer. Hence, we need two things:

1. Our app
2. A link to the application folder

We’re lucky the default folder for applications on MacOS is the same for everyone: “/Applications.” Therefore, it is enough to create a symbolic link to this path – that’s what line 35 of the code above does.

Next, we copy the application that has just been compiled directly into the temporary folder (see line 38 of the code).

It’s at line 41 that everything is played out. Thanks to the “hdiutil” utility we will create the DMG. The first argument makes it possible to specify the export path of a new DMG file, then we give 3 other arguments:

1. “volname”, which names the volume once the DMG is opened – this is where we insert the name of the app
2. “fs”, is the type of volume to use – in our case, it is imperative to keep “HFS” which is specific to MacOS
3. “srcfolder”, which happens to be the content of our DMG – this is our symbolic link and our application. You can of course add anything else you want (a README file, a link to another system folder, another application, and so on)

As should be clear, it’s pretty easy to use!

Here we are: you have explored how to compile a Xamarin.Mac application directly on Azure DevOps, and how to deal with the various challenges that are associated with delivering the same application to MacOS and Windows in a professional context. I hope you’ve enjoyed this latest entry in the Azure DevOps series, and look forward to bringing you more articles soon!

Discover our expert, full-stack software development services!

You might also like...
3 Steps To Create Your Library With Xamarin.Mac

3 Steps To Create Your Library With Xamarin.Mac

Read more
Kevin Sibué - Software Engineer
21 February 2021