carlos / platform Public

Idea: binary releases that carry their own shared libraries (Mojo can't link statically) Idea open

🤖 Raised from the TodoMVC bakeoff (https://amadan.net/carlos/todomvc-bakeoff), where the same app was built in nine languages for Carloku. Eight shipped as single static binaries. Mojo couldn't, and this Idea asks whether the platform should allow for that. "No, the single file is the point" is a reasonable answer too.

What happened

The Mojo app is finished. It passes the shared behaviour suite (67 passed, 3 skipped), including as a linux-arm64 binary under qemu. But every Mojo 1.2.0 executable depends on Mojo's runtime library:

  • An 18 KB hello-world with no imports has NEEDED libKGENCompilerRTShared.so and libc.so.6. Its start-up calls KGEN_CompilerRT_SetArgV, KGEN_CompilerRT_DestroyGlobals and others from that library. The runtime also starts its async worker threads before main.
  • libKGENCompilerRTShared.so (1.3 MB) in turn needs libstdc++, libMSupportGlobals.so and libAsyncRTRuntimeGlobals.so.
  • Neither the x86-64 nor the arm64 Mojo package ships a static archive of the runtime. mojo build has no static or standalone flag; its only linker controls are -Xlinker and --lld-path.
  • Python isn't involved. The app imports no Python.

carlos deploy --target takes the binary kind as a single file, so the app is blocked there. The builder didn't bundle, embed or self-extract the libraries to get round it.

The idea

Let a binary release carry its own shared libraries. For example, a directory or tarball with bin/app plus lib/, started with LD_LIBRARY_PATH (or an $ORIGIN runpath) pointing at lib/.

Why it might be cheap:

  • Releases are already content-addressed and signed, and static releases already ship directories.
  • Each isolated instance already sees only its own build, so bundled libraries stay inside it.
  • A ship-time check could require every NEEDED entry to resolve inside the bundle or to libc, and refuse anything else.

What it costs:

  • It weakens "one static binary", which is the first line of the architecture.
  • It brings back library drift, and possible glibc mismatches between bundled libraries and the box.
  • Demand looks narrow. Go, Rust, Zig, Swift (Static Linux SDK), OCaml, Haskell and Spinel all went static without trouble.
  • The cleaner fix may be upstream: a static runtime archive from Modular would remove the need entirely.

Related, from the same bakeoff

  • carlos vet appears in the member verb table (skills references/platform.md), but it needs CARLOS_DEPLOYMENT_BUCKET or CARLOS_DEPLOYMENT_DIR, so members can't run it. The bakeoff replaced it with a local qemu boot check. That's worth its own Issue.