Skip to content
All posts
2 min readtebakopackagingtutorial

Advanced payloads: Runtimes and native code (4 of 5)

The advanced payloads series: runtimes and native code.

The Tebako team

github.com/tamatebako

The basics treated the runtime as the thing that resolves and mounts. This post treats it as a choice: which runtime engine to declare, and what happens when a payload contains compiled code. The second question is the reason tebako exists: users never compile a gem.

Runtimes and native code the runtime is a choice engine: ruby (MRI) the default, ABI-line pinned engine: jruby a JVM runtime, same two artifacts one constraint grammar covers both; the payload declares, tebako resolves native gems, compiled once your gem with C extensions compiled at press, on your CI users never compile anything macos-arm64 macos-x86_64 linux-gnu / musl windows-ucrt one file per triplet — prebuilt, verified, mounted

Figure 1 — Runtime engines are declared, not configured; native gems compile once at press time and ship as prebuilt, verified files per platform.

Runtime engines

The manifest declares the engine; tebako resolves it:

requires:
  - kind: language
    engine: ruby          # or jruby
    constraint: "~> 3.3.0"

An MRI (Matz’s Ruby Interpreter) runtime and a JRuby runtime are the same two artifacts — an interpreter executable and an environment image — under the same constraint grammar. A payload with native extensions pins an ABI line (~> 3.3.0) so that a runtime from the wrong line is a named error at startup, never a runtime crash.

Native code, compiled once

Gems with C extensions are the classic packaging problem: without help, every user needs a compiler toolchain, matching headers, and good fortune. Tebako moves the compilation to press time, on the packager’s machine or CI:

$ tebako press -r ./myapp -e bin/myapp -o dist/myapp \
    --target macos-arm64 --target macos-x86_64 \
    --target linux-gnu-x86_64 --target windows-ucrt-x86_64

Each target produces one file with its native gems compiled for that triplet. What users download is a prebuilt, SHA-256-verified binary that needs no compiler, no headers, and no toolchain. For payloads with no native code at all, one universal file covers every platform.

This is the distribution model in one sentence: the people who build a package compile it; the people who use it never do.

What you can do now

This post has chosen a runtime engine declaratively, pinned ABI lines for native payloads, and shipped compiled gems as binaries per platform. The last post shows all of it working at once, on a payload that exercises every part of the model.

Note

Continue with part 5 of 5: packed-mn: one download, any document.