Steam Runtime 1½ 'heavy'
========================

heavy is a miniature Steam Runtime used to run Steam's embedded web
browser (`steamwebhelper`). It is not intended to be used by games, or
by untrusted web content.

It's based on Debian 8 'jessie' so that it can (just about) still work with
the version of glibc used in the oldest platforms we still try to support
(SteamOS 2, Debian 8 and Ubuntu 14.04).

Wait, did you say 1½?
---------------------

Yes. Version 2 of the Steam Runtime 2 was already under development at
the time we discovered we needed some newer libraries for `steamwebhelper`.

It's also not a complete runtime (it doesn't have all the libraries
you would need for games), so "... and a half" seems appropriate.

How this fits into the overall Steam Runtime project
----------------------------------------------------

1. Build .deb packages for the content of the Steam Runtime.
    `steamrt` is one of these packages.

2. For `scout` and `heavy` only: Put together the .deb packages into the
    `LD_LIBRARY_PATH`-based Steam Runtime.
    This step is done by the scripts in
    [steam-runtime](https://github.com/ValveSoftware/steam-runtime),
    but the choice of the actual packages to include is mostly delegated to
    `steamrt`.

3. Put together the .deb packages into a Flatpak-style container runtime.
    We don't use this to run games, only to produce a SDK environment.
    This step is done by
    [flatdeb-steam](https://gitlab.steamos.cloud/steamrt/flatdeb-steam),
    but the choice of the actual packages to include is mostly delegated to
    `steamrt`.

In theory `heavy` could be used as a container runtime to run games, but
`soldier` is a better thing to use for that.

Where can I get it?
-------------------

<https://repo.steampowered.com/steamrt-images-heavy/snapshots/> contains
several versions of heavy. Each version's subdirectory contains:

* source code in the `sources` subdirectory
* container images that can run games
  (`*.Platform-*-runtime.tar.gz`, which can also be converted into Flatpak
  runtimes)
* container images that can run games with debugging tools available
  (`*.Sdk-*-runtime.tar.gz` and `*.Sdk-*-debug.tar.gz`,
  which can also be converted into Flatpak runtimes)
* container images for compiling your own software
  (`*.Sdk-*-sysroot.tar.gz`, and `*.Sdk-*-sysroot.Dockerfile`, which can
  also be converted into a Docker image)

What's in this repository?
--------------------------

This repository mostly provides "metapackages". This is Debian jargon for
a package that is (almost) empty, and pulls in desired packages by having
dependencies on them.

Developing software that runs in heavy
--------------------------------------

Please don't.

Backporting policy
------------------

### What we can backport into heavy

This is mostly the same as scout, because the primary product for both
scout and heavy is a `LD_LIBRARY_RUNTIME`-based runtime.

In general, we can backport application-level libraries like Pipewire
and SDL, subject to some conditions:

  * The library needs to have a proper SONAME with a stable ABI,
    for example `libpipewire-0.3.so.0`.
  * There needs to be a minor ABI version number in the library's
    physical filename, which goes up with each release.
    For example, `libpipewire-0.3.so.0 -> libpipewire-0.3.so.0.339.0`
    is suitable: each new release increases the minor ABI version.
    However, `libdrm.so.2 -> libdrm.so.2.4.0` is not suitable (see below).
  * If the new library has runtime dependencies which aren't satisfied
    by the Steam Runtime, we need to backport those first, or patch the
    library to avoid the dependencies.
  * If the new library has build-time dependencies which aren't satisfied
    by the Steam Runtime, we need to backport those first, or patch the
    build system to avoid the dependencies.
  * If the new library loads functionally-necessary plugins, data or
    similar, we need to patch it to respect the `$STEAM_RUNTIME` environment
    variable.

We can backport invididual bug-fixes without backporting an entire
new upstream version, but Steam cannot rely on having those bug-fixes
at runtime, because our library might have been overridden by a newer
upstream version from the host system that does not have those bug-fixes.

Similarly, we can backport invididual features without backporting
an entire new upstream version, but Steam cannot rely on having those
features at runtime, because our library might have been overridden by
a newer upstream version from the host system that does not have those
features. In particular, if we backport something that adds new ABI, we
usually should not add new symbols to public header files, to force Steam
to use forwards-compatible mechanisms like `dlsym()` to find new ABIs.

### Preferred versions to backport

If we can, we prefer to backport the version that was included in a
stable release of Debian or an LTS release of Ubuntu, in preference to
using an intermediate version. This gives us a source for security and
bugfix updates.

If we need a version newer than what's in the current Debian stable release,
we prefer to use the version from Debian testing or unstable, but in this
case we should plan to track its updates until the next stable release.

If we need a version newer than what's in Debian unstable, we can go to
experimental or the latest upstream version, but we need to be careful to
track newer releases in this case.

### What we can't backport

We cannot backport glibc: we have to use the system version of
glibc, because the ELF interpreter `ld.so(8)` needs to be the same
version as `libdl.so.2`, which in turn needs to be the same version as
`libc.so.6`. The absolute path to `ld.so(8)` is hard-coded into every
executable, and cannot be a relative path.

We cannot backport libraries that are closely related to the graphics
stack, notably the libraries built by Mesa, including `libgbm.so.1`. The
Steam Runtime is designed to use the version of Mesa from the host
system, to maximize the probability that it will work with the user's
kernel and hardware.

We cannot safely backport libraries where the minor ABI version in
the physical filename does not increase. For example,
`libdrm.so.2 -> libdrm.so.2.4.0` stays the same across multiple releases,
even while adding new ABI. This means we cannot tell whether our bundled
version is older or newer than the host version, which means we cannot
guarantee that Steam will be using a version that is the same as or
newer than our backport.

Similarly, we cannot safely backport libraries where no minor ABI version
is present in the physical filename at all (such as `libnss3.so`).

In general, we cannot safely backport libraries that have undergone
non-backwards-compatible changes while keeping the same SONAME.

We generally should not backport bug-fixes and new features that have
not been included in upstream's version control system, and preferably
included in a formal release as well.
