This project makes possible to rebuild Native Client for usage with the Dæmon game engine. Chromium development tools are NOT required to build.
Native Client (also known as NaCl) is a sandboxing technology by Google. It was used by Chrome extensions and Chrome apps. The Dæmon engine is the open-source game engine powering the Unvanquished game, it uses Native Client to securely and portably run downloadable compiled games.
Google publicly announced in May of 2017 the (then-)upcoming deprecation and abandonment of Native Client technologies in favor of WebAssembly, and announced the actual deprecation in 2020. But Google also supported Native Client-powered ChromeOS 138 until ChromeOS 139 in July of 2025 and as such continued developpement of some Native Client technologies. This extra development materialized in the maintenance of the loader and a toolchain named Saigo, frequently rebased on the latest LLVM upstream at the time. The loader received commits from Google until April of 2025, and Saigo received commits from Google until January of 2025 and the last rebase was over Clang 21.
The related project to rebuild the Saigo Native Client compiler can be found there:
Nothing about Native Client should be expected from Google anymore.
This is a fork of the upstream repository:
The Git history has been rewritten to remove very large files (multiple MinGW archives were stored in Git and things like that!), reducing the history size from 384MB to 57MB.
More information about this history rewriting can be found there:
This fork brings edits to enable the building of NaCl without the Chromium dev tools.
Many of the original project pages are no longer available. Some documentation about Native Client can be found at:
- Documentation for contributors to Native Client (Web archive)
- Research papers (Web archive)
Currently the Linux amd64, Windows amd64 and Linux armhf platforms are well-tested. However there are issues with platform qualification for ARM. For Windows i686 and Linux i686 it builds at least.
- SCons
- Saigo NaCl SDK
- For Linux: LLVM, if using
--clang(default). Must be installed in/usr/bin. - For Linux: GCC, if using
--no-clang - For Linux: GNU Binutils
- For Windows: Visual Studio
- For Windows: MinGW
The build system uses SCons, which may be invoked as scons and/or python -m SCons depending
how it is installed. Inter-architecture cross-compilation is supported, but inter-operating system
is not. Build artifacts are placed in scons-out/ by default. The scons-out/*/staging
directories contain the "final" outputs of the build. Here are some commonly
used command line arguments for our build:
werror=0to disable compiler warnings as errors--modewhich takes a comma-separated list of toolchains to enable in the build. Some values are:opt-host: trusted code toolchain using optimization flags for the current OSdbg-host: trusted code toolchain with debugging flags for th ecurrent OSnacl: NaCl toolchain to build the sandboxed code
saigo=1to use the Saigo NaCl toolchain. This is the only NaCl toolchain we support so you must always add this when using thenaclmode.--platform=x86,--platform=x86-64, or--platform=arm: choose target architecture.--verbose: show compiler command lines and other stuff-j<N>build parallelism- Target names, e.g.
sel_ldr(NaCl loader),irt_core,small_tests,medium_tests,all_programs,large_tests,huge_tests,run_<something>_test
There is also a toolchain for host-mode tools. Its configuration is based on the same arguments used for the trusted toolchain.
scons --mode=opt-host platform=x86-64 werror=0 sel_ldrOn Linux, add --no-clang to use GCC instead of Clang.
This requires the Saigo NaCl toolchain. You can provide it by either
(a) passing saigo_newlib_dir=<path> on the command line (the directory
you want to target is normally called saigo_newlib), or
(b) dropping the toolchain in toolchain/linux_x86//toolchain/win_x86 and renaming its
top-level directory to saigo_newlib_raw.
The following command builds one irt_core.nexe. You need to strip it
yourself; ordinary Linux strip seems to work.
scons --mode=nacl saigo=1 platform=x86-64 werror=0 irt_core [optional saigo_newlib_dir=...]This builds both components and runs some tests.
scons --mode=opt-host,nacl saigo=1 platform=x86-64 werror=0 --keep-going small_tests medium_tests -j4To enable crash dump tests, add the option breakpad_install_dir=<breakpad install prefix>,
OR install Breakpad to toolchain/linux_x86/breakpad/. The repository can be found at daemon/libs/breakpad. You need to build the Breakpad tools and run make install`.
Install the scons and pywin32 Python modules, Visual Studio, and a MinGW toolchain for the
appropriate architecture (the latter is solely used for the assembler). Python module installation:
python -m pip install scons pywin32
You can use the traditional MSVC compiler with --no-clang, or clang-cl with --clang.
Specify the path to the MinGW installation with mingw_dir=.... For example:
python -m SCons --mode=nacl,opt-windows --no-clang saigo=1 werror=0 mingw_dir=C:\mingw\x86_64-msvcrt-12.2.0 platform=x86-64 sel_ldr irt_core`
There are some special build system features that facilitate testing for the 32-bit ARM Linux target.
Some unit tests can run directly on an x86-based host with the help of user-mode QEMU. You don't need to pass any extra arguments to the build system, just install the necessary software, which may be named something like "qemu-user". Then issue a normal testing command e.g.
scons --mode=opt-host,nacl saigo=1 platform=arm werror=0 --keep-going small_tests
This is useful but there are many tests that it cannot run, for example because they involve
spawning multiple process. Also it is important to test on a full machine to exercise the
arcane kernel interactions such as longjmping out of a signal handler.
To test on an emulated or slow ARM machine, you can build the binaries on another system first
and then copy everything to the test machine. You need to copy both the build system files and
the compiled artifacts. Then on the test machine, you only need to install SCons to run tests,
using the built_elsewhere=1 flag. For example,
# on build machine
scons --mode=opt-linux,nacl saigo=1 platform=arm all_programs -j8
rsync -az --info=progress2 * testuser@testhost:/home/testuser/nacl-test
Then on the test machine,
scons --mode=opt-linux,nacl saigo=1 platform=arm small_tests medium_tests large_tests
Once you have built the loader and IRT, you can use run.py to run an nexe like a normal
program. It specifies relaxed I/O permissions so the nexe can print to stdout, etc.
Note that if you did not build the dependencies, the script will try to build them with a PNaCl toolchain (not the Saigo that we want) and probably fail.
The following list describes major files and directories in the source tree.
COPYING NOTICE README.md RELEASE_NOTES documentation/: Documentation, release, and license information.SConstruct site_scons/ build/: Build system files.src/: Core source code for Native Client.src/include/: Header files that are missing from some platforms and are used by more than one major part of Native Clientsrc/shared/: Source code that's used by both trusted code (such as the service runtime) and untrusted code (such as Native Client modules)src/third_party: Other people's source codesrc/trusted/: Source code that's used only by trusted codesrc/untrusted/: Source code that's used only by untrusted codetests/common/: Source code for examples and tests.tools/: Some scripts used by the build system, plus a lot of stuff we don't use.