Xamarin is a multi-platform technology that can provide efficiencies from allowing code reuse between Android and iOS. However, the WillowTree team was experiencing long build times with Visual Studio for Mac on a recent Xamarin project, negating a lot of the speed and time-to-market benefits that Xamarin brings to the table. Observing the build logs showed that VS appeared to be stalled for significant amounts of time. Perplexed, I tried invoking MSBuild directly from the command line and found that compilation was significantly faster than Visual Studio.
For example, building and deploying a large client project after cleaning in Visual Studio Mac 8.4.2 took about 8 minutes. A subsequent build and deploy cycle after changing a single string literal also took about 8 minutes.
After doing another full clean, I triggered a compile and deploy using MSBuild directly with the following:
msbuild <path to platform csproj> /p:Configuration=Debug.
This build took a little over 4 minutes. A subsequent build and deploy cycle after changing a single string literal took only 16 seconds, a decrease of over 96% from Visual Studio. This speedup allowed our build-debug-build cycles to shorten dramatically.
In order to attach the debugger, Visual Studio Mac requires the entire app to be recompiled. I was able to find an extension for Visual Studio Code, Xamarin Debug by Vadzimv, that allows the user to launch and debug any Xamarin.Android application. There is no alternative for iOS at this time, but Android developers can save additional time using this extension.
After this discovery, I decided to write a simple wrapper around MSBuild and Nuget to allow developers to easily use another editor and perform all normal Xamarin development (with the exception of debugging at the moment) without using Visual Studio. Xambuild is a single python script that you can drop into your project and requires no additional setup for most common project configurations. Projects with the standard Xamarin folder structure with AppName.iOS and AppName.Droid need no extra configuration. Xambuild allows you to build and deploy your project with a simple ./xambuild.py buildAndDeploy instead of requiring that you pass flags and paths to MSBuild.
Xambuild also allows you to restore and wipe Nuget caches for all subprojects simultaneously.
Being able to run a single nuget restore command for your Android, iOS, and data access layer subprojects can save time and confusion when cloning your project or updating dependencies. Similarly, the wipe command is helpful when updating nuget packages - old packages are occasionally cached and can break builds until the Nuget cache is wiped.
Experimenting to find the best tooling has had a great positive impact on my workflow. Engineering effort put into tooling improvements can lead to impressive time savings, both directly from decreased build times but also from improved sustainable flow, which is a significant part of our culture and a company Core Value.