Installing .NET 6 on your M1 Mac (manually)

Maarten Merken
4 min readJan 19, 2021

In this short article, I’ll show you how to uninstall any previous dotnet versions on your M1 Mac and install the latest .NET 6.0.200 Preview release to date.

Microsoft released the official ARM64 macOS installer, please refer to this installer to install the .NET 6 Preview 3. You can continue reading to find out how to install the .NET SDK manually.

Earlier, I wrote about debugging .NET 5 apps on your M1 Mac using the Rosetta 2 translation on macOS Big Sur 11.2 Beta 2. Now, I’m going to show you how to install the latest .NET 6 build onto your M1 Mac.

Firstly, to avoid conflict, remove all .NET installations from your machine, this is easily done using the dotnet-uninstall-pkgs script found here: https://github.com/dotnet/cli/blob/master/scripts/obtain/uninstall/dotnet-uninstall-pkgs.sh

After downloading this file, make it executable so that you can execute it:

cd ~/Downloads
sudo chmod +x dotnet-uninstall-pkgs.sh
sudo ./dotnet-uninstall-pkgs.sh
dotnet uninstall

After uninstall, verify that all dotnet installations are removed:

dotnet
where dotnet

Download the .NET 6 Alpha 6.0.100 release from here : https://github.com/dotnet/installer

Download the tar.gz file

Or via direct download to the latest version: https://aka.ms/dotnet/6.0/daily/dotnet-sdk-osx-arm64.tar.gz

Installing .NET 6 to /usr/local/share/dotnet

dotnet installs to /usr/local/share/dotnet when using the pkgs installer, so that’s what we’re going to do also.

Extract the tar.gz file to disk and examine the contents:

contents of the .NET 6 tar.gz extraction

Copy all files to /usr/local/share/dotnet:

cd <net-6 directory>
cp -a . /usr/local/share/dotnet
copy all files to /usr/local/share/dotnet

Whitelisting all files from /usr/local/share/dotnet from Apple Quarantine

When you try to run the dotnet command in your terminal, you will be prompted to allow the execution for each library that the command invokes.

Malicious software check

To avoid this for all files within the /usr/local/share/dotnet directory, you will need to run the following command in terminal:

find . -type f -print0 | xargs -0 xattr -d com.apple.quarantine
unquarantine all files

After this, you need to create a symbolic link to the /usr/local/share/dotnet/dotnet executable.

cd /usr/local/bin
ln -s /usr/local/share/dotnet/dotnet dotnet
symlink to dotnet

At this point, you can use the dotnet command anywhere on your system.

Performance

Alexander Ziskind did a performance comparison between the M1 Macbook Air and the Intel i9 Macbook Pro 16, which you can find here.

I noticed that .NET 6, running natively on the MBA, performs a bit better when running his example cryptography application for 100.000.000 iterations.

using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
namespace ziskindtest
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100_000_000; i++)
{
Consume(CryptoConfig.CreateFromName("RSA"));
}
Console.WriteLine("All done MBA on .NET6");
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void Consume<T>(in T _) { }
}
}

The results on my M1 MBA were promising, it beats the results from the beefy i9 by a slight margin, I ran a dotnet build -c Release and dotnet run of the published app, and it persisted to run the test in around 53 seconds, which looks like it’s not that big of a performance gain over the 60 seconds running on Rosetta 2.

The Ziskin-test results on .NET 6

Then again, this is .NET 6 Alpha running on macOS Beta…

It’s still impressive that the M1 chip is able to compete against top-of-the-line Intel processors.

What this tells me is that Rosetta 2, truly is an example of magnificent engineering.

Removing the manually installed dotnet 6 Alpha

Undoing this installation is quite easy, you just need to delete the /usr/local/share/dotnet directory and the dotnet symbolic link at /usr/local/bin.

rm -rf /usr/local/share/dotnet
rm /usr/local/bin/dotnet

--

--