Reputation: 860
I want to build an ASP.NET Core Web API service to run on an arm (cortex-A7) device with an angstrom based linux.
Question: What is the best route to follow?
My main concern is the angstrom distribution, which is not supported by dotnet core out of the box. Any advice is welcome!
Edit, Open Questions:
Upvotes: 6
Views: 8777
Reputation: 860
First, forget about angstrom. You will not get any of the native dependencies from that distro or its package manager. Neither will you find any useful resources for angstrom.
Instead, use yocto to build your own OpenEmbedded Core linux distro and add native dependencies during the build. At the time of writing, this can be managed with the meta-aspnet layer from Tragetaschen. The readme.md
states mono as a requirement, which is not true (anymore?).
Once the native dependencies (libunwind, libicu, and many more) are available on the arm system, you can download the latest Linux (armhf) (for glibc based OS)
build from https://github.com/dotnet/core-setup, unpack it into /opt/dotnet/
, and create a symlink via ln -s /opt/dotnet/dotnet /usr/bin/
. This is the OP's solution number 1 and generic bytecode projects (just dotnet publish
) will work fine.
If you don't like to install dotnet on the target machine, you can compile for -r linux-arm
(Martin Ulrich's suggestion), which produces a huge publish folder including coreclr and corefx. However, installing dotnet on the target machine is the smallest of all problems and separating your app from dotnet coreclr/fx/host is cleaner (imho).
The key problems are
The meta-aspnet
layer seems to solve both problems (at the time of writing). You'll have to dig into it for more details or just use it as is.
Upvotes: 3
Reputation: 860
Based on Martin Ulrichs suggestions I had partial success in cross-compiling a self-contained executable for arm. The code is cross-compiled on a Ubuntu.16.04-x64
machine and runs on a raspberry pi 2 (GNU/Linux 4.1.17-v7+ armv7l
) without installing the dotnet runtime on the PI.
On the build machine, Ubuntu.16.04-x64 with dotnet --version = 2.0.0-preview1-005977
, run the following:
mkdir foobar; cd foobar
dotnet new console
dotnet restore -r linux-arm
dotnet publish -r linux-arm
This produces a 31MB publish folder with 174 files. Copy those over to the arm device. Note that the resulting executable will not run on the build machine (wrong architecture).
On the arm device
First, you have to install some required libraries for the dotnet runtime. Unfortunatley this is debian, and probably not suitable for angstrom (this is why I don't mark this as answer). I picked only non-dev prerequisites from here, since the app is not compiled on the PI.
sudo apt-get install libunwind8 libicu52 gettext liblttng-ust-ctl2 liblttng-ust0
This list may contain too much / not enough depending on the actual application. Finally, run the self-contained application
chmod +x bin/Debug/netcoreapp2.0/linux-arm/publish/foobar
bin/Debug/netcoreapp2.0/linux-arm/publish/foobar
The execution speed (slow as hell for writing "Hello World!" to the console) indicates that this is actually byte code bootstrapped by some kind of included dotnet clr.
Upvotes: 2
Reputation: 100641
You can use the portable linux-arm
runtime build of .NET Core.
On your build machine, make sure that dotnet --version
returns a 2.0
, preview, or higher version (at the time of writing: 2.0.0-preview1-005977
).
dotnet new mvc
dotnet restore -r linux-arm
dotnet publish -r linux-arm /p:MvcRazorCompileOnPublish=false
bin/Debug/netcoreapp2.0/linux-arm/publish
to your target machine and run with ./nameOfTheProject
Since you probably want to develop locally as well, you'd want to edit the project (.csproj
) file like this (<PropertyGroup>
):
<RuntimeIdentifiers>linux-arm</RuntimeIdentifiers>
<MvcRazorCompileOnPublish Condition=" '$(RuntimeIdentifier)' != 'linux-arm' ">true</MvcRazorCompileOnPublish>
This way you can use both dotnet restore
, dotnet run
and dotnet publish
during development or other deploys without additional parameters and when ready to deploy to arm, only use:
dotnet publish -c Release -r linux-arm
and use the resulting binaries from bin/Release/netcoreapp2.0/linux-arm/publish
(or pass an additional -o ../publish-output
argument)
Upvotes: 5