Build and install
Lynxer is a C++17 executable with a cross-platform Windows host build. Building and running it does not need Python; Python is used by the LSP and tooling.
Requirements
- A C++17 compiler (
g++orclang++) andmake. python3for the LSP and development tooling.- A Rust toolchain (
cargo): it is required, not optional. Every Rust-backed stdlib module is built bycargo, and the interpreter links the Rust native-call engine (lynxer/rust/ffi). A missing toolchain or a compile error fails the build; there is no reduced build that drops a backend. libffiheaders andpkg-config(e.g.libffi-devon Debian/Ubuntu) for the native-call engine.- Git and network access for the first
cargobuild: crates are fetched from crates.io. Most crates are pure Rust, but a few compile vendored C with the system C compiler —zstd(viazstd-sys), vendored Lua (viamlua), bundled SQLite (viarusqlite) and theringcrypto provider — so a C compiler is required alongside the Rust toolchain.
No system OpenSSL, Boost, CMake, cpp-httplib, Crow, or nlohmann/json is needed: TLS is rustls, the HTTP stack is ureq/tungstenite/axum, and JSON is serde_json.
Build from the repository root
make buildLynxer # interpreter + every stdlib module, C++ and Rust
make testLynxer # the full suite (see README.md)
buildLynxer builds the interpreter and every backend, C++ and Rust, so a separate make cargo is only useful to rebuild the Rust half on its own. Both fail if cargo is missing.
make cargo # just the Rust backends and the native-call engine
make buildLynxerArm64 # the ARM64 interpreter (needs an aarch64 host)
The Makefile lives at the repository root; there is no separate lynxer/Makefile.
Artifacts
lynxer/lynxerorlynxer/lynxer.exe— the interpreter for the build host.lynxer/lynxer-arm64— the ARM64 interpreter, frombuildLynxerArm64.lynxer/stdlib/*.so— the Linux stdlib backends. The Rust-backed modules are produced bycargounderlynxer/build/rust; the C++ ones are compiled fromstdlib/*.cpp.- On Windows,
lynxer/stdlib/*.sofiles contain MinGW PE DLLs while retaining the language-level module names used by the bundled wrappers.
lynxer/build/rust/release/liblynxer_ffi.a— the native-call engine, a Ruststaticlibbuilt bycargoand linked intolynxer/lynxer. It is not a stdlib module and is not copied intostdlib/.
lynxer/liblynxer.soon Linux, orlynxer/lynxer.dllpluslynxer/lynxer.dll.aon Windows — the embedding runtime: the interpreter core (minusmain.cpp) linked as a shared library, exporting only thelynxer_embed_*entry points. Libraries built bylynxer --emit-librarylink against it.lynxer/lynxer.handlynxer/ffi_abi.hare its public headers.
The Rust workspace has twenty-six member crates: the twenty-three stdlib module backends listed in LYNXER_RUST_MODULE_NAMES (compress, crypto, encoding, game, graphics, image, ini, json, lua, network, raylib, re, regex, server, sound, sqldb, text, toml, tui, uuid, watch, xml, yaml), the two crates they share (rust/abi, and rust/regex_engine, the fancy-regex engine behind re/regex), and rust/ffi, the required native-call engine described in native-module-abi.
Install
sudo ./lynxer/lynxer --install # install into /usr/lib/lynxer, link /usr/bin/lynxer
sudo ./lynxer/lynxer --uninstall # remove the installed interpreter
--install lays out one self-contained tree:
/usr/lib/lynxer/lynxer the real binary
/usr/lib/lynxer/stdlib/* every stdlib module
/usr/lib/lynxer/lynxer.config the configuration file
/usr/lib/lynxer/liblynxer.so the Linux embedding runtime (for --emit-library)
/usr/lib/lynxer/lynxer.h the embedding public header
/usr/lib/lynxer/ffi_abi.h the wire-type header
/usr/bin/lynxer a symlink to the real binary
Because the symlink resolves to the real binary (/proc/self/exe), an installed lynxer finds its stdlib — and the embedding runtime plus its headers for --emit-library — from any working directory, so lynxer app.lynx works without keeping the build tree around. See embedding. Set LYNXER_PREFIX to install somewhere other than /usr — for example LYNXER_PREFIX=$HOME/.local lynxer --install needs no root — and pass the same value to --uninstall.
On Windows, --install defaults to %LOCALAPPDATA%\Programs\Lynxer (a per-user install needs no elevation; override it with LYNXER_PREFIX) and lays out the same tree — bin\lynxer.exe plus lib\lynxer\{lynxer.exe, lynxer.dll, lynxer.dll.a, stdlib, lynxer.config} — except that the launcher is a copy rather than a symlink, so the stdlib is resolved from lib\lynxer. --emit-library is available with the MinGW toolchain; consumers need lynxer.dll on the Windows DLL search path. Add <prefix>\bin to PATH to run lynxer by name; the installer says so when it is missing. See windows.
See CLI.
Quick run
./lynxer/lynxer lynxer/examples/milestone5.lynx
./lynxer/lynxer --list-stdlibs
./lynxer/lynxer --compile lynxer/examples/milestone5.lynx -o /tmp/demo
Example programs live under lynxer/examples/, so run them with that prefix from the repository root.
Environment variables
| Variable | Used by | Effect |
|---|---|---|
LYNXER_OPT_REPORT=1 | the interpreter | print the AST optimizer counts to stderr after the run |
LYNXER_GAME_HEADLESS=1 | the game module | run without opening a window |
LYNXER_GRAPHICS_HEADLESS=1 | the graphics module | run without opening a window |
LYNXER_SKIP_DISPLAY=1 | make testLynxer | skip the display and audio fixtures (used by CI) |
The first three are described in more detail in CLI and limitations.