dotnet / iot

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

Is there a reason Iot.Device.Bindings is not based on .netstandard2.1 instead of netcoreapp2.1? #690

Closed hugener closed 1 year ago

hugener commented 5 years ago

It seems like a pity not to have this as a .netstandard library. It builds if I add the following packages:

System.Collections.Immutable could even be avoided, if using ReadOnlyDictionary instead of ImmutableDictionary would be okay. Both implement IReadOnlyDictionary, which is what is exposed.

Is it related to the dependency on System.Drawing.Common? I just wonder because it is only used in RgbLedMatrix and if that's the case, wouldn't it be better to split the Bindings into two libraries? So that most of them can be .netstandard and a second one with the remaining ones that must be .netcoreapp.

Are there any other reasons I'm unaware of why .netcoreapp would be preferred over .netstandard?

joperezr commented 5 years ago

Hey @hugener thanks for logging this. The reason why it today targets netcoreapp2.1 is because at the time we introduced it and designed it netstandard2.1 wasn't defined yet, and netstandard2.0 didn't contain some types that its implementation requires. That said, netsatndard2.1 is fully defined now and so your point is very valid and we might want to re-think this one. I wouldn't see a problem of re targeting this in case the existing binding code does compile against netstandard2.1 + some additional packages.

Taking the above into an aside for just a second though, I'm now interested in where is it that you plan on using this package that .NET Core doesn't run? System.Device.Gpio package targets netstanard2.0 because one of the devices we wanted to target was the raspberry Pi Zero which can't run .NET Core but does run Mono which is netstandard2.0 compliant, but if we targetted netstandard2.1 I'm not sure of which kind of devices (that exist in the market today) would benefit that are compatible with Gpio and all these sensors.

krwq commented 5 years ago

@hugener if you have specific code changes you'd like to see to move us to netstandard2.1 (even partial progress) it would be really helpful.

I personally don't mind either way but if it helps someone to move us to netstandard and there is an easy path then why not

hugener commented 5 years ago

Hi @joperezr and @krwq,

Thank you for taking the time to look into this. I'm working on an RPI project that uses an old C# api for RPI: https://github.com/hugener/Pi (I actually forked it to fix some bugs as well).

As it's no longer maintained and has no RPI x64 support (I use Arch Linux arm), I wanted to explore the possibility of replacing it with System.Device.Gpio and Iot.Device.Bindings. Some of the libraries I have, are based on .netstandard2.0, but the runtime is .netcore2.2, so in that sence it is pure convenience to have .netstandard support. Before I wrote the issue, I actually tried changing the framework to 2.0 and 2.1 and noticed that things like Math.Clamp was missing in 2.0. That's why I ended up writing the issue with 2.1 in mind, but actually I would prefer to have 2.0 support. After your comments I revisited supporting 2.0 and did a pull request here: https://github.com/dotnet/iot/pull/704 It compiles, but I have no means of testing and some code change are not so nice like MathEx.Clamp and the alternative for MemoryMarshal, but maybe you can have a look? Perhaps we could do some multitargeting and #ifs to use the cleaner code on supported platforms while still supporting 2.0?

krwq commented 5 years ago

@hugener I'd prefer if we've targeted netstandard2.1 so that we don't need to duplicate the code and make people move forward to later versions of .NET. In case if it's absolutely necessary we can always re-target to lower version safely.

krwq commented 5 years ago

@hugener talked with @joperezr about this and he brought a point that mono currently supports only netstandard2.0 so I'm fine with re-targetting to 2.0 because that will unblock Raspberry Pi Zero scenarios.

Note that any PRs will need to wait after 3.0 since we are currently trying to stabilize

hugener commented 5 years ago

That sounds great. Let me know if/when I can assist more with this. Should rephrase the issue to reflect .netstandard2.0?

krwq commented 5 years ago

@hugener let's try to get your PR merged, whenever we have an opportunity it would be great to test this code with mono to ensure this is the only thing blocking it from working

hugener commented 5 years ago

I updated my branch so it should be able to merge now.

joperezr commented 5 years ago

Note that any PRs will need to wait after 3.0 since we are currently trying to stabilize

I have now forked for release/3.0 so all PRs merged to master will be now for vNext just as FYI

hugener commented 5 years ago

Are prereleases based on master released to nuget?

krwq commented 5 years ago

@hugener we only occasionally publish to nuget from master - i.e. for previews (right now it likely won't happen for some time), for nightly builds use these instructions which use nightly package feeds: https://github.com/dotnet/iot#net-cli

joperezr commented 5 years ago

as @krwq points out most of our prereleases in nuget.org currently are for 3.0 specifically and don't have immediate plans of pushing to NuGet new builds out of the master branch. That said, we still continue pushing all of these to the feeds that he pointed out, and these are signed packages so it should be straight forward to just reference those if you needed to. If you have any issues please let us know.

hugener commented 5 years ago

Thanks for pointing that you!

MarkCiliaVincenti commented 4 years ago

Is this still WIP?

assert-not-singularity commented 4 years ago

Hi altogether!

I want to deploy a .NET application to a Raspberry Pi Zero as well and I'd prefer to use .NET Core. Since the Pi Zero is not compatible with .NET Core, currently I'm developing the application as platform-dependent library on .NET SDK 3.1 and targeting netstandard2.1 which allows me to use Mono 5.18 as runtime on the Pi. Of course, this is not ideal but should do it until .NET 5 is released and Mono is able to run .NET 5 applications.

If I understand it correctly, setting netstandard2.0 was an issue because there are dependencies to netstandard2.1 and code had to be duplicated. But since Mono supports netstandard2.1 by now, couldn't be this set as the new target? This would allow developers to use the bindings on the Raspberry Pi Zero as well until there is support for .NET 5 in Mono or the .NET 5 runtime supports the Pi Zero.

krwq commented 4 years ago

I believe mono can be now used if you target full framework. @joperezr do you remember specific TFM (-f switch in dotnet command) you have to pass?

If we're gonna re-target to netstandard then I'd prefer if we created tiny compat shim so that we can quickly switch it back once we get proper support

joperezr commented 4 years ago

If we change IoT.Device.Bindings package to target netstandard2.1 instead of netcoreapp2.1 then we would drop netcoreapp2.1 support because netcoreapp2.1 doesn't support netstandard2.1. We could dual-target but we haven't done that yet. My advice for now is that if you have an app and you want to use it with Mono, you should create your Mono project and then copy the binding's source that you need into your project to see if it compiles against the framework you are targetting and use it like that for now.

I believe mono can be now used if you target full framework. @joperezr do you remember specific TFM (-t switch in dotnet command) you have to pass?

you can do dotnet publish -f net461. Mono doesn't really have a framework moniker, usually one from .NET Framework is used instead, as Mono is just a runtime.

assert-not-singularity commented 4 years ago

Thanks for your fast replies! It's a pity that netstandard2.1 would break support for netcoreapp2.1.

To get my app running, I copied the source files of MCP devices I'm interested in into my project and it works fine. I hope this also works with other devices such as display drivers.

I also tried to build against net461 but this prevents me from developing with WSL since .NET Framework 4.6 is not available on Linux afaik. Also, I'd prefer don't break compatibility to .NET Core because I'd like to have the option to switch to the .NET Core runtime on a Raspberry Pi 3 or upgrade to .NET 5 on the Zero as soon as it's released.

raghur commented 4 years ago

I'm interested in this as well - I'm trying to interface with a NRF24 radio on an RPi and because IoT.Device.Bindings targets netcoreapp2.1, my project can't be platform independent and this bubbles upwards. Are there any plans to target both netstandard2.1 and netcoreapp2.1 in the near future? Or should I just copy the source of devices I need?

pgrawehr commented 4 years ago

What hardware are you trying to run on? Rpi 3 and 4 work fine with .Net core 3 (and in future also 5)

assert-not-singularity commented 4 years ago

I'm using a Raspberry Pi Zero W which is unfortunately not able to run .NET Core 3 due to some limitations regarding the instruction set (ARMv7, IIRC).

pgrawehr commented 4 years ago

Armv7 basically works, Rpi3 and 4 usually run in 32bit mode as well. There were some limitations for the Pi Zero, but I don't know whether they still apply. Have you tried Net5.0? ( Use preview 4)

raghur commented 4 years ago

What hardware are you trying to run on? Rpi 3 and 4 work fine with .Net core 3 (and in future also 5)

On RPI 2 Model B+

assert-not-singularity commented 4 years ago

Armv7 basically works, Rpi3 and 4 usually run in 32bit mode as well. There were some limitations for the Pi Zero, but I don't know whether they still apply. Have you tried Net5.0? ( Use preview 4)

The Raspberry Pi Zero's CPU is based on ARMv6 according to Wikipedia. This might be the reason why this happens on my Raspi:

pi@raspberrypi:~ $ tar zxf dotnet-sdk-5.0.100-rc.1.20452.10-linux-arm.tar.gz -C $HOME/dotnet
pi@raspberrypi:~ $ dotnet --version
Segmentation fault
pi@raspberrypi:~ $

Edit: Related discussion on the dotnet/runtime repository here: https://github.com/dotnet/runtime/issues/7764

pgrawehr commented 4 years ago

Yea, that looks like the core of the problem. I fear then there's not much we can do here :-(

joperezr commented 4 years ago

That's not entirely true though, the library with the protocol implementations (System.Device.Gpio) targets .NetStandard 2.0 which is supported by Mono which runs on the Pi Zero. There was an initial prototype on a PR once that was making the bindings target net standard as well but that had some workarounds due to some missing API required by some bindings that was less than ideal ( the pr was basically copy pasting the implementation of the missing methods from dotnet/runtime)

One thing you could do is to copy create a Mono application and then copy the source of the binding you want to use for now, and that will most likely be fine as most of our bindings are .netstandard 2.p compatible.

One thing we can consider for the bindings package, is to have two assets in the package; one that targets .net standard which has only the bindings that don't require additional API, and one that targets .net core which has all of the bindings.

Ellerbach commented 4 years ago

If you want to see examples, I build few here: https://github.com/Ellerbach/Nabaztag.Net

Note: for most of the bindings I'm using, some adaptations are needed, usually quite straight forward. All up, it's working really good at the end of the day. Not the native performance from .NET Core but largely enough for most scenarios.

assert-not-singularity commented 4 years ago

@joperezr, thanks for pointing that out! I did exactly that and created a Mono application by copying the bindings from this repository into my project. This works fine.

However, I hoped that I would be able to just reference the library using NuGet with the coming .NET 5 framework since Mono merges into the .NET framework somehow. But it seems that ARMv6 is still a show-stopper for modern .NET Core applications.

JaggerJo commented 4 years ago

@assert-not-singularity @Ellerbach doing the exact same thing so I can run it on a RBP zero (w). I'm also considering to get a banana Pi zero because that features an ARMv7 cpu..

krwq commented 1 year ago

[Triage] We support netstandard2.0. See https://www.nuget.org/packages/Iot.Device.Bindings/2.3.0-prerelease.22520.10#dependencies-body-tab