+++ type = "blog" title = "[GSoC 2023] .NET Developer Platform - Progress Report #5" author = "Trung Nguyen" date = "2023-08-13" tags = ["haiku", "software", "gsoc", "gsoc2023", "dotnet"] +++
Project status overview
The long awaited stateful FD monitoring[1] has finally been implemented on Haiku, and there now is a partial implementation of `kqueue` usable in `libbsd`.
Therefore, `Release` builds of .NET can now work properly (after some more hacks) and have been set as the default in my custom `dotnet-install.sh` script.
Due to some technical difficulties in parsing Doxygen documentation and converting it to the XML format used in C#, I have delayed my effort to generate documentation for the Haiku API bindings.
Instead, I am going to resume my effort of bootstrapping .NET on Haiku, as mentioned in my second report[1].
There are still a few more obstacles preventing from the most basic components (`clr.runtime`) from being built natively on Haiku: one is related to sockets, another related to the recent GCC 13.2.0 update for Haiku.
Technical details
`kqueue`-related hack
`kqueue` for sockets now works properly in the scenario previously covered by the `poll` hack.
However, in the .NET codebase, there is another component[1] that checks for `kqueue` and uses it when available.
This component used to work just fine on Haiku. Now, with `kqueue` detected, it also makes intensive use of the `.data` field of `struct kevent`. It even has an assert[1] related to this field. The field is supposed to report the number of bytes that could be read, but Haiku does not support[2] such information yet.
Therefore, I am currently explicitly disabling `kqueue` support for this component on Haiku:
A better solution might be to detect a broken `.data` field using a CMake check, and then use `ioctl` with `FIONREAD` to replace that field, but that would result in a few hundred lines of configuration and code, so I am sticking to this hack for now.
MSBuild parallel builds
For some time, bootstrapping .NET would reach the `CMake` step if parallel builds is disabled (`-maxcpucount:1`). However, using the default settings, MSBuild would try to spawn a few child processes to build sub-projects, leading to various problems.
Mysterious build failures due to missing `SO_RCVBUF`
All MSBuild child processes would fail with something like this:
In the end, it was because `setsockopt` with `SO_RCVBUF` always returning an error for `AF_UNIX` sockets:
The function in question has been implemented and is now under code review.
Deadlock on `free()` in child process
This is a very rare condition where a `dotnet` child process would hang while trying to call `free()` before it could reach the `_kern_exec()` syscall.
It used to be a bit more common before waddlesplash re-initialized some of the locks in #6777[1].
Now, the deadlock occurs when trying to acquire[1] the lock for a superblock.
waddlesplash has suggested that a master lock for `fork` will be needed, since resetting all superblocks is not an efficient task.
While the issue still exists, it is much rarer, so I will ignore it for now.
Toolchain errors
`clang` errors
When bootstrapping .NET on Haiku, I tried to build it using `clang`, since it is the default compiler on all platforms (probably except Windows).
However, `clang` (at least the one from `llvm12_clang` from HaikuPorts) seems to be unable to compile Haiku's GNU extensions, even when `_GNU_SOURCE` is properly defined. This causes unexpected compilation errors in some files that use the `sincos()` function.
This bug has been reported to HaikuPorts as #9198[1].
9217[1] should fix the problem by adding the required headers directory for `clang12`.
With this fixed, builds with `clang` would fail the same as GCC builds below, as on Haiku, `clang` still requires `gcc` for its linker functionality (`lld` is broken[1] on Haiku).
Latest GCC toolchain errors
GCC has been recently updated to 13.2.0. This causes a regression, both in the cross-compilers and the `gcc` package found on HaikuPorts.
`-rdynamic` is a compiler option that makes executable binaries export their symbols. Haiku already does this by default, so jessicah added a patch to make this flag a no-op for Haiku's GCC 11.
Despite the changes being left unmodified[1] in the latest commit, the regression still occurs, affecting both the CI for `dotnet-builds` (as well as all cross-compilation efforts) and bootstrap builds on Haiku.
If the error still persists, I will have to add a few more lines of hack in `dotnet`'s CMake files to remove `-rdynamic` for Haiku.
Conclusion
You might notice that this blog is much shorter than my previous ones. You might also notice that I am a bit less active than the few previous months. A new, and rather chaotic, term has started, and I am getting busier and busier with tasks from university.
This is, however, still conforming to my original proposal (which states that my commitment hours per week would half starting from July, yet still fulfilling the 350-hour workload). Major goals have also been fulfilled:
- The .NET runtime and SDK has been ported. `net8.0` applications can be developed and run on
Haiku.
- The `net8.0-haiku` workload has been built and works.
- Some .NET-based frameworks like `GtkSharp` and `FNA` has been tested.
The other goals, making a HaikuPorts recipe or allowing cross-compilation from Windows/Linux, requires my patches to be accepted to the official repo, and are relatively easy when that happens.
Appendix - Pull requests/patches
Like the previous blog, I will have a list of pull requests/patches. Those that have been included in the previous blog (pending and still pending now, or already merged) are not displayed here.
Merged
haiku/haiku[1]
- unix: Implement SO_RCVBUF (#6816)[1]
1: unix: Implement SO_RCVBUF (#6816)
Pending
No new pending pull requests at the time of writing, though haiku/haiku#6616[1] ("Add clone_memory syscall") and dotnet/runtime#86391[2] ("Haiku: Configuration support") have both been pending for quite a long time.