在ARM处理器的Ubuntu系统上安装 .NET SDK(Core 3.1~7.0),并检测ARM内在函数的支持情况

  • 在ARM处理器的Ubuntu系统上安装 .NET SDK(Core 3.1~7.0),并检测ARM内在函数的支持情况已关闭评论
  • 29 次浏览
  • A+
所属分类:.NET技术
摘要

作者: 在前一篇文章(在亚马逊AWS上创建ARM服务器并配置好RDP远程桌面连接的心得)里,我们成功在亚马逊AWS上创建了Ubuntu系统的ARM服务器。现在准备在该服务器上安装 .NET SDK。

作者:

目录

    在前一篇文章(在亚马逊AWS上创建ARM服务器并配置好RDP远程桌面连接的心得)里,我们成功在亚马逊AWS上创建了Ubuntu系统的ARM服务器。现在准备在该服务器上安装 .NET SDK。

    一、尝试 apt-get 安装

    首先尝试了之前在 x86 处理器的Ubuntu系统上安装 .NET SDK的经验,使用 apt-get 来安装。

    ubuntu@ip-175-76-22-54:~$ sudo apt-get install -y dotnet6 Reading package lists... Done Building dependency tree... Done Reading state information... Done E: Unable to locate package dotnet6 

    遇到错误,找不到“dotnet6”的安装包。随后换了几个版本也不行,sudo apt-get update 也没效果。

    于是查找了一下官方文档,发现 《在 Ubuntu 上安装 .NET SDK 或 .NET 运行时》中有这一段话:

    仅在 x64 体系结构上支持包管理器安装。 对于 Arm 等其他体系结构,必须通过其他一些方式安装 .NET,例如,通过 Snap 和安装程序脚本进行安装,或通过手动提取二进制文件进行安装。 

    原来ARM体系不支持包管理安装,看来得换一种办法来安装了。

    二、尝试 snap 安装

    现在来尝试 snap 安装。
    摘录官方文档:

    若要安装适用于 .NET SDK 的 Snap 包,请运行 snap install 命令。 使用 --channel 参数来指明要安装哪个版本。 如果省略此参数,则使用 latest/stable。 在下面的示例中,指定的是 7.0:  Bash sudo snap install dotnet-sdk --classic --channel=7.0 

    随后参考它,在我们的ARM服务器上执行命令。

    ubuntu@ip-175-76-22-54:~$ sudo snap install dotnet-sdk --classic --channel=7.0 error: snap "dotnet-sdk" is not available on 7.0/stable but other tracks exist.         Please be mindful that different tracks may include different features.        Get more information with 'snap info dotnet-sdk'. 

    有报错,说找不到可用的安装包。
    于是用命令查询了一下 snap 上有哪些 dotnet-sdk 版本。

    ubuntu@ip-175-76-22-54:~$ snap info dotnet-sdk name:      dotnet-sdk summary:   Develop high performance applications in less time, on any platform. publisher: Microsoft .NET Core (dotnetcore✓) store-url: https://snapcraft.io/dotnet-sdk contact:   https://dot.net/core license:   MIT description: |   .NET Core is the modular and high performance implementation of .NET for   creating web applications and services that run on Windows, Linux and Mac.   It is open source and it can share the same code with .NET Framework and   Xamarin apps.    .NET Core is a .NET Foundation project. https://dotnetfoundation.org/ snap-id: uHc4y9lWxyqYfxsqcr4xILzAai4L1BHs channels:   5.0/stable:    –   5.0/candidate: –   5.0/beta:      –   5.0/edge:      5.0.100-preview.3.20216.6 2020-04-21 (79) 127MB classic 

    发现它不支持 .net 7.0,仅有 .net 5.0版的。且没有稳定版(stable),只在edge通道有一个预览版(preview)。
    故再换一种办法吧。

    三、使用 dotnet-install 脚本安装

    3.1 脚本准备

    摘自官方文档:

    脚本安装 dotnet-install 脚本用于 SDK 和运行时的自动化和非管理员安装。 可通过 https://dot.net/v1/dotnet-install.sh 下载脚本。  重要:需要 Bash 才能运行该脚本。 运行此脚本之前,需要授予此脚本作为可执行文件运行的权限:  Bash sudo chmod +x ./dotnet-install.sh 

    上文介绍了脚本的网址,于是我们可以用 wget 命令下载该脚本,然后参考它修改文件属性。

    ubuntu@ip-175-76-22-54:~$ wget https://dot.net/v1/dotnet-install.sh --2022-11-26 08:28:01--  https://dot.net/v1/dotnet-install.sh Resolving dot.net (dot.net)... 20.53.203.50, 20.112.52.29, 20.103.85.33, ... Connecting to dot.net (dot.net)|20.53.203.50|:443... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh [following] --2022-11-26 08:28:02--  https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh Resolving dotnet.microsoft.com (dotnet.microsoft.com)... 13.107.246.46, 13.107.213.46, 2620:1ec:46::46, ... Connecting to dotnet.microsoft.com (dotnet.microsoft.com)|13.107.246.46|:443... connected. HTTP request sent, awaiting response... 200 OK Cookie coming from dotnet.microsoft.com attempted to set domain to dotnetwebsite.azurewebsites.net Cookie coming from dotnet.microsoft.com attempted to set domain to dotnetwebsite.azurewebsites.net Length: 58293 (57K) [application/x-sh] Saving to: ‘dotnet-install.sh’  dotnet-install.sh   100%[===================>]  56.93K  --.-KB/s    in 0.003s  2022-11-26 08:28:02 (20.4 MB/s) - ‘dotnet-install.sh’ saved [58293/58293]  ubuntu@ip-175-76-22-54:~$ sudo chmod +x ./dotnet-install.sh 

    3.2 安装最新长期支持 (LTS)版 .NET 6.0

    对于安装最新的长期支持 (LTS),可参考官方文档:

    该脚本默认安装最新的 长期支持 (LTS) SDK 版本,即 .NET 6。 若要安装最新版本(可能不是 LTS) 版本的 (版本),请使用 --version latest 参数。  Bash ./dotnet-install.sh --version latest 

    注意它在运行脚本时,没有加“sudo”,表示该脚本支持将程序安装到当前用户的目录下,无需管理员权限。
    但这对多用户使用时会带来麻烦。为了避免每个用户都装一次,于是也可选择用“sudo”来安装,这样便会安装在所有用户都能访问的路径中。

    ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where: dotnet-install: - The SDK needs to be installed without user interaction and without admin rights. dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs. dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.  dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.403/dotnet-sdk-6.0.403-linux-arm64.tar.gz dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.403/dotnet-sdk-6.0.403-linux-arm64.tar.gz dotnet-install: Installed version is 6.0.403 dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script. dotnet-install: Note that the script does not resolve dependencies during installation. dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section. dotnet-install: Installation finished successfully. 

    从上面的信息可看出,已安装好 .NET SDK 6.0,它装在 /root/.dotnet 目录中。

    3.3 安装最新版本 .NET 7.0

    对于安装指定的版本,可参考官方文档:

    可以使用 参数安装特定的主版本 --channel ,以指示特定版本。 以下命令安装 .NET 7.0 SDK。  Bash ./dotnet-install.sh --channel 7.0 

    按照文档,进行安装。

    ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh --channel 7.0 dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where: dotnet-install: - The SDK needs to be installed without user interaction and without admin rights. dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs. dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.  dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/7.0.100/dotnet-sdk-7.0.100-linux-arm64.tar.gz dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/7.0.100/dotnet-sdk-7.0.100-linux-arm64.tar.gz dotnet-install: Installed version is 7.0.100 dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script. dotnet-install: Note that the script does not resolve dependencies during installation. dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section. dotnet-install: Installation finished successfully. 

    .NET SDK 7.0 安装成功。

    3.4 安装旧版本 .NET Core 3.1

    官方文档的“受支持”列表里还有“.NET Core 3.1”,于是也可安装。

    ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh --channel 3.1 dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where: dotnet-install: - The SDK needs to be installed without user interaction and without admin rights. dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs. dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.  dotnet-install: Attempting to download using primary link https://dotnetcli.azureedge.net/dotnet/Sdk/3.1.425/dotnet-sdk-3.1.425-linux-arm64.tar.gz dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/3.1.425/dotnet-sdk-3.1.425-linux-arm64.tar.gz dotnet-install: Installed version is 3.1.425 dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script. dotnet-install: Note that the script does not resolve dependencies during installation. dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section. dotnet-install: Installation finished successfully. 

    .NET Core SDK 3.1 安装成功。

    3.5 安装不受支持的版本 .NET 5.0

    官方文档中,“.NET 5.0”在“不受支持”列表里,它会否能安装呢?于是我尝试了一下。

    ubuntu@ip-175-76-22-54:~$ sudo ./dotnet-install.sh --channel 5.0 dotnet-install: Note that the intended use of this script is for Continuous Integration (CI) scenarios, where: dotnet-install: - The SDK needs to be installed without user interaction and without admin rights. dotnet-install: - The SDK installation doesn't need to persist across multiple CI runs. dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.  dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.408/dotnet-sdk-5.0.408-linux-arm64.tar.gz dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.408/dotnet-sdk-5.0.408-linux-arm64.tar.gz dotnet-install: Installed version is 5.0.408 dotnet-install: Adding to current process PATH: `/root/.dotnet`. Note: This change will be visible only when sourcing script. dotnet-install: Note that the script does not resolve dependencies during installation. dotnet-install: To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section. dotnet-install: Installation finished successfully. 

    .NET SDK 5.0 安装成功。
    看来“不受支持”仅是指没有技术支持,还是可以用 dotnet-install 脚本安装该版本的。

    3.6 查看.NET SDK信息

    装好了,想查看一下安装的SDK信息,于是执行了以下命令。

    ubuntu@ip-175-76-22-54:~$ dotnet --list-sdks dotnet: command not found 

    报错了,找不到命令。
    原来是它没被自动加到环境变量,故需要写全路径。

    ubuntu@ip-175-76-22-54:~$ /root/.dotnet/dotnet --list-sdks -bash: /root/.dotnet/dotnet: Permission denied 

    这次遇到了“Permission denied”报错。
    看来是跟先前的“sudo”安装有关,需要使用“sudo”才能执行它。

    ubuntu@ip-175-76-22-54:~$ sudo /root/.dotnet/dotnet --list-sdks 3.1.425 [/root/.dotnet/sdk] 5.0.408 [/root/.dotnet/sdk] 6.0.403 [/root/.dotnet/sdk] 7.0.100 [/root/.dotnet/sdk]  ubuntu@ip-175-76-22-54:~$ sudo /root/.dotnet/dotnet --info .NET SDK:  Version:   7.0.100  Commit:    e12b7af219  Runtime Environment:  OS Name:     ubuntu  OS Version:  22.04  OS Platform: Linux  RID:         ubuntu.22.04-arm64  Base Path:   /root/.dotnet/sdk/7.0.100/  Host:   Version:      7.0.0   Architecture: arm64   Commit:       d099f075e4  .NET SDKs installed:   3.1.425 [/root/.dotnet/sdk]   5.0.408 [/root/.dotnet/sdk]   6.0.403 [/root/.dotnet/sdk]   7.0.100 [/root/.dotnet/sdk]  .NET runtimes installed:   Microsoft.AspNetCore.App 3.1.31 [/root/.dotnet/shared/Microsoft.AspNetCore.App]   Microsoft.AspNetCore.App 5.0.17 [/root/.dotnet/shared/Microsoft.AspNetCore.App]   Microsoft.AspNetCore.App 6.0.11 [/root/.dotnet/shared/Microsoft.AspNetCore.App]   Microsoft.AspNetCore.App 7.0.0 [/root/.dotnet/shared/Microsoft.AspNetCore.App]   Microsoft.NETCore.App 3.1.31 [/root/.dotnet/shared/Microsoft.NETCore.App]   Microsoft.NETCore.App 5.0.17 [/root/.dotnet/shared/Microsoft.NETCore.App]   Microsoft.NETCore.App 6.0.11 [/root/.dotnet/shared/Microsoft.NETCore.App]   Microsoft.NETCore.App 7.0.0 [/root/.dotnet/shared/Microsoft.NETCore.App]  Other architectures found:   None  Environment variables:   Not set  global.json file:   Not found  Learn more:   https://aka.ms/dotnet/info  Download .NET:   https://aka.ms/dotnet/download 

    成功得到了安装信息。

    四、运行 .NET 程序

    在Windows系统中,可方便的双击运行 .NET 程序;或是在命令行里直接输入程序的exe文件名,来运行程序。
    而在非Windows系统中,需要通过 dotnet 命令来运行 .NET 程序。且命令行参数里不是传递主程序的exe文件名,而应该传递主程序的dll文件名。
    详见官方文档,摘录:

    运行应用程序:  .NET CLI dotnet [--additionalprobingpath <PATH>] [--additional-deps <PATH>]     [--fx-version <VERSION>]  [--roll-forward <SETTING>]     <PATH_TO_APPLICATION> [arguments]  dotnet exec [--additionalprobingpath] [--additional-deps <PATH>]     [--depsfile <PATH>]     [--fx-version <VERSION>]  [--roll-forward <SETTING>]     [--runtimeconfig <PATH>]     <PATH_TO_APPLICATION> [arguments] 

    4.1 运行 .NET 7.0 程序

    可以在其他电脑上开发程序,然后将编译后的文件,拷贝到ARM服务器上再运行。平台(Platform)选 AnyCPU 就行,无需特意选 ARM64。且不用发布(Publish),直接将“bin”文件夹下的 Debug或Release目录 拷贝过去就行。
    于是我将前段时间开发的 VectorClassDemo 程序拷贝了过去,顺便能检查一下 .NET 对ARM的内在函数的支持性。将该程序分别用 .NET 5.0/7.0编译一下,然后拷贝过去。

    若想将文件拷贝到远程的服务器上,可以用 scp 等命令。或者可以用RDP远程桌面连接过去,在本机复制文件,然后在远程桌面的文件管理器中粘贴,便能将文件复制过去。
    文件复制成功后,进入程序所在目录,然后便可以用 dotnet 命令来执行程序了。例如我的这个程序的主程序的dll文件名为“VectorClassDemo50.dll”,于是语句为“sudo /root/.dotnet/dotnet ./VectorClassDemo50.dll”。
    在ARM处理器的Ubuntu系统上安装 .NET SDK(Core 3.1~7.0),并检测ARM内在函数的支持情况

    输出信息摘录如下:

    ubuntu@ip-175-76-22-54:~/Documents/VectorClassDemo50/net7.0$ sudo /root/.dotnet/dotnet ./VectorClassDemo50.dll VectorClassDemo50  IsRelease:	True EnvironmentVariable(PROCESSOR_IDENTIFIER):	 Environment.ProcessorCount:	2 Environment.Is64BitOperatingSystem:	True Environment.Is64BitProcess:	True Environment.OSVersion:	Unix 5.15.0.1023 Environment.Version:	7.0.0 RuntimeEnvironment.GetRuntimeDirectory:	/root/.dotnet/shared/Microsoft.NETCore.App/7.0.0/ RuntimeInformation.FrameworkDescription:	.NET 7.0.0 BitConverter.IsLittleEndian:	True IntPtr.Size:	8 Vector.IsHardwareAccelerated:	True Vector<byte>.Count:	16	# 128bit Vector<T>.Assembly.CodeBase:	file:///root/.dotnet/shared/Microsoft.NETCore.App/7.0.0/System.Private.CoreLib.dll  [Intrinsics.Arm] AdvSimd.IsSupported:	True AdvSimd.Arm64.IsSupported:	True Aes.IsSupported:	True Aes.Arm64.IsSupported:	True ArmBase.IsSupported:	True ArmBase.Arm64.IsSupported:	True Crc32.IsSupported:	True Crc32.Arm64.IsSupported:	True Dp.IsSupported:	True Dp.Arm64.IsSupported:	True Rdm.IsSupported:	True Rdm.Arm64.IsSupported:	True Sha1.IsSupported:	True Sha1.Arm64.IsSupported:	True Sha256.IsSupported:	True Sha256.Arm64.IsSupported:	True  -- Single, Vector<Single>.Count=4 -- srcT:	<-3.4028235E+38, Infinity, NaN, -1.2>	# (FF7FFFFF 7F800000 FFC00000 BF99999A) srcAllOnes:	<NaN, NaN, NaN, NaN>	# (FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF) Abs(srcT):	<3.4028235E+38, Infinity, NaN, 1.2>	# (7F7FFFFF 7F800000 7FC00000 3F99999A) 

    可以看到:

    • 该程序正确的以“64位 .NET 7.0 程序”的方式在运行。
    • 向量类型支持硬件加速(Vector.IsHardwareAccelerated),且向量类型的长度为 128bit。这是因为ARM的 AdvSimd 指令集的数据长度最长为128位。
    • 目前的所有ARM内在函数(Intrinsics.Arm)的IsSupported都是true,表示都支持。

    4.2 运行 .NET 5.0 程序

    随后又尝试运行了 .NET 5.0编译的程序。

    ubuntu@ip-175-76-22-54:~/Documents/VectorClassDemo50/net5.0$ sudo /root/.dotnet/dotnet ./VectorClassDemo50.dll VectorClassDemo50  IsRelease:	True EnvironmentVariable(PROCESSOR_IDENTIFIER):	 Environment.ProcessorCount:	2 Environment.Is64BitOperatingSystem:	True Environment.Is64BitProcess:	True Environment.OSVersion:	Unix 5.15.0.1023 Environment.Version:	5.0.17 RuntimeEnvironment.GetRuntimeDirectory:	/root/.dotnet/shared/Microsoft.NETCore.App/5.0.17/ RuntimeInformation.FrameworkDescription:	.NET 5.0.17 BitConverter.IsLittleEndian:	True IntPtr.Size:	8 Vector.IsHardwareAccelerated:	True Vector<byte>.Count:	16	# 128bit Vector<T>.Assembly.CodeBase:	file:///root/.dotnet/shared/Microsoft.NETCore.App/5.0.17/System.Private.CoreLib.dll  [Intrinsics.Arm] AdvSimd.IsSupported:	True AdvSimd.Arm64.IsSupported:	True Aes.IsSupported:	True Aes.Arm64.IsSupported:	True ArmBase.IsSupported:	True ArmBase.Arm64.IsSupported:	True Crc32.IsSupported:	True Crc32.Arm64.IsSupported:	True Dp.IsSupported:	False Dp.Arm64.IsSupported:	False Rdm.IsSupported:	False Rdm.Arm64.IsSupported:	False Sha1.IsSupported:	True Sha1.Arm64.IsSupported:	True Sha256.IsSupported:	True Sha256.Arm64.IsSupported:	True  -- Single, Vector<Single>.Count=4 -- srcT:	<-3.4028235E+38, Infinity, NaN, -1.2>	# (FF7FFFFF 7F800000 FFC00000 BF99999A) srcAllOnes:	<NaN, NaN, NaN, NaN>	# (FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF) Abs(srcT):	<3.4028235E+38, Infinity, NaN, 1.2>	# (7F7FFFFF 7F800000 7FC00000 3F99999A) 

    发现用 .NET 5.0 运行时,部分ARM内在函数是不被支持的,例如 Dp、Rdm。
    而之前查看 cpuinfo信息 时,Features里有 asimddp、asimdrdm,且刚才用 .NET 7.0 测试时是支持的。看来硬件是支持的,只是 .NET 5.0 软件不支持而已。
    即:虽然 .NET 5.0 定义了ARM内在函数,但是在某些平台上的.NET 5.0运行时,没能支持所有的内在函数。直到 .NET 7.0,才全部解决了内在函数的支持性问题。

    参考文献