intel-iot-devkit / meta-iot-cloud

OpenEmbedded layer to add support for multiple cloud IoT services including Microsoft Azure & Google Cloud Platform.
MIT License
69 stars 80 forks source link

dotnet: update to version 6.0 #106

Closed ghost closed 2 years ago

ghost commented 2 years ago

I've bumped dotnet to lts release version 6.0

srware commented 2 years ago

Thanks for the PR @Pan5ky, unfortunately this fails for me with current master due to the following error:

ERROR: dotnet-6.0.100-r0 do_package_qa: QA Issue: /usr/share/dotnet/shared/Microsoft.NETCore.App/6.0.0/libcoreclrtraceptprovider.so contained in package dotnet requires liblttng-ust.so.0()(64bit), but no providers found in RDEPENDS:dotnet? [file-rdeps]

It seems this library is compiled against liblttng-ust.so.0 but the latest lttng-ust package ships liblttng-ust.so.1

I would say there are 2 possibilities:

  1. Blank out libcoreclrtraceptprovider.so to effectively remove it (not ideal for anyone who depends on it I suppose?)

echo "" > ${D}${datadir}/dotnet/shared/Microsoft.NETCore.App/${RUNTIME}/libcoreclrtraceptprovider.so

  1. The other option would be to do a bbappend for lttng-ust and create a symlink liblttng-ust.so.1->liblttng-ust.so.0 so runtime dependencies are satisfied.
Livius90 commented 2 years ago

Please use DOTNET_RUNTIME variable name instead of RUNTIME in declaration of RUNTIME = "6.0.0" or any similar different name. In some other BSP layers it can be declared as RUNTIME = "gnu" global variable, i had some conflict in this name concept in Xilinx BSP Yocto.

Livius90 commented 2 years ago

Thanks for the PR @Pan5ky, unfortunately this fails for me with current master due to the following error:

ERROR: dotnet-6.0.100-r0 do_package_qa: QA Issue: /usr/share/dotnet/shared/Microsoft.NETCore.App/6.0.0/libcoreclrtraceptprovider.so contained in package dotnet requires liblttng-ust.so.0()(64bit), but no providers found in RDEPENDS:dotnet? [file-rdeps]

It seems this library is compiled against liblttng-ust.so.0 but the latest lttng-ust package ships liblttng-ust.so.1

I would say there are 2 possibilities:

  1. Blank out libcoreclrtraceptprovider.so to effectively remove it (not ideal for anyone who depends on it I suppose?)

echo "" > ${D}${datadir}/dotnet/shared/Microsoft.NETCore.App/${RUNTIME}/libcoreclrtraceptprovider.so

  1. The other option would be to do a bbappend for lttng-ust and create a symlink liblttng-ust.so.1->liblttng-ust.so.0 so runtime dependencies are satisfied.

By the way, this issue was reported in dotnet runtime repo also. https://github.com/dotnet/runtime/issues/57784

ghost commented 2 years ago

Hi @srware,

I changed the runtime variable like @Livius90 suggested. I also tried creating a symlink like you suggested but that did not work for me and I was not able to resolve it. I also would like to mentioning that this issue is not specific to this PR but also occurs on the current master branch so it may be good to open a separate issue for that.

Livius90 commented 2 years ago

There is a new release for .NET 6.0 with some security fix. It is .NET SDK 6.0.101, can you try to use this newest in this recipe? Soon there will be a .NET SDK 6.0.200, it is now in preview state.

srware commented 2 years ago

@Pan5ky , agree this issue is mostly due to dependency version bumps in master and needs fixing in upstream also so I won't let that block merging. As @Livius90 mentioned there is a new point release. Could you update to the latest 6.0 release and squash the multiple commits to a single commit for the PR and I will get it merged.

Thanks

Livius90 commented 2 years ago

Here is the solution for liblttng-ust issue: https://github.com/dotnet/runtime/issues/62398#issuecomment-1014581653 So, need to upgrade to the new lttng-ust 2.13.1 or any newer version, in openembedded-core layer lttng-ust 2.13.1 is available from end of december. I suggest to wait for latest .NET SDK 6.0.200 then need to test the recipe with lttng-ust 2.13.1.

srware commented 2 years ago

Thanks for digging into this @Livius90 . Do we have confirmation that the next .NET 6.0.200 binary release will be compiled against the fixed lttng-ust version or will this only work if the recipe builds from source?

omajid commented 2 years ago

Hi, I am a developer who works with the .NET project upstream as well as a maintainer in the Fedora project. I am not a Yocto user, so please take my advice with a grain of salt.

If I understand this PR correctly, this is about the prebuilt .NET (not one that is being built from source as a part of Yocto).

The prebuilt .NET Runtime has a dependency on liblttng-ust.so.0()(64bit), and isn't compatible with liblttng-ust.so.1()(64bit) - this is very different from, for example, the dependency on OpenSSL where .NET 6 will work with pretty much any version of OpenSSL (1.0, 1.1 or 3.0). There's an ABI break between liblttng-ust.so.0 and liblttng-ust.so.1 and the prebuilt .NET is simply not prepared to handle the new version in anyway.

Updating lttng-ust to the latest bugfix release of 2.13 doesn't fix that: .NET will continue looking for the older, missing, library.

This is an issue that affects all currently supported versions of .NET - 3.1, 5.0 and 6.0. It doesn't have anything to do with the update to 6.0. And I see no plans that this will be fixed with any upcoming releases of .NET.

I do think that if someone was to come up with a fix, upstream .NET maintainers would be receptive to it. But I haven't seen anything being proposed yet.

I would say there are 2 possibilities:

I think the second option, which creates a fake liblttng-ust.so.0, may keep the QA dependency resolver happy, but because of the ABI change in lttng-ust, still results in something that doesn't work for .NET. Worse, it may actually lead to segfaults and cause .NET to crash at runtime when it accidentally loads liblttng-ust.so.1 which has a different ABI than .NET is expecting.

I think a variant of the first option, where we "break" libcoreclrtraceptprovider.so might actually be better.

The features provided by libcoreclrtraceptprovider.so are more useful to lower level profiling/debugging of the .NET runtime itself than something .NET users might expect to do. It's unlikely a user building or running .NET applications will need it. .NET itself is prepared for the case that a dependency for libcoreclrtraceptprovider.so (like lttng-ust!) is missing and silently (and gracefully) stops loading libcoreclrtraceptprovider.so but otherwise continues to work just fine.

So, if we ignore QA and just install .NET (with the dependency liblttng-ust.so.0 missing) things should Just Work. Is there some way to tell QA to ignore libcoreclrtraceptprovider.so contained in package dotnet requires liblttng-ust.so.0()(64bit)? On Fedora, we would filter out the automatic dependency. I don't know the analogue for Yocto.

And if someone really needs libcoreclrtraceptprovider.so, well, they will have to get a working liblttng-ust.so.0 anyway before they can use any .NET version with it.

Livius90 commented 2 years ago

@omajid Thanks the infos. Can you help in that what version of lttng-ust can provide the compatible version of liblttng-ust.so.0? QA issue can be ignored but not a nice solution, my idea is that we could some how integrate the compatible liblttng-ust source downloading in dotnet recipes then we can compile and install correct but old liblttng-ust.so.0 to lib folder by manual recipe commands.

omajid commented 2 years ago

With my Fedora maintainer hat on:

That said, https://github.com/dotnet/runtime/issues/57784 suggests that the so name changed between 2.12 and 2.13. So lttng-ust 2.12 should produce a liblttng-ust.so.0

On Fedora 35, I have lttng-ust-2.12.2 which provides /usr/lib64/liblttng-ust.so.0.0.0. On Fedora 36, lttng-ust-2.13.1 is present and provides /usr/lib64/liblttng-ust.so.1.0.0. That matches with what's reported on that linked issue.

tmds commented 2 years ago

Can you try building with export DOTNET_LTTng=0? That should stop .NET from trying to load libcoreclrtraceptprovider.so which is the library that needs liblttng-ust.so.0.

srware commented 2 years ago

I tend to agree with @omajid here that effectively blanking out libcoreclrtraceptprovider.so to remove the QA issue and admittedly the functionality it provides is likely the best short-term solution to this. @Livius90 I don't really want to re-add an old lttng-ust recipe in this layer which fights against Openembedded upstream and will likely cause issues with other packages.

The only other option I see is we start building from source and not simply pulling in the pre-compiled binaries. Happy to explore that option if it is viable but it's not a "quick fix". @tmds I assume what you mentioned only applies when building from source?

tmds commented 2 years ago

The envvar works with any version of .NET and it is the way to stop .NET from loading libcoreclrtraceptprovider.so.

After reading through the issue again, I realize this is not about the issues that happen at runtime (.NET crashing when built against v2.13.0: https://github.com/dotnet/runtime/issues/62398, and .NET not supporting tracing with v2.13+: https://github.com/dotnet/runtime/issues/57784).

When lttng-ust is not available, .NET works fine and the tracing is not enabled. Microsoft packages don't specify lttng-ust as a dependency.

Telling your QA tooling to ignore the missing dependency would be most similar to how Microsoft is packaging .NET.

Otherwise you can remove/corrupt the libcoreclrtraceptprovider.so.

Livius90 commented 2 years ago

The envvar works with any version of .NET and it is the way to stop .NET from loading libcoreclrtraceptprovider.so.

After reading through the issue again, I realize this is not about the issues that happen at runtime (.NET crashing when built against v2.13.0: dotnet/runtime#62398, and .NET not supporting tracing with v2.13+: dotnet/runtime#57784).

When lttng-ust is not available, .NET works fine and the tracing is not enabled. Microsoft packages don't specify lttng-ust as a dependency.

Telling your QA tooling to ignore the missing dependency would be most similar to how Microsoft is packaging .NET.

Otherwise you can remove/corrupt the libcoreclrtraceptprovider.so.

Can you help and send a link about how works .NET SDK 6 building in Linux? Yocto automaticaly support many building processes like CMake, Make, Autoconf if it has any Linux friendly build script method, it is easy to compile from GitHub source in a yocto recipe.

omajid commented 2 years ago

Can you help and send a link about how works .NET SDK 6 building in Linux?

The short version is at https://github.com/dotnet/installer/#building-source-build.

This was tested with the v6.0.100 tag in dotnet/installer repo. The v6.0.101 tag has some bugs that are fixed by later commits in the release/6.0.1xx branch. If you run into any issues, please open an issue in https://github.com/dotnet/source-build/issues where a lot of folks building .NET from source hang out.

Livius90 commented 2 years ago

Does it buildable by GCC only or do we need to use any other compiler, too?

omajid commented 2 years ago

From the Fedora build scripts, the dependencies for building .NET 6 are: clang cmake coreutils git hostname krb5-devel libicu-devel llvm lttng-ust-devel make openssl-devel python3 tar util-linux zlib-devel

It might be possible to build using gcc instead of clang, but I am not sure how well tested that is.

During build (actually, as part of ./prep.sh), .NET will download a .NET SDK and related binaries, because most of the .NET source code is written in a language (eg, C#) which needs a .NET compiler to compile. If you have a recent build of .NET 6, you can provide the SDK and the binaries built alongside the SDK as arguments to the ./build.sh script which will avoid needing to download anything.

Livius90 commented 2 years ago

If gcc can be used instead of clang it should works in Yocto project build beacuse any other dependencies are easily available. Is your Fedora package build script open-source? Can we look it how starting? For Yocto the most suitable could be if it would be a real CMake project for dotnet SDK, in this case a CMakeLists.txt can be executed automatically by Yocto bitbake.

omajid commented 2 years ago

If gcc can be used instead of clang it should works in Yocto project build beacuse any other dependencies are easily available.

Sounds worth a try... Can you try it out and see how it goes? We (.NET folks) can probably help out and offer some guidance, but I am not sure we can spare the time right now to verify that this works end to end (and fix any issues that come up).

Is your Fedora package build script open-source?

Yup. Fedora is completely open source! We are not allowed to do anything proprietary.

Can we look it how starting?

Our complete set of build scripts and patches are here: https://src.fedoraproject.org/rpms/dotnet6.0/tree/rawhide

If you aren't familiar with rpm spec files, the meat of the build script is between the %prep and %check sections at https://src.fedoraproject.org/rpms/dotnet6.0/blob/rawhide/f/dotnet6.0.spec#_373

Before running the build via RPM, we generate a source tarball by running ./build.sh /p:ArcadeBuildTarball=true /p:TarballDir=/path/to/place/complete/dotnet/sources in a checkout of the dotnet/installer repo. This is automated via a script. Then we run the build scripts in the RPM spec file.

The RPM spec file describes the build steps. It unpacks the tarball, applies some patches, does some other fixes, sets some environment variables and then run the ./build.sh script to build all of .NET. It then unpacks the .NET SDK that's built into the final install location, along with a bunch of other useful things (like man pages).

The other non-obvious part is bootstrapping. Please note that it's completely optional and only required one time. We needed it for Fedora because Fedora forbids prebuilts, to ensure everything is open source. Here's how we do it. .NET 6 needs a .NET 6 compiler to build itself. So we have to do two builds: one that uses an already-built .NET 6 SDK (via ./prep.sh --bootstrap) to build .NET 6 from source. Then we take our just-built .NET 6 and use it to build .NET 6 again, this time avoiding anything that was built outside of Fedora build servers. Once these two builds are done, we can do future builds using the .NET 6 packages we just build.

Also maybe worth a look is the port Alpine folks are working on - https://gitlab.alpinelinux.org/ayakael/aports/-/tree/testing/dotnet6/testing/dotnet6 - and what the Homebrew folks are doing: https://github.com/dotnet/source-build/issues/2719

For Yocto the most suitable could be if it would be a real CMake project for dotnet SDK, in this case a CMakeLists.txt can be executed automatically by Yocto bitbake.

Sorry, that's not available. There is a CMakeLists.txt (in fact, there are multiple) but they all compile specific small parts of the .NET SDK. To build the whole thing, the only current process is to use the ./build.sh scripts. The build.sh scripts will invoke cmake as required.

Livius90 commented 2 years ago

Ok i got it, so ./build.sh is a single script from MS which will build and make the tar.gz pack. The content of this pack will be the same what we can download from MS webserver. Current Yocto recipe can be useful, because after this single script executing we can get the same self-made tar.gz as the current recipe is fetching from MS webserver, and then we can install their same content.

I hope there will be no any secret apt-get or yum distribution specific package manager command in this ./build.sh otherwise Yocto will totaly failed to do it.

omajid commented 2 years ago

Ok i got it, so ./build.sh is a single script from MS which will build and make the tar.gz pack.

Yup, that's right!

The content of this pack will be the same what we can download from MS webserver.

It should be 99.9% same. There's some tiny differences in the open source build vs Microsoft's build. We try and fix everything we can.

I hope there will be no any secret apt-get or yum distribution specific package manager command in this ./build.sh otherwise Yocto will totaly failed to do it

FWIW, folks have had some luck building this on ArchLinux (which doesn't use apt/yum) and Homebrew (macOS), so apt/yum commands would be unexpected. If you do find any, please report it as a bug. Even with my Fedora packager hat on, I would like that to be fixed, because calling yum during a Fedora build is undefined behaviour.

Livius90 commented 2 years ago

It is amazing! First ./build.sh step is failed for me I got HTTP ERROR 403 when i try to open https://pkgs.dev.azure.com in a browser.

Failed to download package 'Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.13' from
'https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/microsoft.dotnet.web.projecttemplates.5.0/5.0.13/microsoft.dotnet.web.projecttemplates.5.0.5.0.13.nupkg'
Livius90 commented 2 years ago

@omajid Do you have any experience in how could that tarball builder/fetcher works behind a proxy? I am using an Kerberos proxy and i can not use any plaintext user/password solution for it.

Failed to download package 'Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.13' from 'https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/45bacae2-5efb-47c8-91e5-8ec20c22b4f8/nuget/v3/flat2/microsoft.dotnet.web.projecttemplates.5.0/5.0.13/microsoft.dotnet.web.projecttemplates.5.0.5.0.13.nupkg'.
Name or service not known (ytvvsblobprodcus310.vsblob.vsassets.io:443)
omajid commented 2 years ago

Sorry, I haven't used a proxy with .NET.

The output shown suggests this is being shown by a nuget restore. Looking around, issues like https://github.com/NuGet/Home/issues/10932 suggest this should be working, while there are many more that suggest proxying is broken in certain configurations.

Livius90 commented 2 years ago

I can not build this ***, because of the proxy. Lets try to update recipe to the latest .NET 6.0.200 SDK and use any supression for QA issue.

srware commented 2 years ago

I have added a new recipe for .NET 6 with workarounds for the dependency issues and x86-64 interpreter paths (this is why we always try not to work with anything pre-compiled...).

I explored building .NET from source but the current build mechanisms are far from compatible with Yocto, particularly for cross-compilation. The only option I can see would be attempting to build each individual component with their respective CMake mechanisms sufficiently patched to work with the Yocto toolchain but it would be a massive amount of work.

Closing this PR. Thanks for the efforts on this one!