Skip to content
Closed

Linux #1136

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8379cf2
Default to gstreamer backend to prevent capture card flickering
ConnorC432 Mar 11, 2026
8ed547c
Use unix directories for Resources and persistent data
ConnorC432 Mar 11, 2026
468c0a9
look for Resources in ~/.local/share/SerialPrograms instead of ../Res…
ConnorC432 Mar 11, 2026
82211eb
Merge branch 'PokemonAutomation:main' into linux
ConnorC432 Mar 11, 2026
0dd6834
detect system onnxruntime with pkg-config
ConnorC432 Mar 13, 2026
18966ad
fix compile using onnxruntime 1.24.x
ConnorC432 Mar 13, 2026
91b9570
onnx gpu hw accel for linux
ConnorC432 Mar 13, 2026
741b986
look for Resources in cwd
ConnorC432 Mar 13, 2026
3babe1f
Merge branch 'main' into linux
ConnorC432 Mar 13, 2026
562a9f4
ignore empty frames from capture card
ConnorC432 Mar 14, 2026
04a61e0
default auto-reset to 0 on linux builds to prevent black frames on reset
ConnorC432 Mar 14, 2026
87c7894
Merge branch 'main' into linux
ConnorC432 Mar 14, 2026
df8d967
CPack config to build linux packages
ConnorC432 Mar 14, 2026
b05aac9
linux packaging scripts
ConnorC432 Mar 15, 2026
44ac2e4
Merge branch 'main' into linux
ConnorC432 Mar 15, 2026
40a6f0b
fix debian package requirements
ConnorC432 Mar 15, 2026
c835b8a
fix debian package requirements
ConnorC432 Mar 15, 2026
28fa48f
Merge remote-tracking branch 'origin/linux' into linux
ConnorC432 Mar 15, 2026
6811cdf
build linux packages correctly
ConnorC432 Mar 15, 2026
e8bd6ba
updated linux build guide
ConnorC432 Mar 15, 2026
1dc5dd7
add Firmware to packages
ConnorC432 Mar 15, 2026
aa6833b
Revert "ignore empty frames from capture card"
ConnorC432 Mar 15, 2026
3f812f2
suppress sleep on linux using dbus inhibitor lock
ConnorC432 Mar 19, 2026
2c0dd25
Merge branch 'PokemonAutomation:main' into linux
ConnorC432 Mar 19, 2026
b51b950
Revert "suppress sleep on linux using dbus inhibitor lock"
ConnorC432 Mar 19, 2026
dcc01b1
Revert "onnx gpu hw accel for linux"
ConnorC432 Mar 20, 2026
0c030a5
Revert "fix compile using onnxruntime 1.24.x"
ConnorC432 Mar 20, 2026
0daf090
Revert "detect system onnxruntime with pkg-config"
ConnorC432 Mar 20, 2026
ac14f38
Revert "default auto-reset to 0 on linux builds to prevent black fram…
ConnorC432 Mar 20, 2026
1bf50f3
Revert "Default to gstreamer backend to prevent capture card flickering"
ConnorC432 Mar 20, 2026
4cd65cb
libsystemd-dev build requirement
ConnorC432 Mar 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# How to Build (Qt 6.8.2) - Ubuntu 24.04
# How to Build (Qt 6.8.2) - Linux

Note that our Ubuntu setup does not work. The video display flickers to the point of being unusable.
Note that our Linux setup might not work. The video display can flicker to the point of being unusable.

## Build Tools:

Install the following packages:
Install the following build requirements, these steps will use ubuntu packages but the steps will be the same on your distro:

```
sudo apt install cmake
sudo apt install libglx-dev libgl1-mesa-dev
sudo apt install libopencv-dev
git cmake ninja-build gcc g++ qt6-base-dev qt6-multimedia-dev qt6-serialport-dev libopencv-dev libonnx-dev libasound2-dev libsystemd-dev
dpkg # To build .deb packages for Debian based distros
rpm # To build .rpm packages for RHEL based distros
pacman-package-manager # To build .pkg packages for Arch based distros
```


Expand All @@ -30,20 +31,30 @@ sudo apt install libopencv-dev
![](Images/Windows-Install-Qt6.7.3-Custom.png)
![](Images/Windows-Install-Qt6.8.2-Components.png)

### Alternatively:
1. ```curl -L https://download.qt.io/official_releases/online_installers/qt-online-installer-linux-x64-online.run -o qt.run```
2. ```chmod +x qt.run```
3. ```./qt.run install qt6.8.2-full-dev```
4. ```export CMAKE_PREFIX_PATH=/opt/Qt/6.8.2/gcc_64:$CMAKE_PREFIX_PATH```

## Setup:

### Package:
1. Clone this repo.
2. Clone the [Packages Repo](https://github.com/PokemonAutomation/Packages).
3. In the `Packages` repo, copy the `SerialPrograms/Resources` folder into the root of the `Arduino-Source` repo.

![](Images/Directory.png)

4. Open Qt Creator.
5. Click on `File` -> `Open File or Project`.
6. Navigate to `SerialPrograms` and select `CMakeLists.txt`.
7. Enable parallel build: Build & Run -> Build Steps -> Build -> Details -> CMake arguments: `-j16` (the # of cores you have)
8. At the bottom left corner, click on the little monitor and select `Release with Debug Information`.
9. Still in the bottom left corner, click the upper green arrow to compile and launch the program.
2. Open a terminal in the folder ```Arduino-Source/SerialPrograms/Scripts/Linux```
3. Run the script ```./packages.sh (PACKAGE TYPE)```
- PACKAGE TYPE:
- DEB - .deb package
- RPM - .rpm package
- PKG - .pkg package
- TGZ - Generic package
4. Find the package at ```/Arduino-Source/SerialPrograms/build```
5. Install the package ```apt install ./pokemon-automation--x86_64.deb```

### Source:
1. Clone this repo.
2. Open a terminal in ```Arduino-Source/SerialPrograms```
3. Compile the source code ```cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O2 -march=native -Wno-odr" -DCMAKE_CXX_FLAGS="-O2 -march=native -Wno-odr" && ninja -C build```

<hr>

Expand Down
1 change: 1 addition & 0 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -713,3 +713,4 @@ endif()

# Add command-line executable (GUI-free) from subdirectory
include(Source/CommandLine/CommandLineExecutable.cmake)
include(cmake/CPack.cmake)
65 changes: 65 additions & 0 deletions SerialPrograms/Scripts/Linux/PKGBUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
pkgname=pokemon-automation
pkgver=1
pkgrel=1
pkgdesc="Pokemon Automation Serial Programs"
arch=('x86_64')
url="https://github.com/PokemonAutomation/Arduino-Source"
license=('MIT')
options=('!debug')

depends=('qt6-base' 'qt6-multimedia' 'qt6-serialport' 'qt6-imageformats' \
'qt6-multimedia-gstreamer' 'gstreamer' 'opencv' 'mesa' \
'libglvnd' 'hdf5' 'vtk' 'tesseract' 'onnxruntime')

makedepends=('cmake' 'ninja')

source=("Arduino-Source.tar.gz")
sha256sums=('SKIP')

build() {
CCACHE_ARGS=()
if command -v ccache >/dev/null 2>&1; then
echo "[INFO] Using ccache for compilation"
CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache)
fi

mkdir -p "$srcdir/Arduino-Source/SerialPrograms/build"
cd "$srcdir/Arduino-Source/SerialPrograms/build"

cmake .. \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-O2 -g0 -fno-record-gcc-switches -fno-ident -Wno-odr" \
-DCMAKE_CXX_FLAGS="-O2 -g0 -fno-record-gcc-switches -fno-ident -Wno-odr" \
"${CCACHE_ARGS[@]}"

ninja -j$(( $(nproc) - 1))
}

package() {
install -Dm755 $srcdir/Arduino-Source/SerialPrograms/build/SerialPrograms \
"$pkgdir/usr/bin/SerialPrograms"

install -d "$pkgdir/usr/share/SerialPrograms"
cp -r "$srcdir/Arduino-Source/SerialPrograms/build/Resources/." \
"$pkgdir/usr/share/SerialPrograms/Resources/"
cp -r "$srcdir/Arduino-Source/SerialPrograms/build/Firmware/." \
"$pkgdir/usr/share/SerialPrograms/Firmware/"

install -d "$pkgdir/usr/share/icons/hicolor/256x256/apps"
install -Dm644 $srcdir/Arduino-Source/IconResource/SerialPrograms.png \
"$pkgdir/usr/share/icons/hicolor/256x256/apps/SerialPrograms.png"

install -d "$pkgdir/usr/share/applications"
cat > "$pkgdir/usr/share/applications/SerialPrograms.desktop" <<EOF
[Desktop Entry]
Name=Pokemon Automation
Exec=/usr/bin/SerialPrograms
Icon=SerialPrograms
Type=Application
Categories=Utility;
EOF

install -Dm644 $srcdir/Arduino-Source/LICENSE -t \
"${pkgdir}/usr/share/licenses/SerialPrograms/"
}
101 changes: 101 additions & 0 deletions SerialPrograms/Scripts/Linux/packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/bash
#
# Usage:
# ./packages.sh [PACKAGE_TYPE]
#
# PACKAGE_TYPE (optional):
# DEB
# RPM
# TGZ
# PKG
#

# Config
AVAILABLE_TYPES=("DEB" "RPM" "TGZ" "PKG")
declare -A TOOLS=(
[DEB]="dpkg"
[RPM]="rpmbuild"
[TGZ]=""
[PKG]="makepkg"
)

SCRIPT_DIR="$(realpath "$(dirname "$0")")"
SOURCE_DIR="${SCRIPT_DIR}/../../../SerialPrograms/"
BUILD_DIR="${SOURCE_DIR}/build/"


# Arg Parse
BUILD_TYPE="$1"
if [[ -n "$BUILD_TYPE" ]]; then
BUILD_TYPE="${BUILD_TYPE^^}"
if [[ ! " ${AVAILABLE_TYPES[*]} " =~ " $BUILD_TYPE " ]]; then
echo "Invalid package type: $BUILD_TYPE"
echo "Valid types: ${AVAILABLE_TYPES[*]}"
exit 1
fi
TARGETS=("$BUILD_TYPE")
else
TARGETS=("${AVAILABLE_TYPES[@]}")
fi


# Check Tools
echo "Checking required packaging tools..."
for pkg in "${TARGETS[@]}"; do
TOOL=${TOOLS[$pkg]}
if [[ -n "$TOOL" ]]; then
if ! command -v "$TOOL" >/dev/null 2>&1; then
echo " [MISSING] $pkg requires $TOOL"
TARGETS=("${TARGETS[@]/$pkg}")
else
echo " [OK] $pkg -> $TOOL found"
fi
else
echo " [OK] $pkg -> no external tool required"
fi
done


# Check CCache
CCACHE_ARGS=()
if command -v ccache >/dev/null 2>&1; then
echo " [INFO] ccache found, caching compilation"
CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache)
fi


# Build CMake
cd "$SOURCE_DIR"
cmake "$SOURCE_DIR" -G Ninja -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-O2 -g0 -fno-record-gcc-switches -fno-ident -Wno-odr" \
-DCMAKE_CXX_FLAGS="-O2 -g0 -fno-record-gcc-switches -fno-ident -Wno-odr" \
"${CCACHE_ARGS[@]}"

cd "$SOURCE_DIR/build"
ninja -j$(( $(nproc) - 1))


# Build Packages
cd "$BUILD_DIR"
for pkg in "${TARGETS[@]}"; do
case "$pkg" in
DEB|RPM|TGZ)
echo "Building $pkg package with CPack..."
cpack -G "$pkg"
;;
PKG)
echo "Building PKG package with makepkg..."
cp "$SCRIPT_DIR/PKGBUILD" "."
git -C "$SOURCE_DIR/.." archive --format=tar.gz --prefix=Arduino-Source/ \
HEAD > "Arduino-Source.tar.gz"
makepkg -Cf
;;
*)
echo "Unknown package type: $pkg"
;;
esac
done

echo "Package creation complete."
echo "Packages can be found here: $BUILD_DIR"
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ GlobalSettings::GlobalSettings()
false,
"<b>Stats File:</b><br>Use the stats file here. Multiple instances of the program can use the same file.",
LockMode::LOCK_WHILE_RUNNING,
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__linux__)
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString() + "/UserSettings/PA-Stats.txt",
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString() + "/UserSettings/PA-Stats.txt"
#else
Expand All @@ -133,6 +133,10 @@ GlobalSettings::GlobalSettings()
#if defined(__APPLE__)
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString() + "/TempFiles/",
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).toStdString() + "/TempFiles/"
#elif defined(__linux__)
// /tmp/
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString(),
QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString()
#else
"TempFiles/",
"TempFiles/"
Expand Down
26 changes: 26 additions & 0 deletions SerialPrograms/Source/CommonFramework/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ const size_t LOG_HISTORY_LINES = 10000;
namespace{

QString get_application_base_dir_path(){
#if defined(__linux__)
// ~/.local/share/SerialPrograms
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
#else
QString application_dir_path = qApp->applicationDirPath();
if (application_dir_path.endsWith(".app/Contents/MacOS")){
// a macOS bundle. Change working directory to the folder that hosts the .app folder.
Expand All @@ -122,8 +126,24 @@ QString get_application_base_dir_path(){
return base_folder_path;
}
return application_dir_path;
#endif
}
std::string get_resource_path(){
#if defined(__linux__)
// Look for Resources installed as part of a package
QString system_path = "/usr/share/SerialPrograms/Resources/";
if (QDir(system_path).exists()) {
return system_path.toStdString();
}
// Check for Resources in the current working directory
QString cwd_path = "./Resources/";
if (QDir(cwd_path).exists()) {
return cwd_path.toStdString();
}
// Prevents a prompt telling the user to install Resources to /usr/Resources
// if the binary is located at /usr/bin/SerialPrograms
return (get_application_base_dir_path() + "/Resources/").toStdString();
#else
// Find the resource directory.
QString path = get_application_base_dir_path();
for (size_t c = 0; c < 5; c++){
Expand All @@ -135,6 +155,7 @@ std::string get_resource_path(){
path += "/..";
}
return (QCoreApplication::applicationDirPath() + "/../Resources/").toStdString();
#endif
}
std::string get_training_path(){
// Find the training data directory.
Expand All @@ -151,6 +172,10 @@ std::string get_training_path(){
}

std::string get_runtime_base_path(){
#if defined(__linux__)
// ~/.local/share/SerialPrograms/
return (get_application_base_dir_path() + "/").toStdString();
#else
// On MacOS, find the writable application support directory
if (QSysInfo::productType() == "macos" || QSysInfo::productType() == "osx"){
// QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) returns
Expand All @@ -167,6 +192,7 @@ std::string get_runtime_base_path(){
return appSupportPath.toStdString() + "/";
}
return "./";
#endif
}

std::string get_setting_path(){
Expand Down
8 changes: 8 additions & 0 deletions SerialPrograms/Source/CommonFramework/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "Windows/MainWindow.h"

#include <iostream>
#include <QStandardPaths>
using std::cout;
using std::endl;

Expand All @@ -48,13 +49,20 @@ using namespace PokemonAutomation;
Q_DECLARE_METATYPE(std::string)

void set_working_directory(){
#if defined(__linux__)
// ~/.local/share/SerialPrograms
QString base_folder_path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
std::cout << base_folder_path.toStdString() << std::endl;
QDir::setCurrent(base_folder_path);
#else
QString application_dir_path = qApp->applicationDirPath();
if (application_dir_path.endsWith(".app/Contents/MacOS")){
// a macOS bundle. Change working directory to the folder that hosts the .app folder.
QString app_bundle_path = application_dir_path.chopped(15);
QString base_folder_path = QFileInfo(app_bundle_path).dir().absolutePath();
QDir::setCurrent(base_folder_path);
}
#endif
}


Expand Down
Loading
Loading