dotnet / iot

This repo includes .NET Core implementations for various IoT boards, chips, displays and PCBs.
MIT License
2.18k stars 585 forks source link

libhostfxr.so could not be found on Raspberry Pi #867

Closed gingters closed 4 years ago

gingters commented 4 years ago

Describe the bug

On a Raspberry Pi I added the System.Device.Iot and Iot.Device.Bindings libs to an empty .net core 3 console application to display text on an I2C LCD display.

Running the program resulted in an err "A fatal error occurred. The required library libhostfxr.so could not be found."

Steps to reproduce

On a Raspberry Pi 3 Model B+ with latest Raspbian install .NET Core SDK 3.0.100. Then create a new project using dotnet new console and install System.Device.Iot and Iot.Device.Bindings NuGet packages (both version 1.0).

Then use the following main method.

using System;
using System.Device.I2c;
using Iot.Device.CharacterLcd;

namespace GpioTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            try
            {
                var lcd = new Lcd1602(I2cDevice.Create(new I2cConnectionSettings(0, 27)));
                lcd.Write("Hello World");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
        }
    }
}

Expected behavior

The application should start and write text to the I2C Display.

Actual behavior

The following error message is shown:

A fatal error occurred. The required library libhostfxr.so could not be found.
If this is a self-contained application, that library should exist in [/home/pi/dev/dotnetgpiotest/GpioTest/bin/Debug/netcoreapp3.0/].
If this is a framework-dependent application, install the runtime in the global location [/usr/share/dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location or register the runtime location in [/etc/dotnet/install_location].

Versions used

Add following information:

pi@raspidev:~/dev/dotnetgpiotest/GpioTest $ dotnet --info
.NET Core SDK (gemäß "global.json"):
 Version:   3.0.101
 Commit:    bc5f8df0f5

Laufzeitumgebung:
 OS Name:     raspbian
 OS Version:  10
 OS Platform: Linux
 RID:         linux-arm
 Base Path:   /home/pi/dotnet-arm32/sdk/3.0.101/

Host (useful for support):
  Version: 3.0.1
  Commit:  19942e7199

.NET Core SDKs installed:
  3.0.101 [/home/pi/dotnet-arm32/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.App 3.0.1 [/home/pi/dotnet-arm32/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.0.1 [/home/pi/dotnet-arm32/shared/Microsoft.NETCore.App]

1.0.0

1.0.0

krwq commented 4 years ago

@gingters how did you run the app? dotnet run or dotnet publish -r linux-arm + running produced exe?

gingters commented 4 years ago

I'm using dotnet run, as I'm on the Pi itself.

I think I figured it out partially though. When I SSH into the Pi using putty and run it, I get different errors about not implemented methods, but the so can be loaded.

When I use VS Code to remote-ssh into the Pi, and use dotnet run from the VS Code terminal, it doesn't work.

For whatever reasons, printenv shows that the DOTNET_ROOT environment variable is set on plain ssh (putty), but the environment variable is not set when I'm in the VS Code terminal on the Pi.

So I guess I have an issue with VS Code and not with this lib directly. Will report back when I have new info.

gingters commented 4 years ago

Didn't figure it out. No matter how often I closed vs code and reconnected the remote server, the environment variable was not set. After a reboot of the Pi it worked, as the variable was then set. Sorry to bother you.

krwq commented 4 years ago

@gingters I think if you somehow get a consistent repro it might be beneficial for community to report the issue on the vscode repo. Without repro though I'm not expecting this will get fixed though

pouncer29 commented 4 years ago

I was able to reproduce. I'm running from the command line and my DOTNET_ROOT was set to $HOME/path/to/my/sdk. Changing it to an absolute path fixed this issue for me.

eg. export DOTNET_ROOT=/home/pi/path/to/my/sdk

AArnott commented 3 years ago

I see it on my Raspberry Pi 4 as well. After using ~/dotnet-install.sh -c Current to install 5.0, I get the error:

$ dotnet run -p hello
A fatal error occurred. The required library libhostfxr.so could not be found.
If this is a self-contained application, that library should exist in [/home/pi/git/hello/bin/Debug/net5.0/].
If this is a framework-dependent application, install the runtime in the global location [/usr/share/dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location or register the runtime location in [/etc/dotnet/install_location].

The .NET runtime can be found at:
  - https://aka.ms/dotnet-core-applaunch?missing_runtime=true&arch=arm&rid=raspbian.10-arm&apphost_version=5.0.7

dotnet itself is evidently on the PATH:

$ whereis dotnet
dotnet: /home/pi/.dotnet/dotnet

But the error above happens until I also do export DOTNET_ROOT=/home/pi/.dotnet/, after which it works.

So... why does DOTNET_ROOT have to be set when dotnet should arguably be able to find its own runtime based on where dotnet itself is?

Ironically, dotnet publish hello -r linux-arm followed by hello/bin/Debug/net5.0/linux-arm/publish/hello works just fine, without any DOTNET_ROOT env var. So the SDK can find the files necessary to build a self-contained executable, but apparently can't find enough to run a FDD one. Go figure.