Native Client

From Unvanquished
Jump to: navigation, search

Native Client or NaCl is the current technology used for virtualizing the game code in the Dæmon engine.

It replaced the Q3VM (Quake3 Virtual Machine) in the engine.

Unlike Q3VM for which the .qvm binaries were limited to be produced with the old C supported by the proprietary LCC compiler, the .nexe NaCl binaries can be compiled with Clang-based open source compilers supporting modern-enough C++ versions and allowing to reuse off-the-shelf C++ libraries that may even be shared between the engine and the game source code.

The Native Client documentation can be found on chrome.jscn.org/docs/native-client/welcome-to-native-client/.

Platforms

Platform NaCl compatibility
Linux Windows macOS FreeBSD
amd64 i686 arm64 armhf amd64 i686 amd64 arm64 amd64
✅️ native ✅️ native ☑️ through armhf
compatibility
✅️ native ✅️ native ✅️ native ✅️ native ☑️ through amd64
compatibility
☑️ through Linux
compatibility

The NaCl loader (the virtual machine running the virtualized code) is available for three systems: Linux, Windows and macOS. The supported architectures differs per system:

  • Linux:
    • amd64,
    • i686,
    • armhf;
  • Windows
    • amd64,
    • i686;
  • macOS:
    • amd64.

It is possible to run native engines with other platforms when there is a compatibility layer to run the NaCl loader:

  • Linux:
    • arm64, running the armhf NaCl loader through built-in Linux 32-bit compatibility;
  • FreeBSD:
    • amd64, running the Linux NaCl loader through built-in Linuxulator compatibility.

The Linux i686 NaCl loader may run on FreeBSD using Linuxulator but it is not tested.

With some plumbing to be done, it should be possible to run an arm64 macOS engine with amd64 macOS NaCl loader running on Rosetta2. For now arm64 macOS users runs the whole engine and NaCl loader on Rosetta2.

NaCl upstream development has slowed down since the competing solution WebAssembly became the industry standard, so it is very unlikely support for new systems and architecture would be added. To overcome this problem, we would have to switch to WebAssembly (that unfortunately also lacks support for some platforms NaCl supports, like i686 or armhf).

NaCl also supports 32-bit MIPS on Linux but this architecture is not supported by the Dæmon engine and the Unvanquished game project.

Compilers

PNaCl

PNaCl is the current NaCl compiler we use to build the nexe game binaries. It is based on an old Clang 3.6 and does not support C++ above C++14. To overcome some of the related limitations we may switch to Saigo.

The PNaCl compilation workflow is to build a single .pexe then to translate them to per-architecture .nexe (amd64, i686, armhf) using a specific translator tool.

The PNaCl SDK consists on Python-based wrappers around Clang internals. It was initially using now-obsolete and hard-to-find Python2 but we ported it to Python3 to extend its lifespan.

The provided PNaCl SDK runs on Linux, Windows and macOS systems, on amd64 architectures.

While the .pexe compiler itself runs on FreeBSD with the Linuxulator, the translator does not, meaning it's not possible to build .nexe binaries on FreeBSD.

PNaCl supports C++ exception. There exist newer PNaCl SDKs (from chromium canary releases) that do not support exceptions and may not provide more what we already have with latest stable PNaCl.

Saigo

Saigo is a new NaCl compiler based on latest Clang and supporting latest C++ standards. It compiles directly to .nexe.

Unlike PNaCl, Saigo do not provide released binaries, meaning a switch to Saigo requires a convenient way to provide it to contributors.

For now it has been successful to build an sgame.nexe (server game binary) with Saigo and run it, so with more efforts it may be possible to also build the cgame.exe (client game binary) as well and drop PNaCl.

Google provides some nightly Linux amd64 Saigo toolchain snapshots that aren't easy to get without some Google scripts.

The Saigo compiler and other related toolchain tools should build everywhere their upstream build, but only targeting the usual platforms, as the nacl_loader is basically the same: a more recent nacl_loader is also buildable but doesn't bring new platform supports.

The Saigo compiler itself isn't hard to build (same as Clang itself), what is more complex is to get the toolchain and the libc/libc++ to build.

Saigo may not support C++ exceptions as far as we know.

Moving to Saigo can be considered as a first step before migrating to WebAssembly, as it would allow us to migrate to a new C++ standard before migrating to WebAssembly, and the redesign of our CMake configuration for Saigo may help later when migrating to WebAssembly.

Here is a GitHub issue about the ongoing efforts at migrating to Saigo: