This guide builds ShogiBoardQ on Linux, creates ShogiBoardQ-linux.zip, and publishes it on GitHub Releases. The ZIP contains the AppImage (the application), tsume shogi collections for 3, 5, 7, 9, 11, and 13 moves to mate (1,000 puzzles each, 6,000 in total), and the Hayanagi USI engine for regular games. This ZIP is the only Linux file attached to a release.
Packaging is supported only on Arch Linux. The license notices of the libraries bundled in the AppImage are collected with pacman, so the package is built with Arch's Qt packages. Release packages are built in an older Arch Linux container (5.1). You can build and develop the application itself on other distributions.
Contents
1. Requirements
| Item | Requirement |
|---|---|
| OS | x86_64 Linux. Packaging (AppImage and ZIP) requires Arch Linux (for releases, Arch Linux in a Docker container) |
| Compiler | GCC 9 or later, or Clang 10 or later, with C++17 support |
| CMake | 3.16 or later (Ninja recommended) |
| Qt | 6.7 or later (Widgets, Charts, Network, Concurrent, Multimedia, Sql, LinguistTools). Packaging also needs the SVG plugins |
| Python | Python 3 (packaging scripts) |
| Docker | To build release packages in the container |
| Other | Git, curl, file, FUSE 2 (to run AppImage-based tools), ImageMagick (to shrink icons larger than 512 px) |
Packaging needs network access: linuxdeploy and appimagetool are downloaded the first time.
About glibc: an AppImage runs only on systems whose glibc is the same as or newer than that of the build system. Built on the latest Arch Linux, it requires glibc 2.43 or later and does not start on, for example, Ubuntu 24.04 (glibc 2.39). Release packages are therefore built in a container pinned to Arch Linux as of 2024-07-15 (glibc 2.39, Qt 6.7.2; see 5.1). That AppImage requires glibc 2.38 or later and libstdc++ from GCC 14 or later, and runs on Ubuntu 24.04 or later, Debian 13, Fedora 40 or later, and similar (not on Fedora 39, whose libstdc++ is from GCC 13).
About the bundled OpenSSL and libcurl: the other packages in the container stay at the versions of that time, but the bundled OpenSSL and libcurl, and the network libraries libcurl uses (nghttp2, nghttp3, ngtcp2, libssh2), are replaced with newer versions (OpenSSL 3.6.5 and curl 8.23.0 as of October 2026; see 5.1). OpenSSL 3.3.1 and curl 8.8.0 of that time lack later fixes such as CVE-2024-6119. OpenSSL cannot be taken from the system instead: the bundled libcurl (used by libproxy, which Qt Network loads, to fetch proxy auto-configuration files) needs OpenSSL 3.5 or later functions, so the app would not start on Ubuntu 24.04 with OpenSSL 3.0. AppRun points the bundled OpenSSL to its own settings (
usr/share/ShogiBoardQ/openssl.cnf) withOPENSSL_CONF: the system settings are written for the distribution's OpenSSL, and upstream OpenSSL cannot read Fedora's (crypto policies), which disabled TLS for network play.
2. Setting up the development environment
2.1 Arch Linux and Docker (for packaging)
Release packages are built inside the container, so the host only needs Docker, Git, and Python 3; Qt and the other build dependencies are in the container. Add your user to the docker group and log in again.
sudo usermod -aG docker $USER
Members of the docker group can perform root-equivalent operations through docker.
To build and develop on Arch Linux directly, install the build tools and Arch's Qt packages. fcitx5-qt provides the Japanese input (fcitx5) plugin that is bundled in the AppImage; without it, that plugin is left out.
sudo pacman -S --needed base-devel cmake ninja git curl file python fuse2 imagemagick \
qt6-base qt6-charts qt6-multimedia qt6-svg qt6-tools fcitx5-qt
2.2 Other distributions (building the application only)
You can build and develop the application on Ubuntu, Debian, or Fedora as well. Qt 6.7 or later is required; if your distribution's Qt is older, install Qt with the Qt Online Installer.
Ubuntu / Debian:
sudo apt install build-essential cmake ninja-build git \
qt6-base-dev qt6-charts-dev qt6-multimedia-dev qt6-tools-dev qt6-tools-dev-tools \
qt6-l10n-tools libqt6sql6-sqlite libgl1-mesa-dev
Fedora:
sudo dnf install gcc-c++ cmake ninja-build git \
qt6-qtbase-devel qt6-qtcharts-devel qt6-qtmultimedia-devel qt6-qttools-devel \
qt6-linguist mesa-libGL-devel
For Qt installed with the Qt Online Installer, pass its location when configuring CMake (Qt 6.11.2 in this example).
cmake -B build -S . -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$HOME/Qt/6.11.2/gcc_64"
2.3 Checking the installation
cmake --version
g++ --version
qmake6 --version
3. Getting the source and building
Clone the repository together with its Hayanagi submodule. Without the submodule, files needed for the build are missing.
git clone --recurse-submodules https://github.com/hnakada123/ShogiBoardQ.git
cd ShogiBoardQ
In an existing checkout, run git submodule update --init --recursive to fetch the recorded Hayanagi version. Then build in Release mode and start the application.
cmake -B build -S . -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/ShogiBoardQ
To run the tests:
cmake -B build -S . -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON
cmake --build build
ctest --test-dir build --output-on-failure
For a build without packaging, you can also use ./scripts/build-linux.sh --skip-appimage.
4. Preparing Qt license notices
The AppImage includes the license notices extracted from the source of the same Qt version, together with a record of where the source comes from. Prepare them once before packaging and again after updating Qt. Ordinary builds do not need them.
The Qt version depends on where you build. The release container (5.1) uses Qt 6.7.2, so download and verify the Qt 6.7.2 source (qt-everywhere) and extract the notices to build-container/qt-licenses. Check the SHA-256 against the .sha256 file next to the source on the official download site.
curl -fsSL https://download.qt.io/archive/qt/6.7/6.7.2/single/qt-everywhere-src-6.7.2.tar.xz.sha256
python3 scripts/qt_licenses.py fetch --version 6.7.2 \
--sha256 0aaea247db870193c260e8453ae692ca12abc1bd841faa1a6e6c99459968ca8a \
--output build-container/qt-sources
python3 scripts/qt_licenses.py prepare --version 6.7.2 \
--archive build-container/qt-sources/qt-everywhere-src-6.7.2.tar.xz \
--sha256 0aaea247db870193c260e8453ae692ca12abc1bd841faa1a6e6c99459968ca8a \
--source-url https://download.qt.io/archive/qt/6.7/6.7.2/single/qt-everywhere-src-6.7.2.tar.xz \
--provenance 'Arch Linux packages from the Arch Linux Archive snapshot 2024-07-15: qt6-base 6.7.2-1; qt6-charts, qt6-multimedia, qt6-svg 6.7.2-1; qt6-wayland 6.7.2-2. Upstream Qt source plus Arch PKGBUILDs and patches.' \
--output build-container/qt-licenses
In --provenance, describe where the Qt you use comes from, including the Arch package versions and that Arch's patches and build instructions apply. It is recorded in QT-SOURCE.json and shown under “Obtaining source code” in “Version Info”. To build directly on Arch Linux, prepare the notices for the version reported by pacman -Q qt6-base in build/qt-licenses.
preparedoes not overwrite an existing output directory; use a new one to recreate the notices.- The default location is
qt-licensesin the build directory (build-containerfor the container,buildfor direct builds). If you use--clean, which deletes the build directory, create the notices elsewhere and point to them with theSHOGIBOARDQ_QT_LICENSE_DIRenvironment variable. - Do not attach the Qt source or the notices to a release separately. See the Qt distribution notes (Japanese) for the policy.
5. Creating the AppImage and ZIP
5.1 Running the script
Release packages are built in an older Arch Linux container (the Arch Linux Archive as of 2024-07-15: glibc 2.39, Qt 6.7.2).
For a release, first update the version to the release date and commit it (section 6).
./scripts/build-linux-container.sh
- The first run creates the build image (
scripts/linux-container/Dockerfile, about 3 GB). Downloads from the Arch Linux Archive are slow and take tens of minutes. - Inside the container,
scripts/build-linux.shruns as your user. It usesbuild-containerinstead of the usualbuilddirectory and writes the outputs to the repository root. - Some keys that signed packages at that time have since expired. The image verifies signatures against the official keyring but does not require the keys to be currently trusted.
- The bundled OpenSSL and libcurl, and the network libraries libcurl uses (nghttp2, nghttp3, ngtcp2, libssh2), are replaced with newer versions, because the versions of that time lack later fixes. Current Arch packages are installed after checking their SHA-256 (
scripts/linux-container/packages.sha256) and signatures; curl, whose current package uses newer glibc functions, is rebuilt in the image from the same version's Arch PKGBUILD. - To update them, download the new packages and their
.sigfiles on your machine, check the signatures withpacman-key --verify, and updatepackages.sha256. For curl, setCURL_PKGVERandCURL_PKGBUILD_SHA256(the SHA-256 of the PKGBUILD at the Arch tag) in the Dockerfile; the tag signature is checked with the key incurl-signing-key.asc. First make sure the glibc version a new package needs (the highestGLIBC_inobjdump -T) is 2.38 or lower; rebuild in the image any package that needs more. Changingscripts/linux-container/makesbuild-linux-container.shrebuild the image.
You can also build directly on Arch Linux. Such an AppImage requires the host's glibc version or later (2.43 as of October 2026).
./scripts/build-linux.sh
Both scripts accept these options:
| Option | Description |
|---|---|
--skip-appimage | Build only; do not create the AppImage and ZIP |
--clean | Delete the build directory before building |
--help | Show help |
| Environment variable | Description |
|---|---|
SHOGIBOARDQ_BUILD_DIR | Build directory (default: build; build-container in the container) |
SHOGIBOARDQ_QT_LICENSE_DIR | Location of the prepared Qt notices (default: qt-licenses in the build directory) |
APPIMAGE_EXTRACT_AND_RUN=1 | Extract and run AppImage-based tools where FUSE is unavailable (always set in the container) |
DOCKER | Container only: the docker command (for example sudo docker) |
SHOGIBOARDQ_ARCH_SNAPSHOT | Container only: the Arch Linux Archive date (default: 2024/07/15) |
build-linux.sh performs these steps (in the container, the same steps run inside it):
- Check the required tools (cmake and python3; ninja recommended)
- Configure CMake and build in Release mode (ShogiBoardQ and Hayanagi)
- Check the executable, translation files, and the 3- to 13-move collections (one file per move count)
- Download linuxdeploy, its Qt plugin, and appimagetool (first time only; saved in the build directory). Before running them, check them against the SHA-256 values in
build-linux.sh. They are continuous builds that upstream replaces, so a replacement makes the check fail and stop; then review the upstream release digest and changes before updating the values - Create the AppDir and generate the AppImage (files needed to run, plus Qt and bundled library license notices)
- Create the ZIP with the AppImage, puzzle collections, and Hayanagi
The outputs are ShogiBoardQ-linux-x86_64.AppImage and ShogiBoardQ-linux.zip in the repository root. The working directories are AppDir and ShogiBoardQ-linux/ in the build directory.
5.2 Contents of the AppImage
The AppImage contains only the files needed to start and run the application, plus license notices.
ShogiBoardQ-linux-x86_64.AppImage
└── (extracted)
├── AppRun ← starts the app with only the bundled Qt and OpenSSL settings
├── shogiboardq.desktop
├── shogiboardq.png
└── usr/
├── bin/
│ ├── ShogiBoardQ ← executable
│ ├── qt.conf ← Qt plugin location
│ └── ShogiBoardQ_{ja_JP,en,zh_CN,zh_TW}.qm ← application translations (4 languages)
├── lib/ ← Qt and dependencies
├── plugins/
│ ├── platforms/libqxcb.so ← X11
│ ├── imageformats/libqsvg.so, libqjpeg.so, libqico.so
│ ├── iconengines/libqsvgicon.so
│ ├── platforminputcontexts/ ← Japanese input (compose, fcitx5, ibus)
│ ├── platformthemes/libqxdgdesktopportal.so
│ ├── sqldrivers/libqsqlite.so ← tsume history and analysis cache
│ └── tls/libqopensslbackend.so ← TLS for CSA network play (OpenSSL)
└── share/
├── applications/, icons/
├── ShogiBoardQ/openssl.cnf ← settings the bundled OpenSSL reads (empty; the system's are not read)
└── licenses/ShogiBoardQ/
├── NOTICE*.md, SOURCE_CODE*.md, GPL-3.0.txt, LGPL-3.0.txt
├── QT-NOTICES.md, qt/ ← notices of the bundled Qt modules
├── QT-SOURCE.json, BUILD.json ← Qt source record and build version
└── THIRD-PARTY-NOTICES.md, third-party/ ← notices of the other bundled libraries
- Puzzle collections, the Hayanagi engine for regular games, documentation, and validation records (
validation_*.json) are not included. The application does not read them from inside the AppImage and users cannot select files there, so they are shipped only as files outside the AppImage in the ZIP. The Hayanagi used for tsume play is built into the application. - Qt's own translations placed by linuxdeploy (
usr/translations/) are removed. The Japanese and Chinese translations of standard dialogs are built into the executable, and the application translations are read fromusr/bin/. - Unused plugins are not bundled: OpenGL integration (
xcbglintegrations) and GIF images. No widget uses OpenGL. - Of the
tlsplugins, only the OpenSSL backend (libqopensslbackend.so) is bundled, for the "TLS (encrypted)" connection in CSA network play. libssl and libcrypto are bundled as its dependencies. The app makes no HTTPS or other connections. - The Qt license notices cover only the bundled Qt modules (qtbase, qtcharts, qtmultimedia, qtsvg, qttranslations, and qtwayland) and the files they refer to (
scripts/qt_licenses.py). Notices for modules that are not distributed, such as Qt WebEngine, are left out. - For the other bundled libraries (about 50 packages such as glib, PulseAudio, OpenSSL, and fcitx5-qt),
scripts/bundled_licenses.pylooks up each package with pacman, copies the license texts tothird-party/, and lists versions, licenses, and source locations inTHIRD-PARTY-NOTICES.md. Both lists are shown in “Version Info” as “Third-party licenses in Qt” and “Bundled library licenses”.
5.3 Contents of the ZIP
The ZIP contains the following files. After extracting it, users can select the puzzle collections and Hayanagi right away.
| Source file | Location in the ZIP |
|---|---|
ShogiBoardQ-linux-x86_64.AppImage | ShogiBoardQ-linux/ |
resources/platform/README-linux.md | ShogiBoardQ-linux/README.md |
LICENSE | ShogiBoardQ-linux/LICENSE |
build/Hayanagi/hayanagi | ShogiBoardQ-linux/Hayanagi/hayanagi |
build/Hayanagi/book/hayanagi_book.db | ShogiBoardQ-linux/Hayanagi/book/hayanagi_book.db |
Hayanagi/README.md | ShogiBoardQ-linux/Hayanagi/README.md |
data/tsumeshogi/tsume_{3,5,7,9,11,13}ply_*.txt, data/tsumeshogi/README.md | ShogiBoardQ-linux/data/tsumeshogi/ |
ShogiBoardQ-linux.zip
└── ShogiBoardQ-linux/
├── ShogiBoardQ-linux-x86_64.AppImage
├── README.md
├── LICENSE
├── Hayanagi/
│ ├── hayanagi
│ ├── book/hayanagi_book.db ← Hayanagi opening book
│ └── README.md
└── data/tsumeshogi/
├── tsume_{3,5,7,9,11,13}ply_1000_20261001.txt ← 6 files (1,000 puzzles each)
└── README.md
- The puzzle collections are copied unchanged. Their hashes match the audit records built into the application, so verified move counts and solutions are reused when a collection is opened.
- Keep exactly one collection per move count in
data/tsumeshogi/(the repository tracks only the current 20261001 files). The script stops with an error if two files exist for the same move count. - Hayanagi is stripped before it is added. Its opening book
hayanagi_book.db, which the build copies tobuild/Hayanagi/book/, goes toHayanagi/book/; Hayanagi reads the book frombook/next to its executable. The ZIP has nodocs/,validation_*.json, orlicenses/outside the AppImage; the license notices are inside the AppImage.
Users start the application as follows. In tsume play, they choose a collection in data/tsumeshogi/ with “Open collection…”; to register the engine for regular games, they choose Hayanagi/hayanagi.
unzip ShogiBoardQ-linux.zip
cd ShogiBoardQ-linux
chmod +x ShogiBoardQ-linux-x86_64.AppImage Hayanagi/hayanagi
./ShogiBoardQ-linux-x86_64.AppImage
5.4 Testing
# Start
./ShogiBoardQ-linux-x86_64.AppImage
# Extract and check the contents (no Hayanagi and no Qt translations inside)
./ShogiBoardQ-linux-x86_64.AppImage --appimage-extract
ls squashfs-root/usr/bin/ squashfs-root/usr/plugins/*/
ls squashfs-root/usr/share/licenses/ShogiBoardQ/THIRD-PARTY-NOTICES.md
test ! -e squashfs-root/usr/bin/hayanagi && test ! -e squashfs-root/usr/translations && echo OK
# Required glibc version
find squashfs-root/usr -type f \( -name '*.so*' -o -name ShogiBoardQ \) -exec objdump -T {} + 2>/dev/null \
| grep -o 'GLIBC_[0-9.]*' | sort -uV | tail -1
# Hayanagi in the ZIP answers as a USI engine
unzip -o -q ShogiBoardQ-linux.zip -d /tmp/zipcheck
printf 'usi\nisready\nquit\n' | /tmp/zipcheck/ShogiBoardQ-linux/Hayanagi/hayanagi
# The ZIP has the 12 expected files and is not corrupted
python3 -m zipfile -l ShogiBoardQ-linux.zip
python3 -m zipfile -t ShogiBoardQ-linux.zip
For a container build, the required glibc version should be GLIBC_2.38 or lower. The AppImage uses the system's OpenGL (libEGL, libOpenGL), fontconfig, HarfBuzz, and wayland-client, which desktop systems normally provide.
Test in an environment whose
LD_LIBRARY_PATHdoes not include Qt's lib directory; otherwise system libraries are used and missing files go unnoticed. If possible, also check on another environment such as Ubuntu 24.04: switching among Japanese, English, and Chinese, SVG pieces, piece sounds, saving tsume history, and the license lists in “Version Info”.
6. Publishing on GitHub Releases
Update the version only on the day of a release, to that date. Before building the packages, change APP_VERSION in CMakeLists.txt, commit it, and build the packages from that commit. For a second release on the same day, add a fourth number, as in 2026.10.07.1. Use this version for the tag (without a leading v) and the release name. See Versioning and releases (Japanese) for details.
Attach only ShogiBoardQ-linux.zip for Linux, and keep this filename the same in every release.
git tag -a 2026.10.07 -m "ShogiBoardQ 2026.10.07"
git push origin main 2026.10.07
gh release create 2026.10.07 --title "ShogiBoardQ 2026.10.07" \
--notes-file RELEASE_NOTES.md ShogiBoardQ-linux.zip
If the packages for other operating systems are already published, add the ZIP to the existing release:
gh release upload 2026.10.07 ShogiBoardQ-linux.zip
- Name each file to attach. Do not upload the whole working directory or files in
build/. - Do not attach the Qt source,
QT-SOURCE.json, checksums, or an SBOM separately. The license notices and source information are inside the AppImage. - After publishing, check the list of attached files. The Source code links that GitHub adds automatically are separate from the attached files.
In the release notes, explain how to start the Linux version and its requirements, such as the glibc version.
### Running on Linux
1. Download and extract ShogiBoardQ-linux.zip
2. chmod +x ShogiBoardQ-linux-x86_64.AppImage Hayanagi/hayanagi
3. ./ShogiBoardQ-linux-x86_64.AppImage
Requirements: x86_64 Linux with glibc 2.38 or later and libstdc++ from GCC 14 or later (Ubuntu 24.04 or later, Debian 13, Fedora 40 or later, etc.)
Without FUSE, start it with --appimage-extract-and-run.
The repository's release.yml builds all three operating systems for tags beginning with
vor when run manually, but its Linux job runs on Ubuntu. Until collecting the bundled library notices supports Ubuntu, that job cannot create the Linux package, so the ZIP built in the Arch Linux container is attached manually.
7. Troubleshooting
Qt is not found
Could not find a package configuration file provided by "Qt6"
Make sure Qt 6.7 or later and the required modules are installed. For Qt from the Qt Online Installer, pass -DCMAKE_PREFIX_PATH. After switching Qt or the CMake generator, start over in a new build directory.
Hayanagi sources are missing
Run git submodule update --init --recursive in the repository root.
The script stops because of multiple collections
==> ERROR: 5手詰の問題集が複数あります: data/tsumeshogi/tsume_5ply_1000_20260926.txt data/tsumeshogi/tsume_5ply_1000_20261001.txt
An older version of a collection remains in data/tsumeshogi/ (the message says that several collections were found for one move count). Delete the unused version so that one file remains per move count.
Qt notice validation fails
Qt license preparation failed: Qt version mismatch: build=6.7.2, source=6.11.2
Qt license preparation failed: Qt notices are missing. See docs/dev/qt-licensing.md; set SHOGIBOARDQ_QT_LICENSE_DIR to prepared matching notices.
Prepare the notices for the same Qt version used for the build (section 4): Qt 6.7.2 in the container, or the version reported by pacman -Q qt6-base on Arch Linux. Do not ship a package after a failed step.
Collecting bundled library notices fails
Bundled library notices failed: Bundled library notices need pacman (Arch Linux); other distributions are not supported yet
Bundled library notices failed: Cannot find the system file of lib/libQt6Core.so.6
Bundled library notices failed: No license text for bundled package fcitx5-qt (GPL)
- Create the package on Arch Linux with Arch's Qt packages. If the AppImage contains libraries that do not belong to a pacman package, such as Qt from the Qt Online Installer, their package cannot be identified and the script stops.
No license text for …means that no license text was found for a package. Older repositories may use license fields that are not SPDX expressions; add the upstream expression toLICENSE_OVERRIDESinscripts/bundled_licenses.py. Put texts that a package lacks, such as a notice with the actual copyright line, inscripts/license-texts/<package>/.
docker cannot be used
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
Add your user to the docker group and log in again (sudo usermod -aG docker $USER), or set DOCKER="sudo docker".
linuxdeploy does not start
dlopen(): error loading libfuse.so.2
Install fuse2, or run APPIMAGE_EXTRACT_AND_RUN=1 ./scripts/build-linux.sh.
The AppImage does not start (FUSE)
AppImages require FUSE to run.
Install FUSE 2, or start it with --appimage-extract-and-run.
./ShogiBoardQ-linux-x86_64.AppImage --appimage-extract-and-run
The glibc version is too old
version `GLIBC_2.38' not found
The system's glibc is older than that of the build system. Build release packages in the container (5.1). If that is still too new, use a distribution with a newer glibc (see the glibc note in Requirements).
System libraries are missing
error while loading shared libraries: libOpenGL.so.0: cannot open shared object file: No such file or directory
Libraries that are not bundled in the AppImage (OpenGL, fontconfig, HarfBuzz, wayland-client) are missing on the system. Example for Ubuntu / Debian:
sudo apt install libegl1 libopengl0 libfontconfig1 libharfbuzz0b libwayland-client0
The xcb platform plugin cannot be loaded
qt.qpa.plugin: Could not load the Qt platform plugin "xcb"
X11 libraries are missing. Examples for Ubuntu / Debian, Fedora, and Arch Linux, in that order:
sudo apt install libxcb-cursor0 libxcb-xinerama0
sudo dnf install xcb-util-cursor xcb-util-wm xcb-util-keysyms
sudo pacman -S xcb-util-cursor xcb-util-wm xcb-util-keysyms
Japanese text cannot be entered
The AppImage bundles only the X11 platform plugin, so it runs through XWayland on Wayland desktops. If the QT_IM_MODULE environment variable is not set, no Japanese input plugin is selected. Start it with QT_IM_MODULE=fcitx for fcitx5, or QT_IM_MODULE=ibus for IBus.
QT_IM_MODULE=fcitx ./ShogiBoardQ-linux-x86_64.AppImage
Translations are not loaded
Check that the .qm files are in usr/bin/, next to the executable.
./ShogiBoardQ-linux-x86_64.AppImage --appimage-extract
ls squashfs-root/usr/bin/*.qm