# Building and packaging Lantern Terminal

## Source package

Extract `lantern-terminal-0.6.0-source.tar.gz` and enter its top-level directory. Paths containing spaces are supported. The source archive contains C++ code, CMake configuration, shell/PowerShell scripts, terminal-parser and Lua runtime source, specifications, examples, tests and dependency/download manifests. Build outputs go to `build/`; release files go to `dist/`.

## Linux — easiest build

Requirements: C++17 compiler, CMake 3.22+, Ninja, Qt 6.8+ development files for Widgets/Network/SerialPort/PrintSupport/Core5Compat/Test, OpenSSH client tools and Python 3. Qt 6.10.2 was used for the supplied Linux build.

On a distribution that supplies a suitable Qt version:

```sh
sudo apt install build-essential cmake ninja-build qt6-base-dev qt6-serialport-dev qt6-5compat-dev libssh-dev libssl-dev freerdp3-dev openssh-client python3 libglib2.0-bin desktop-file-utils
./scripts/build-linux.sh
./build/linux/lantern-terminal
```

Alternatively `./scripts/build-linux.sh --install-deps` installs those packages before building. This is opt-in and uses sudo. Older Ubuntu distributions may supply Qt below 6.8; install a Qt 6.8+ SDK and pass `-DCMAKE_PREFIX_PATH=/path/to/Qt/gcc_64` to the build script.

To make a Debian installer and a tar archive:

```sh
./scripts/package-linux.sh
```

The `.deb` declares its actual shared-library dependencies. It is intended for a compatible Linux distribution; it is not a universal Linux binary. Build from source on a different distribution. The tar archive uses the same runtime libraries and contains `bin/` and `share/` content.

Choose a compiler/build directory/job count if needed:

```sh
LANTERN_BUILD_DIR="$PWD/build/debug" LANTERN_BUILD_TYPE=Debug LANTERN_JOBS=4 ./scripts/build-linux.sh
```

The `lantern-lua` worker is built automatically with the application from vendored Lua 5.4.9 source. No Lua SDK, interpreter download or LuaSocket installation is needed. Both executables must remain together in the installed `bin/` directory (Windows: application directory).

## Windows — native build

Install CMake, Ninja, Python 3, NSIS, and Qt 6.8.3 with its matching 64-bit MinGW 13.1 compiler and Qt SerialPort and Qt 5 Compatibility components. The application is built with C++17. Use the matching MinGW compiler rather than mixing MSVC with a MinGW Qt kit.

In PowerShell from the extracted source directory:

```powershell
.\scripts\build-windows.ps1 -QtRoot C:\Qt\6.8.3\mingw_64 -CompilerBin C:\Qt\Tools\mingw1310_64\bin
.\build\windows-native\lantern-terminal.exe
.\scripts\package-windows.ps1 -QtRoot C:\Qt\6.8.3\mingw_64 -CompilerBin C:\Qt\Tools\mingw1310_64\bin
```

Add `cmake`, `ninja`, `python` and `makensis` to PATH. The packaging script uses Qt's deployment tool to collect required libraries/plugins, adds the application data and scripting interface, and creates an installer and portable ZIP. Runtime download versions and SHA256 values are pinned in `scripts/runtime-downloads.json`; packaging requires Internet access on the first run and uses a user cache thereafter.

## Build the Windows installer from Linux

```sh
sudo apt install mingw-w64 cmake ninja-build nsis python3-venv
./scripts/setup-windows-cross.sh
./scripts/build-windows-libssh.sh
./scripts/build-windows-freerdp.sh
./scripts/build-windows-cross.sh
```

`build-windows-libssh.sh` cross-builds zlib, OpenSSL and libssh (versions and SHA256 checksums pinned in `scripts/dependencies.json`) into the toolchain cache for the built-in SSH engine; it needs `make` and `perl` and takes several minutes the first time. Without it the Windows build still works but offers only the OpenSSH engine. `LANTERN_LIBSSH_WINDOWS` selects a different libssh kit. `build-windows-freerdp.sh` then cross-builds the FreeRDP 3 client libraries (pinned with their checksum) using that OpenSSL, for RDP sessions; without it the Windows build has no RDP. `LANTERN_FREERDP_WINDOWS` selects a different FreeRDP kit. On Linux, RDP uses the distribution's FreeRDP 3 (`freerdp3-dev`); CMake leaves RDP out with a warning if it is missing.

The setup script installs a pinned aqt helper into a user virtual environment and downloads the official Qt 6.8.3 MinGW Windows kit. The cross build uses the POSIX MinGW compiler variant and vendored Vulkan headers so Linux headers do not enter the Windows build. It does not alter the system compiler configuration.

An already-installed kit can be selected with `LANTERN_QT_WINDOWS=/absolute/path/to/mingw_64`. `LANTERN_TOOLCHAIN_CACHE` changes the cache root. Windows binaries must still be tested on Windows; successful cross-compilation or Wine smoke tests alone do not validate every Windows device/integration.

## Source archive and checksums

```sh
python3 scripts/package.py source
python3 scripts/package.py checksums
sha256sum -c dist/SHA256SUMS
```

Generated artifacts, caches, profiles, private keys and Python bytecode are excluded from the source archive. Public upstream dependencies retain their licences. Qt remains dynamically linked and replaceable.

## Tests

```sh
ctest --test-dir build/linux --output-on-failure
python3 tests/integration.py build/linux/lantern-terminal
python3 tests/launch_checks.py build/linux/lantern-terminal
```

The RLogin, BBS-session and Zmodem tests (`tests/rlogin.py`, `tests/bbs.py`, `tests/zmodem.py`) run in ctest; the Zmodem test needs lrzsz (`sz`, `rz`) and is skipped by CMake when they are not installed. Also in ctest: `tests/ssh_tools.py` (SFTP Browser and Copy Public Key, needs `sshd`), `tests/xfer.py` (Xmodem, Ymodem and Kermit; needs lrzsz and `gkermit`), `tests/rdp.py` (needs `Xvfb`, `xterm`, `freerdp-shadow-cli3` from freerdp3-shadow-x11 and `winpr-hash`; it runs on a private display) and `tests/update.py`. `tests/windows_rdp.py` and `tests/windows_libssh.py` run the packaged Windows build under Wine on private displays. The built-in VGA font in `src/vgafont.h` is generated: `python3 scripts/make-vga-font.py > src/vgafont.h` (needs the console-setup-linux fonts).

Integration tests create disposable profiles, loopback TCP/Telnet endpoints, a serial PTY, TFTP files and an SSH daemon with temporary keys. SSH tests need `sshd` and `ssh-keygen`; no production hosts, credentials, service configurations or SSH trust stores are modified. The test daemon listens only on loopback. Tests use a protected user cache so OpenSSH strict ownership checks remain enabled.

`docs/TEST-RESULTS.md` records the actual release checks and limitations.

The native core suite exercises a desktop launcher through `gio` (libglib2.0-bin); launch_checks.py also uses desktop-file-validate (desktop-file-utils). Appearance and workspace tests use disposable/offscreen UI instances. The SSH trace check runs OpenSSH configuration inspection without making a network connection.
