Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-52220] Support for Cosmopolitan Libc #8350

Open
sgammon opened this issue Feb 9, 2024 · 15 comments
Open

[GR-52220] Support for Cosmopolitan Libc #8350

sgammon opened this issue Feb 9, 2024 · 15 comments

Comments

@sgammon
Copy link

sgammon commented Feb 9, 2024

Feature request

Build-once, run-anywhere, but for native-image

Is your feature request related to a problem? Please describe.

Currently, one must run a Native Image build for each operating system and architecture pair which they want to target with their software.

Describe the solution you'd like.

GraalVM supports targeting glibc and musl as LibC backends. If GraalVM additionally supported Cosmopolitan Libc, GraalVM users could compile once and ship to all major operating systems, and even micro-architectures, with one binary: Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD and even BIOS.

Describe who do you think will benefit the most.

Firstly this benefits GraalVM developers, because iteration on software could be much faster if native builds only needed to occur once and remained testable on multiple operating systems.

Secondly, this benefits consumers of software built by GraalVM developers, because a distribution option would become available which only involves one single binary.

Consider that CI systems, local development/testing, and nearly all popular forms of software distribution (downloads, archives, things like group policy) multiply in complexity with the number of output targets needed. By reducing these targets to just one (where appropriate) while maintaining cross-OS and cross-architecture compatibility, complexity of distribution of GraalVM native programs drops to meet Java's build-once-run-anywhere standard.

For use cases which should remain optimized to a target architecture, the pluggable nature of GraalVM's LibC support should still allow targeting glibc or musl (for example, tailored-for-purpose server binaries).

Describe alternatives you've considered.

  • Containers: Docker containers and other cross-platform virtualization methods are already supported by GraalVM, but incur a performance and tooling penalty; binaries cannot be run directly, only wrapped in a container, which must be built, downloaded, and executed with underlying OS support.

  • WASM: Although GraalVM can execute WASM, WebAssembly isn't ready for this task because GraalVM can't yet target WASM for native-image.

Additional context.
I tried to build a native-image using Cosmopolitan, but wasn't able to get far, and I think contributing this feature is outside the scope of my skillset.

Express whether you'd like to help contributing this feature
I would be happy to help with a stacktrace, reproducer, or with contributions in Java. Justine Tunney, the author of Cosmo, is very open to contributions and there is an active community.

@sgammon sgammon added the feature label Feb 9, 2024
@fernando-valdez
Copy link
Member

Thanks for creating this feature request. I will evaluate your feature request and will let you know if I have any questions.

@fernando-valdez fernando-valdez self-assigned this Feb 10, 2024
@fernando-valdez fernando-valdez changed the title Support for Cosmopolitan Libc [GR-52220] Support for Cosmopolitan Libc Feb 21, 2024
@fernando-valdez
Copy link
Member

Created internal ticket: GR-52220

@wirthi
Copy link
Member

wirthi commented Feb 21, 2024

Hi @sgammon

That sounds like an interesting idea to pursue. I don't expect this to be on our priority list anytime soon, though. It might be interesting to pursue this e.g. as part of a student project or an internship eventually. Of course, we are happy to accept open source contributions in that area.

Having this working properly would require the whole JDK to work with cosmopolitan so it can be used in Native Image; with MUSL we have seen this was quite some effort, initially.

Best,
Christian

@jart
Copy link

jart commented Feb 25, 2024

Cosmopolitan's based on Musl so you've probably done most of the legwork already.

@sgammon
Copy link
Author

sgammon commented May 12, 2024

@fernando-valdez / @wirthi Any update on the internal ticket? Just curious if there are places the community can help

@jjsullivan5196
Copy link

jjsullivan5196 commented May 13, 2024

Hi all, figure this would be the best place to chime in. I'm attempting to get native-image to build a static binary with cosmocc, the cosmopolitan build toolchain. I'm still stuck at the feature query stage of the build, as substrate's POSIX interface code appears to have a hard dependency on dladdr, which is not part of cosmopolitan

Native image version (installed with sdkman on debian 12)

john@crunchbox:~/src/cosmograal$ native-image --version
native-image 22.0.1 2024-04-16
GraalVM Runtime Environment GraalVM CE 22.0.1+8.1 (build 22.0.1+8-jvmci-b01)
Substrate VM GraalVM CE 22.0.1+8.1 (build 22.0.1+8, serial gc)

Using this build script (the cosmocc toolchain lives in the directory named cosmocc) https://cosmo.zip/pub/cosmocc/cosmocc-3.3.2.zip

#!/bin/sh

export PATH="$PWD/cosmocc/bin:$PWD:$PATH"
export CC="cosmocc"
export CXX="cosmoc++"
export INSTALL=cosmoinstall
export AR=cosmoar

native-image -H:-CheckToolchain -H:TempDirectory=$PWD/tmp -H:+TraceNativeToolUsage -H:-JNI --native-compiler-path=$PWD/cosmocc/bin/cosmocc --libc=musl --static HelloWorld

I had to disable the toolchain check since the cosmocc frontend doesn't provide the same version output as GCC usually does. Also, it might be the case that the actual GCC compiler shipped with cosmocc may need to be used directly, but using the GCC binaries made it so that things like stdio.h couldn't be included. @jart @ahgamut maybe you know the correct way around this

Putting this all together, GCC gives up when it has to find the Dl_info struct (part of the dladdr API and not defined)

/home/john/src/cosmograal/tmp/SVM-1715589268342/PosixDirectives.c:443:     printf("NativeCodeInfo:PosixDirectives:StructInfo:Dl_info:PropertyInfo:size=%lu\n", ((unsigned long)sizeof(Dl_info)));

There's also a smaller problem of ucontext.h apparently being missing from the dependencies of PosixDirectives

which generates a similar set of errors (undefined register constants)

/home/john/src/cosmograal/tmp/SVM-1715589268342/PosixDirectives.c:224:     printf("NativeCodeInfo:PosixDirectives:ConstantInfo:REG_RSP:PropertyInfo:value=%lX\n", ((unsigned long)REG_RSP));

@sgammon if any of this sounds familiar lmk :-) I'll try to clean up what I'm doing here and put it in a repo so other people can try it out, but I think both of these issues are currently blockers.

@jjsullivan5196
Copy link

jjsullivan5196 commented May 14, 2024

Just to note, I'm making some progress getting the feature queries to work correctly. There's a few more bits of the POSIX headers that define interfaces that exist as GNU or Linux specific extensions but aren't marked correctly. I'm working thru them one by one and I'll throw up a patch once I get most of them nailed down.

@sgammon
Copy link
Author

sgammon commented May 14, 2024

@jjsullivan5196 It looks like you got stuck where I did, but I wasn't able to proceed. That's great news. Waiting in the wings to test... let me know if you want to connect on Discord. I'm happy to throw you some hardware if it would help (in x86 or ARM)

@loiclefevre
Copy link
Member

Some recent news on mutex: https://justine.lol/mutex/

@hohwille
Copy link

hohwille commented Jan 7, 2025

Sorry for the naive question but aren't the binary formats totally different and incompatible between the operating-systems (linux ELF with SO files, Windows EXE with DDL files, MacOS *.app application format that is more or less a folder with a specific stucture, etc.)?

@paul-bjorkstrand
Copy link

@hohwille : https://justine.lol/ape.html has the context for you on how this works (I just found it myself and just understand at a high level, I don't know the nitty gritty 😄 )

@sgammon
Copy link
Author

sgammon commented Jan 21, 2025

@jjsullivan5196 (and anyone else interested) I've made some progress on this recently, with significant help from @ahgamut. I now have static libraries building against musl, and we are able to provide all of the requisite cosmoified labsjdk dependencies via superconfigure.

One challenge that has surfaced is that certain constructs like SO_KEEPALIVE are actually extern const int under Cosmo, where they would normally be #defined. Some sources tolerate this fine; others, in particular Java sources which expect those to be constants, do not.

To actually resolve these symbols at runtime, we'll need to wire those in via JNI instead, I think.

@sgammon
Copy link
Author

sgammon commented Jan 21, 2025

cc / @fniephaus @lewurm who have also helped on this previously

@lewurm
Copy link
Member

lewurm commented Jan 21, 2025

One challenge that has surfaced is that certain constructs like SO_KEEPALIVE are actually extern const int under Cosmo, where they would normally be #defined. Some sources tolerate this fine; others, in particular Java sources which expect those to be constants, do not.

I posted a workaround for this a while ago on the redbean discord: lewurm/labs-openjdk-21@46e6b19#diff-b970d466355efe5c78ea536cf3a230db59dc07dfd5fd6cdb8c4fe4d9b6d83d5b

@sgammon
Copy link
Author

sgammon commented Jan 21, 2025

Thank you @lewurm, unblocked in record time. We have a branch of OpenJDK at 25+0 with this patch and some other changes to the build to consider Cosmo a valid libc target.

Unless I'm configuring something totally wrong, I'm seeing most of Hotspot build just fine under Cosmo. There are some questions about dynamic libraries and missing symbols that might get complex but so far most seem to be features that could simply not be supported for now (eg, SO_PEERCRED)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants