Skip to content

Fishtest uses cutechess-cli, a command-line chess game manager. To maximize the compatibility with the workers running fishtest, use these instructions to build a static cutechess-cli binary for Windows and Linux. The building process requires some time, especially on Linux.

Running Cutechess

To run cutechess in a way equivalent to fishtest use (linux example below):

./cutechess-cli -repeat -rounds 10000 -games 2 -tournament gauntlet \
                -resign movecount=3 score=600 -draw movenumber=34 movecount=8 score=20 \
                -concurrency 8 -openings file=UHO_4060_v2.edp format=epd order=random plies=16 \
                -engine name=base cmd=stockfish.base option.EvalFile=/home/user/nn-ad9b42354671.nnue option."Use NNUE=true" \
                -engine name=test cmd=stockfish.test option.EvalFile=/home/user/nn-ad9b42354671.nnue option."Use NNUE=true" \
                -ratinginterval 1 -each tc=10.0+0.1 proto=uci option.Threads=1 -pgnout result.pgn

The book UHO_XXL_+0.90_+1.19.edp can be downloaded from the books repo. The EvalFile is specific to the binary, can be downloaded from the network server, and must be specified with the full path. Look at ./cutechess-cli --help for more options.

Windows

Download and install MSYS2 using the default settings and follow the official instructions to update the MSYS2 packages (here below the shortest way):

  1. pacman -Syuu to update the core packages, if request close the console pushing the top-right X button
  2. pacman -Syuu to update the other packages

32/64 bit version

  1. start a MSYS2 MinGW32 Shell for 32 bit or a MSYS2 MinGW64 Shell for 64 bit
  2. write this script, setting the "arch" variable to or 32 or 64
  3. run the script:
Click to view
bash
#!/bin/bash
# https://stackoverflow.com/questions/1011197/qt-static-linking-and-deployment
# https://www.msys2.org/docs/cmake/

# set arch to or 32 or 64
arch=32

# update and install packages
if [ "$arch" -eq 32 ]; then
    pacman -S --needed --noconfirm zip git mingw-w64-i686-cmake mingw-w64-i686-gcc mingw-w64-i686-qt5-static
else
    pacman -S --needed --noconfirm zip git mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-qt5-static
fi

# configure
n_jobs=6
base_path="$PWD"
cute_source="$base_path"/cutechess
cute_build="$base_path"/cutechess-build

mkdir -p "$cute_source" "$cute_build"

# build cutechess-cli
git clone https://github.com/cutechess/cutechess.git "$cute_source"

# checkout the latest tag
cd "$cute_source"
git fetch -p --tags --all
tag=$(git describe --tags `git rev-list --tags --max-count=1`)
git switch --detach "$tag"
git log --oneline -n 5 > "$cute_build"/cutechess.git.log

# use static libraries with QT
sed -i '/find_package(Qt6 COMPONENTS ${QT_COMPONENTS} Core5Compat QUIET)/i list(PREPEND CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)' "$cute_source"/CMakeLists.txt

# make static build
cd "$cute_build"
cmake -G Ninja "$cute_source" -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS="-static"
cmake --build . -j "$n_jobs"
strip cutechess-cli.exe
strip cutechess.exe
zip -j9 "$base_path"/cutechess-cli-win-"$arch"bit.zip "$cute_source"/COPYING cutechess-cli.exe

# run tests
echo "testing cutechess..."
for file in "$cute_build"/test_*; do
    if [ -x "$file" ] && [ ! -d "$file" ]; then
        base=$(basename -- "$file")
        "$file" > "$base".log 2>&1 &
    fi
done
wait
for file in "$cute_build"/test_*.log; do
    tail "$file"
done
"$cute_build"/cutechess-cli --version

Linux

Use Alpine (tested with version 3.18) to build cutechess-cli for fishtest, at example with a lxd/lxc container on Ubuntu:

bash
sudo lxd init --auto   # run once
lxc launch images:alpine/3.18 alp
lxc file push make_cute.sh alp/root/make_cute.sh
lxc exec alp -- sh -ic "sh make_cute.sh > out 2>&1 &"
lxc exec alp -- tail -f out
lxc file pull alp/root/cutechess-cli-linux-64bit.zip cutechess-cli-linux-64bit.zip
lxc delete -f alp

Write and start this script:

Click to view
bash
#!/bin/sh
# sudo sh make_cute.sh
# https://wiki.qt.io/Building_Qt_6_from_Git
# https://wiki.qt.io/Building_Qt_5_from_Git
# http://doc.qt.io/qt-5/linux-deployment.html
# https://github.com/qt/qt5

# install packages
apk update && apk add perl python3 git zip make cmake ninja g++ linux-headers mesa-dev

# configure
arch=64
n_jobs=6
base_path="$PWD"
qt_source="$base_path"/qt5
qt_build="$base_path"/qt5-build
qt_install=/opt/qt5-static
cute_source="$base_path"/cutechess
cute_build="$base_path"/cutechess-build

mkdir -p "$qt_source" "$qt_build" "$qt_install" "$cute_source" "$cute_build"

# build Qt static
git clone https://code.qt.io/qt/qt5.git "$qt_source"
cd "$qt_source"
git switch --detach v5.15.10-lts-lgpl
# use the default is the fast build should stop working
# perl init-repository --module-subset=default,-qtwebengine
perl init-repository --module-subset=qtbase,qtsvg
cd "$qt_build"
"$qt_source"/configure -static -release -opensource -confirm-license -prefix "$qt_install" -nomake examples -nomake tests -nomake tools

make -j "$n_jobs"
make install

# build cutechess-cli
git clone https://github.com/cutechess/cutechess.git "$cute_source"

# checkout the latest tag
cd "$cute_source"
git fetch -p --tags --all
tag=$(git describe --tags `git rev-list --tags --max-count=1`)
git switch --detach "$tag"
git log --oneline -n 5 > "$cute_build"/cutechess.git.log

# set static build
sed -i '/set_target_properties(cli PROPERTIES OUTPUT_NAME cutechess-cli)/a set_target_properties(cli PROPERTIES LINK_SEARCH_START_STATIC ON)\nset_target_properties(cli PROPERTIES LINK_SEARCH_END_STATIC ON)\ntarget_link_options(cli PRIVATE -static-libgcc -static-libstdc++ -static)' "$cute_source"/CMakeLists.txt

# make static build
cd "$cute_build"
cmake -G Ninja "$cute_source" -DCMAKE_BUILD_TYPE=Release
cmake --build . -j "$n_jobs"
strip cutechess-cli
zip -j9 "$base_path"/cutechess-cli-linux-"$arch"bit.zip "$cute_source"/COPYING cutechess-cli

# run tests
echo "testing cutechess..."
for file in "$cute_build"/test_*; do
    if [ -x "$file" ] && [ ! -d "$file" ]; then
        base=$(basename -- "$file")
        "$file" > "$base".log 2>&1 &
    fi
done
wait
for file in "$cute_build"/test_*.log; do
    tail "$file"
done
"$cute_build"/cutechess-cli --version

Use this script to test the linux cutechess-cli binaries with some major linux distributions:

Click to view
#!/bin/bash
# use lxc/lxd on Ubuntu 18.04 or later
# sudo snap install lxd
# sudo lxd init
# accept all the defaults
# copy cutechess-cli binaries in "32" and "64" folders

_test_cute () {
echo ${1} ${2}
lxc launch ${1} c000
lxc file push ${2}/cutechess-cli c000/root/cutechess-cli
[[ -z ${3} ]] || lxc exec c000 -- sh -ic "${3}"
lxc exec c000 -- ldd cutechess-cli
lxc exec c000 -- ./cutechess-cli --version
lxc delete -f c000
}

_test_cute images:almalinux/8 64
_test_cute images:almalinux/9 64

_test_cute images:alpine/3.15 64
_test_cute images:alpine/3.16 64
_test_cute images:alpine/3.17 64
_test_cute images:alpine/3.18 64
_test_cute images:alpine/edge 64

_test_cute images:archlinux 64

_test_cute images:centos/8-Stream 64
_test_cute images:centos/9-Stream 64

_test_cute images:debian/10 64
_test_cute images:debian/11 64
_test_cute images:debian/12 64
_test_cute images:debian/sid 64

_test_cute images:fedora/36 64
_test_cute images:fedora/37 64
_test_cute images:fedora/38 64

_test_cute images:gentoo/systemd 64

_test_cute images:opensuse/15.4/desktop-kde 64
_test_cute images:opensuse/15.5/desktop-kde 64
_test_cute images:opensuse/tumbleweed 64

_test_cute ubuntu:14.04 64
_test_cute ubuntu:16.04 64
_test_cute ubuntu:18.04 64
_test_cute ubuntu:20.04 64
_test_cute ubuntu:22.04 64

_test_cute images:voidlinux 64
_test_cute images:voidlinux/musl 64

_test_cute ubuntu:14.04/i386 32
_test_cute ubuntu:16.04/i386 32
_test_cute ubuntu:18.04/i386 32

MacOs

Install Xcode or

  1. any other toolset that contains a C++-compiler and
  2. git (e.g. via Homebrew: brew install git)
  3. cmake and ninja (brew install cmake ninja)

Then start this script:

Click to view
bash
#!/bin/sh
# https://wiki.qt.io/Building_Qt_6_from_Git
# https://wiki.qt.io/Building_Qt_5_from_Git
# http://doc.qt.io/qt-5/linux-deployment.html
# https://github.com/qt/qt5

# configure
arch=64
n_jobs=6
base_path="$PWD"
qt_source="$base_path"/qt5
qt_build="$base_path"/qt5-build
qt_install=/opt/qt5-static
cute_source="$base_path"/cutechess
cute_build="$base_path"/cutechess-build

mkdir -p "$qt_source" "$qt_build" "$cute_source" "$cute_build"
sudo mkdir -p "$qt_install"

# build Qt static
git clone https://code.qt.io/qt/qt5.git "$qt_source"
cd "$qt_source"
git switch --detach v5.15.10-lts-lgpl
# use the default is the fast build should stop working
# perl init-repository --module-subset=default,-qtwebengine
perl init-repository --module-subset=qtbase,qtsvg
cd "$qt_build"
"$qt_source"/configure -static -release -opensource -confirm-license -prefix "$qt_install" -nomake examples -nomake tests -nomake tools

make -j "$n_jobs"
sudo make install

# build cutechess-cli
git clone https://github.com/cutechess/cutechess.git "$cute_source"

# checkout the latest tag
cd "$cute_source"
git fetch -p --tags --all
tag=$(git describe --tags `git rev-list --tags --max-count=1`)
git switch --detach "$tag"
git log --oneline -n 5 > "$cute_build"/cutechess.git.log

# set static build
sed -i '/set_target_properties(cli PROPERTIES OUTPUT_NAME cutechess-cli)/a set_target_properties(cli PROPERTIES LINK_SEARCH_START_STATIC ON)\nset_target_properties(cli PROPERTIES LINK_SEARCH_END_STATIC ON)\ntarget_link_options(cli PRIVATE -static-libgcc -static-libstdc++ -static)' "$cute_source"/CMakeLists.txt

# make static build
cd "$cute_build"
cmake -G Ninja "$cute_source" -DCMAKE_BUILD_TYPE=Release
cmake --build . -j "$n_jobs"
strip cutechess-cli
zip -j9 "$base_path"/cutechess-cli-linux-"$arch"bit.zip "$cute_source"/COPYING cutechess-cli

# run tests
echo "testing cutechess..."
for file in "$cute_build"/test_*; do
    if [ -x "$file" ] && [ ! -d "$file" ]; then
        base=$(basename -- "$file")
        "$file" > "$base".log 2>&1 &
    fi
done
wait
for file in "$cute_build"/test_*.log; do
    tail "$file"
done
"$cute_build"/cutechess-cli --version