RVVM icon indicating copy to clipboard operation
RVVM copied to clipboard

Add official cosmopolitan libc support

Open fish4terrisa-MSDSM opened this issue 8 months ago • 10 comments

I succeeded in compiling RVVM with cosmopolitan libc toolchian. The one binary compiled using it runs normally on Linux(x86-64/arm64) and windows(x86-64).(My compile system is linux arm64) GUI of course didnt work(may be implemented using Nano-X later), but it can boot up system with opensbi, with jit, tty terminal and network support. However, I have to patch a little on src/devices/chardev_term.c. In details, replace the line

        .c_cc[VMIN] = 1,

to

        .c_cc[6] = 1,

( The value of VMIN in linux is 6, at least on Linux/arm64 devices. The output binary works just fine on Linux/x86_64 and windows, so I dont think it really matters. But it's just a temporary solution. ) I didnt boot a whole system on a windows machine(only tested it on a VM with only opensbi, just to make sure it still functions). The terminal interface works just fine, but socket may fail(not tested) Maybe we can add cosmopolitan libc support to the list? It claims to support Linux, Mac, Windows, FreeBSD, OpenBSD, NetBSD(not tested in *BSD env, and bare metal didnt work), with no noticeable performance lose(at least no on Linux/arm64 and Linux/x86_64) Btw, I compiled RVVM with

make CC="cosmocc" USE_NET=1 USE_X11=0 USE_LIB=0

after installed their toolchain and added their bin to path.

fish4terrisa-MSDSM avatar Mar 19 '25 14:03 fish4terrisa-MSDSM

I succeeded in compiling RVVM with cosmopolitan libc

Oh that's really nice. I have thought about it a while ago but did not actually touch it myself yet.

However, I have to patch a little

It is actually possible to omit that whole field initialization line altogether, or cover it under #ifdef VMIN. The terminal input is supposed to be non-blocking, but is done in a more portable way via select(), at which point VMIN may be 0 anyways.

I am simply afraid that other code trying to print into stdout may be unprepared for a non-blocking behavior (Imagine printf() that looses part of output text), which may affect logger as well as other code in the process in case of library usage.

No noticeable performance lose (At least no on Linux/arm64 and Linux/x86_64)

Is it building it as a fat binary sorta? I.e. it contains native RVVM code for both x86_64/arm64?

LekKit avatar Mar 19 '25 15:03 LekKit

Ah, figured out VMIN only affects stdin blocking behavior, but not stdout. There's no harm in removing it then and initializing VMIN to zero.

LekKit avatar Mar 19 '25 15:03 LekKit

Commit 42b23d3 should fix build.

LekKit avatar Mar 19 '25 15:03 LekKit

However, I have to patch a little

It is actually possible to omit that whole field initialization line altogether, or cover it under #ifdef VMIN. The terminal input is supposed to be non-blocking, but is done in a more portable way via select(), at which point VMIN may be 0 anyways.

It's not VMIN not defined, it's some other problem that I didnt figure out... You can compile it without patching and you'll get the same error message.(In fact, I compiled it on my phone and I dont have the building log aside)

I am simply afraid that other code trying to print into stdout may be unprepared for a non-blocking behavior (Imagine printf() that looses part of output text), which may affect logger as well as other code in the process in case of library usage.

Didnt test, if you have some kind of tests maybe we'll figure out. Or maybe we can just disable log for it.

No noticeable performance lose (At least no on Linux/arm64 and Linux/x86_64)

Is it building it as a fat binary sorta? I.e. it contains native RVVM code for both x86_64/arm64?

I thought it's like what Apple did with their fat Mach-O binary, but it turns out that it's not that simple. The compiler generated x86_64 objs(although I'm compiling it on an arm64 device), and with binwalk I didnt spot any sign of multiarch... They claimed that it works like JVM, which translates the code, but the performance doesnt look like that. I have no idea about how it works. I didnt see noticeable performance lose, but it doesnt mean that there're no performance lose. The best usage of it I think is to be provided as a demo, which need no dependency, and can be downloaded and test in all mainline os and arch(well, in fact only arm64 and amd64, but they already covered the most). Also I dont know if the port for other *BSD is done. If it's not, maybe it can be seen as a temporary solution.

fish4terrisa-MSDSM avatar Mar 19 '25 15:03 fish4terrisa-MSDSM

Commit 42b23d3 should fix build.

worked (as intended)

fish4terrisa-MSDSM avatar Mar 19 '25 15:03 fish4terrisa-MSDSM

btw where's the porting status table? I remembered there's a table showing the current porting status for each os in README.md before?

fish4terrisa-MSDSM avatar Mar 19 '25 15:03 fish4terrisa-MSDSM

I remembered there's a table showing the current porting status for each os in README.md before?

It grew so much that there is no point in showing it even anymore (It could probably work even on some toy POSIX operating systems I have not heard of). That list also would need to be updated to at least add Redox support and a few RTOS that i've tested myself. If anything, only small patches like this one should be needed onward.

There is also fallback for a pure generic C99 support without OS-specifics except threads, but things work worse (I.e. running without terminal input, with very poor time precision, no GUI/network/threaded IO, and higher CPU use). DOS port for example was originally made like this, but turns out it is possible to run Win32 RVVM exe via HX extender and it works way better that way.

LekKit avatar Mar 19 '25 15:03 LekKit

Interesting notes:

  • It is probably really a fat binary, I tried injecting purposely non-compilable code into RVJIT ARM64 backend and the build failed
  • On Windows, no Win32-specific code from RVVM itself is used, Cosmopolitan provides a POSIX emulation layer
  • This has a small interesting detail that we now need to request _SC_GRANSIZE in VMA mmap() implementation, but other than that it should be OK (RVVM already works on e.q. Cygwin). See 1c78d75.
  • SDL2 could possibly work, but I have not yet figured out how to link it properly

LekKit avatar Mar 19 '25 16:03 LekKit

RVVM now has proper Cosmopolitan support as of 4607ad0, including GUI support via dynamically-loaded SDL2 (X11 or Wayland may theoretically work too, but need to somehow provide their headers without clashing with the host).

Build with: make CC=cosmocc OS=Cosmopolitan ARCH=x86_64_arm64 CC_BRAND=gcc USE_SDL=2

The resulting binary worked on both Linux and Windows for me, as well as under Wine. Dropping SDL2.dll from SDL2 releases into the executable directory allowed SDL2 GUI to work in Windows variant.

@polina4096 reports that it also works on Mac M1, but SDL2 GUI didn't load (Possibly rpath issues, likely fixable), and the performance was less than that of a native build. It needs further debugging.

It would be nice to automate the build more, i.e. just make CC=cosmocc and deduce everything else automatically. Unfortunately cosmocc doesn't yet report all the needed info, see https://github.com/jart/cosmopolitan/issues/1316#issuecomment-2739803889.

LekKit avatar Mar 20 '25 10:03 LekKit

Also note that when Wine with binfmt support is installed in your host distro, it is very wise to disable it temporarily, otherwise cosmocc as well as the built RVVM will attempt to run under Wine....

On Arch it may be done with

sudo systemctl stop systemd-binfmt

And re-enabled on same boot via

sudo systemctl start systemd-binfmt

LekKit avatar Mar 20 '25 15:03 LekKit

Since 79d52cf RVVM has Cosmopolitan CI target with SDL2 support built-in, and runs tests in CI. The artifacts are available as usual (Note that despite it being marked as x86_64, it's in fact a fat binary with ARM64 support)

SDL2 support is verified at least on Linux and Windows and requires either an installed SDL2 package or libSDL2.dll in the executable directory.

This concludes Cosmopolitan support as completed, but note that it's just an interesting toy target, and misses on native features like VFIO, and future ones like KVM.

LekKit avatar Jun 25 '25 21:06 LekKit