From 8379cf2dcc33b84bcf4448715cfe0eef6735662f Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Wed, 11 Mar 2026 21:43:00 +0000 Subject: [PATCH 01/25] Default to gstreamer backend to prevent capture card flickering --- SerialPrograms/Source/CommonFramework/Main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SerialPrograms/Source/CommonFramework/Main.cpp b/SerialPrograms/Source/CommonFramework/Main.cpp index 455b9a2f96..25c1d5679e 100644 --- a/SerialPrograms/Source/CommonFramework/Main.cpp +++ b/SerialPrograms/Source/CommonFramework/Main.cpp @@ -201,6 +201,12 @@ int main(int argc, char *argv[]){ set_program_path(argv[0]); #endif +#if defined(__linux__) + // Qt multimedia, default to gstreamer to prevent flickering + if (qEnvironmentVariableIsEmpty("QT_MEDIA_BACKEND")) + qputenv("QT_MEDIA_BACKEND", "gstreamer"); +#endif + // So far, this is only needed on Mac where static initialization is fucked up. PokemonAutomation::register_all_statics(); From 8ed547cf0735f7e4f31c7551f12fb6595d968b99 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Wed, 11 Mar 2026 21:49:15 +0000 Subject: [PATCH 02/25] Use unix directories for Resources and persistent data --- .../CommonFramework/GlobalSettingsPanel.cpp | 6 +++++- .../Source/CommonFramework/Globals.cpp | 17 +++++++++++++++++ SerialPrograms/Source/CommonFramework/Main.cpp | 8 ++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp index 0af765e2a0..5cfe805e92 100644 --- a/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp +++ b/SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp @@ -118,7 +118,7 @@ GlobalSettings::GlobalSettings() false, "Stats File:
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 @@ -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/" diff --git a/SerialPrograms/Source/CommonFramework/Globals.cpp b/SerialPrograms/Source/CommonFramework/Globals.cpp index 66ac309261..55bdb1ecbb 100644 --- a/SerialPrograms/Source/CommonFramework/Globals.cpp +++ b/SerialPrograms/Source/CommonFramework/Globals.cpp @@ -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. @@ -122,8 +126,16 @@ 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(); + } +#endif // Fallback to ~/.local/share/SerialPrograms/Resources // Find the resource directory. QString path = get_application_base_dir_path(); for (size_t c = 0; c < 5; c++){ @@ -151,6 +163,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 @@ -167,6 +183,7 @@ std::string get_runtime_base_path(){ return appSupportPath.toStdString() + "/"; } return "./"; +#endif } std::string get_setting_path(){ diff --git a/SerialPrograms/Source/CommonFramework/Main.cpp b/SerialPrograms/Source/CommonFramework/Main.cpp index 25c1d5679e..ad1c5d6e63 100644 --- a/SerialPrograms/Source/CommonFramework/Main.cpp +++ b/SerialPrograms/Source/CommonFramework/Main.cpp @@ -39,6 +39,7 @@ #include "Windows/MainWindow.h" #include +#include using std::cout; using std::endl; @@ -48,6 +49,12 @@ 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. @@ -55,6 +62,7 @@ void set_working_directory(){ QString base_folder_path = QFileInfo(app_bundle_path).dir().absolutePath(); QDir::setCurrent(base_folder_path); } +#endif } From 468c0a9e062db667daf80794793e49e4cfa98136 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Wed, 11 Mar 2026 23:09:53 +0000 Subject: [PATCH 03/25] look for Resources in ~/.local/share/SerialPrograms instead of ../Resources --- SerialPrograms/Source/CommonFramework/Globals.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/CommonFramework/Globals.cpp b/SerialPrograms/Source/CommonFramework/Globals.cpp index 55bdb1ecbb..763026fd29 100644 --- a/SerialPrograms/Source/CommonFramework/Globals.cpp +++ b/SerialPrograms/Source/CommonFramework/Globals.cpp @@ -135,7 +135,10 @@ std::string get_resource_path(){ if (QDir(system_path).exists()) { return system_path.toStdString(); } -#endif // Fallback to ~/.local/share/SerialPrograms/Resources + // 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++){ @@ -147,6 +150,7 @@ std::string get_resource_path(){ path += "/.."; } return (QCoreApplication::applicationDirPath() + "/../Resources/").toStdString(); +#endif } std::string get_training_path(){ // Find the training data directory. From 0dd6834fa381e3c5e7543c4e3c9b9e8502e1d6f9 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 13 Mar 2026 15:49:37 +0000 Subject: [PATCH 04/25] detect system onnxruntime with pkg-config --- SerialPrograms/CMakeLists.txt | 137 +++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index ec74150758..14aedfe161 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -379,74 +379,87 @@ else() # macOS and Linux # extract it, and then link it up # Set the ONNXRUNTIME version and arch, allows for quick updates - set(ONNXRUNTIME_VERSION "1.23.0") - set(ONNXRUNTIME_ARCH "x64") - set(ONNXRUNTIME_DIR_NAME "onnxruntime-linux-${ONNXRUNTIME_ARCH}-${ONNXRUNTIME_VERSION}") - set(ONNXRUNTIME_TGZ_NAME "${ONNXRUNTIME_DIR_NAME}.tgz") - # build up the URL based on the version and name - set(ONNXRUNTIME_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/${ONNXRUNTIME_TGZ_NAME}") - - # Cache variable is editable by users *and* is properly stored - set(ONNX_ROOT_PATH "" CACHE PATH "Path to the root of a pre-installed ONNX Runtime (e.g., /path/to/onnxruntime-linux-x64-1.23.0)") - - # Download the onnxruntime if it doesn't exist or if the path is bad - if(NOT ONNX_ROOT_PATH OR NOT EXISTS "${ONNX_ROOT_PATH}/include/onnxruntime_cxx_api.h") - set(EXTRACTED_ONNX_PATH "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_DIR_NAME}") - - if(NOT IS_DIRECTORY ${EXTRACTED_ONNX_PATH}) - message(STATUS "ONNX_ROOT_PATH not found. Downloading ONNX Runtime v${ONNXRUNTIME_VERSION}...") - - # logic for downloading... - set(DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_TGZ_NAME}") - file(DOWNLOAD - ${ONNXRUNTIME_URL} - ${DOWNLOAD_LOCATION} - SHOW_PROGRESS - STATUS download_status - ) - list(GET download_status 0 error_code) - if(NOT error_code EQUAL 0) - list(GET download_status 1 error_message) - message(FATAL_ERROR "Failed to download ONNX Runtime: ${error_message}") - endif() + pkg_check_modules(ONNXRUNTIME QUIET libonnxruntime) - # logic for extracting the tarball to our working directory - message(STATUS "Extracting ONNX Runtime...") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf "${DOWNLOAD_LOCATION}" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - endif() + if(ONNXRUNTIME_FOUND) + message(STATUS "Found system installed ONNX Runtime") + + message(STATUS "Found ONNX Include Dirs: ${ONNXRUNTIME_INCLUDE_DIRS}") + message(STATUS "Found ONNX Library: ${ONNXRUNTIME_LIBRARIES}") + + target_include_directories(SerialProgramsLib PUBLIC ${ONNXRUNTIME_INCLUDE_DIRS}) + target_link_libraries(SerialProgramsLib PUBLIC ${ONNXRUNTIME_LIBRARIES}) - # Update the ONNX_ROOT_PATH to point to our downloaded version, force ensures we update it - set(ONNX_ROOT_PATH "${EXTRACTED_ONNX_PATH}" CACHE PATH "Path to the downloaded ONNX Runtime" FORCE) - message(STATUS "Using downloaded ONNX Runtime at: ${ONNX_ROOT_PATH}") else() - message(STATUS "Using user-provided ONNX Runtime at: ${ONNX_ROOT_PATH}") - endif() + set(ONNXRUNTIME_VERSION "1.23.0") + set(ONNXRUNTIME_ARCH "x64") + set(ONNXRUNTIME_DIR_NAME "onnxruntime-linux-${ONNXRUNTIME_ARCH}-${ONNXRUNTIME_VERSION}") + set(ONNXRUNTIME_TGZ_NAME "${ONNXRUNTIME_DIR_NAME}.tgz") + # build up the URL based on the version and name + set(ONNXRUNTIME_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/${ONNXRUNTIME_TGZ_NAME}") + + # Cache variable is editable by users *and* is properly stored + set(ONNX_ROOT_PATH "" CACHE PATH "Path to the root of a pre-installed ONNX Runtime (e.g., /path/to/onnxruntime-linux-x64-1.23.0)") + + # Download the onnxruntime if it doesn't exist or if the path is bad + if(NOT ONNX_ROOT_PATH OR NOT EXISTS "${ONNX_ROOT_PATH}/include/onnxruntime_cxx_api.h") + set(EXTRACTED_ONNX_PATH "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_DIR_NAME}") + + if(NOT IS_DIRECTORY ${EXTRACTED_ONNX_PATH}) + message(STATUS "ONNX_ROOT_PATH not found. Downloading ONNX Runtime v${ONNXRUNTIME_VERSION}...") + + # logic for downloading... + set(DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_TGZ_NAME}") + file(DOWNLOAD + ${ONNXRUNTIME_URL} + ${DOWNLOAD_LOCATION} + SHOW_PROGRESS + STATUS download_status + ) + list(GET download_status 0 error_code) + if(NOT error_code EQUAL 0) + list(GET download_status 1 error_message) + message(FATAL_ERROR "Failed to download ONNX Runtime: ${error_message}") + endif() + + # logic for extracting the tarball to our working directory + message(STATUS "Extracting ONNX Runtime...") + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xzf "${DOWNLOAD_LOCATION}" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + endif() - # configure and find headers from the onnxruntime - find_path(ONNX_INCLUDE_DIRS - NAMES onnxruntime_cxx_api.h - HINTS "${ONNX_ROOT_PATH}/include" - REQUIRED - ) + # Update the ONNX_ROOT_PATH to point to our downloaded version, force ensures we update it + set(ONNX_ROOT_PATH "${EXTRACTED_ONNX_PATH}" CACHE PATH "Path to the downloaded ONNX Runtime" FORCE) + message(STATUS "Using downloaded ONNX Runtime at: ${ONNX_ROOT_PATH}") + else() + message(STATUS "Using user-provided ONNX Runtime at: ${ONNX_ROOT_PATH}") + endif() - find_library(ONNX_RUNTIME_LIB - NAMES onnxruntime - HINTS "${ONNX_ROOT_PATH}/lib" - REQUIRED - ) + # configure and find headers from the onnxruntime + find_path(ONNX_INCLUDE_DIRS + NAMES onnxruntime_cxx_api.h + HINTS "${ONNX_ROOT_PATH}/include" + REQUIRED + ) - if(ONNX_INCLUDE_DIRS AND ONNX_RUNTIME_LIB) - # only link if it was found, otherwise we error out - message(STATUS "Found ONNX Include Dirs: ${ONNX_INCLUDE_DIRS}") - message(STATUS "Found ONNX Library: ${ONNX_RUNTIME_LIB}") - target_include_directories(SerialProgramsLib PUBLIC "${ONNX_INCLUDE_DIRS}") - target_link_libraries(SerialProgramsLib PUBLIC "${ONNX_RUNTIME_LIB}") - else() - message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") - endif() + find_library(ONNX_RUNTIME_LIB + NAMES onnxruntime + HINTS "${ONNX_ROOT_PATH}/lib" + REQUIRED + ) + + if(ONNX_INCLUDE_DIRS AND ONNX_RUNTIME_LIB) + # only link if it was found, otherwise we error out + message(STATUS "Found ONNX Include Dirs: ${ONNX_INCLUDE_DIRS}") + message(STATUS "Found ONNX Library: ${ONNX_RUNTIME_LIB}") + target_include_directories(SerialProgramsLib PUBLIC "${ONNX_INCLUDE_DIRS}") + target_link_libraries(SerialProgramsLib PUBLIC "${ONNX_RUNTIME_LIB}") + else() + message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") + endif() + endif () endif() # end Linux # Find OpenCV From 18966ad5b0ee08448872e783d0f0f2b6856c4873 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 13 Mar 2026 17:24:46 +0000 Subject: [PATCH 05/25] fix compile using onnxruntime 1.24.x --- SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp index 2171a6ea82..822345f76c 100644 --- a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp +++ b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp @@ -203,10 +203,7 @@ void print_model_input_output_info(const Ort::Session& session){ } Ort::Env create_ORT_env(){ - if (Ort::Global::api_ == nullptr){ - throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Onnx API returned a null pointer."); - } - + // Bit redundant now, but still might be useful to add logging or other init? return Ort::Env(); } From 91b9570e54cab7c108a3e479887bc24a41703d7b Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 13 Mar 2026 17:44:24 +0000 Subject: [PATCH 06/25] onnx gpu hw accel for linux --- .../ML/Models/ML_ONNXRuntimeHelpers.cpp | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp index 822345f76c..ce1447b6b2 100644 --- a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp +++ b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp @@ -86,6 +86,28 @@ if (use_gpu){ std::cout << "DirectML execution provider not available, falling back to CPU: " << e.what() << std::endl; } } +#elif defined(__linux__) + // Try CUDA first for NVIDIA GPUs (best performance) + // See: https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html + try { + OrtCUDAProviderOptions cuda_options{}; + cuda_options.device_id = 0; + so.AppendExecutionProvider_CUDA(cuda_options); + std::cout << "Using CUDA execution provider for GPU acceleration" << std::endl; + } catch (const Ort::Exception& e) { + std::cout << "CUDA execution provider not available, trying ROCm: " << e.what() << std::endl; + + // Try ROCm next for AMD GPUs + // See: https://onnxruntime.ai/docs/execution-providers/ROCm-ExecutionProvider.html + try { + OrtROCMProviderOptions rocm_options{}; + rocm_options.device_id = 0; + so.AppendExecutionProvider_ROCM(rocm_options); + std::cout << "Using ROCm execution provider for GPU acceleration" << std::endl; + } catch (const Ort::Exception& e) { + std::cout << "ROCm execution provider not available, falling back to CPU: " << e.what() << std::endl; + } + } #endif } From 741b986caffd6848ffc9a6c8d9a53ea1c45310a1 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 13 Mar 2026 17:48:40 +0000 Subject: [PATCH 07/25] look for Resources in cwd --- SerialPrograms/Source/CommonFramework/Globals.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SerialPrograms/Source/CommonFramework/Globals.cpp b/SerialPrograms/Source/CommonFramework/Globals.cpp index 763026fd29..f291c6ae55 100644 --- a/SerialPrograms/Source/CommonFramework/Globals.cpp +++ b/SerialPrograms/Source/CommonFramework/Globals.cpp @@ -135,6 +135,11 @@ std::string get_resource_path(){ 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(); From 562a9f4d26e8fc530f5c3b897d64912d908f7e6a Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sat, 14 Mar 2026 12:49:55 +0000 Subject: [PATCH 08/25] ignore empty frames from capture card --- .../VideoPipeline/Backends/CameraWidgetQt6.5.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp b/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp index 28229c3293..84b15855ff 100644 --- a/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp +++ b/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp @@ -190,6 +190,9 @@ void CameraVideoSource::set_video_output(QGraphicsVideoItem& item){ &m_camera->camera(), [&](const QVideoFrame& frame){ // This runs on the QCamera's thread. So it is off the critical path. + if (frame.size().isEmpty() || frame.bytesPerLine(0) == 0) + return; // Ignore empty frames + WallClock now = current_time(); if (!m_last_frame.push_frame(frame, now)){ return; From 04a61e076277a461c493bb3679e7fac2013b233c Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sat, 14 Mar 2026 20:42:28 +0000 Subject: [PATCH 09/25] default auto-reset to 0 on linux builds to prevent black frames on reset --- .../CommonFramework/VideoPipeline/VideoPipelineOptions.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h index e7a4d19133..c1f7dc20bb 100644 --- a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h +++ b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h @@ -34,9 +34,13 @@ class VideoPipelineOptions : public GroupOption{ , AUTO_RESET_SECONDS( "Video Auto-Reset:
" "Attempt to reset the video if this many seconds has elapsed since the last video frame (in order to fix issues with RDP disconnection, etc).
" - "This option is not supported by all video frameworks.", + "This option is not supported by all video frameworks. Set to a value of 0 to disable Auto-Reset.", LockMode::UNLOCK_WHILE_RUNNING, +#if defined(__linux__) + 0 // Default to disabled on linux, auto-resets briefly output black frames +#else 5 +#endif ) { PA_ADD_OPTION(VIDEO_BACKEND); From df8d96751b269e2f6b6d24c40fb0a294180f60c9 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sat, 14 Mar 2026 23:41:59 +0000 Subject: [PATCH 10/25] CPack config to build linux packages --- SerialPrograms/CMakeLists.txt | 1 + SerialPrograms/cmake/CPack.cmake | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 SerialPrograms/cmake/CPack.cmake diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 14aedfe161..fa52cb5b28 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -726,3 +726,4 @@ endif() # Add command-line executable (GUI-free) from subdirectory include(Source/CommandLine/CommandLineExecutable.cmake) +include(cmake/CPack.cmake) \ No newline at end of file diff --git a/SerialPrograms/cmake/CPack.cmake b/SerialPrograms/cmake/CPack.cmake new file mode 100644 index 0000000000..cccf8c5230 --- /dev/null +++ b/SerialPrograms/cmake/CPack.cmake @@ -0,0 +1,57 @@ +### Packaging +# Install binary +install( + TARGETS SerialPrograms + RUNTIME DESTINATION bin +) + +# Resources +install( + DIRECTORY ${CMAKE_BINARY_DIR}/Resources/ + DESTINATION share/SerialPrograms/Resources +) + +# App icon +install( + FILES ${CMAKE_SOURCE_DIR}/../IconResource/SerialPrograms.png + DESTINATION share/icons/hicolor/256x256/apps +) + +# Desktop Entry +install( + FILES ${CMAKE_SOURCE_DIR}/../IconResource/SerialPrograms.desktop + DESTINATION share/applications +) + +# License +install( + FILES ${CMAKE_SOURCE_DIR}/../LICENSE + DESTINATION share/licenses/SerialPrograms +) + +### CPack Config +set(CPACK_GENERATOR "DEB;RPM;TGZ") +set(CPACK_PACKAGE_NAME "pokemon-automation") +set(CPACK_PACKAGE_VERSION ${SerialPrograms_VERSION}) +set(CPACK_PACKAGING_INSTALL_PREFIX "/usr") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") + +# Debian +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "PokemonAutomation") +set(CPACK_DEBIAN_PACKAGE_DEPENDS + "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, qt6-imageformats-plugins, \ + gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-ugly, \ + libopencv-core4.6, libopencv-imgproc4.6, libglx0, libgl1, libhdf5-103, libvtk7.1, tesseract-ocr, \ + onnxruntime-tools" +) + +# RPM +set(CPACK_RPM_PACKAGE_LICENSE "MIT") +set(CPACK_RPM_PACKAGE_GROUP "Applications/Utilities") +set(CPACK_RPM_PACKAGE_REQUIRES + "qt6-qtbase, qt6-qtmultimedia, qt6-qtserialport, qt6-qtimageformats, gstreamer1, gstreamer1-plugins-base, \ + gstreamer1-plugins-good, gstreamer1-plugins-bad-free, gstreamer1-plugins-ugly, gstreamer-plugin-libav, \ + opencv, mesa-libGL, libglvnd, hdf5, vtk, tesseract, leptonica, onnxruntime" +) + +include(CPack) \ No newline at end of file From b05aac9680180823684a5d41e19691ab8aa3b117 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 01:53:04 +0000 Subject: [PATCH 11/25] linux packaging scripts --- SerialPrograms/Scripts/Linux/PKGBUILD | 63 ++++++++++++++ SerialPrograms/Scripts/Linux/packages.sh | 101 +++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 SerialPrograms/Scripts/Linux/PKGBUILD create mode 100644 SerialPrograms/Scripts/Linux/packages.sh diff --git a/SerialPrograms/Scripts/Linux/PKGBUILD b/SerialPrograms/Scripts/Linux/PKGBUILD new file mode 100644 index 0000000000..fd4d9c1a13 --- /dev/null +++ b/SerialPrograms/Scripts/Linux/PKGBUILD @@ -0,0 +1,63 @@ +pkgname=pokemon-automation +pkgver=0.62.5 +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/" + + 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" </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" \ No newline at end of file From 40a6f0b213eed5b4e3a65331ce61cd8cd8621e7a Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 12:13:06 +0000 Subject: [PATCH 12/25] fix debian package requirements --- SerialPrograms/cmake/CPack.cmake | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SerialPrograms/cmake/CPack.cmake b/SerialPrograms/cmake/CPack.cmake index cccf8c5230..108a712383 100644 --- a/SerialPrograms/cmake/CPack.cmake +++ b/SerialPrograms/cmake/CPack.cmake @@ -39,11 +39,9 @@ set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}-${CMAKE_SY # Debian set(CPACK_DEBIAN_PACKAGE_MAINTAINER "PokemonAutomation") set(CPACK_DEBIAN_PACKAGE_DEPENDS - "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, qt6-imageformats-plugins, \ + "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, qt6-image-formats-plugins, \ gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-ugly, \ - libopencv-core4.6, libopencv-imgproc4.6, libglx0, libgl1, libhdf5-103, libvtk7.1, tesseract-ocr, \ - onnxruntime-tools" -) + libopencv-core, libopencv-imgproc, libglx0, libgl1, libhdf5, libvtk, tesseract-ocr, libonnx" # RPM set(CPACK_RPM_PACKAGE_LICENSE "MIT") From c835b8a8bf41b8a4c835ad20a24a291cdecae8de Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 12:13:06 +0000 Subject: [PATCH 13/25] fix debian package requirements --- SerialPrograms/cmake/CPack.cmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/SerialPrograms/cmake/CPack.cmake b/SerialPrograms/cmake/CPack.cmake index cccf8c5230..1abdc33071 100644 --- a/SerialPrograms/cmake/CPack.cmake +++ b/SerialPrograms/cmake/CPack.cmake @@ -39,10 +39,9 @@ set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}-${CMAKE_SY # Debian set(CPACK_DEBIAN_PACKAGE_MAINTAINER "PokemonAutomation") set(CPACK_DEBIAN_PACKAGE_DEPENDS - "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, qt6-imageformats-plugins, \ + "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, qt6-image-formats-plugins, \ gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-ugly, \ - libopencv-core4.6, libopencv-imgproc4.6, libglx0, libgl1, libhdf5-103, libvtk7.1, tesseract-ocr, \ - onnxruntime-tools" + libopencv-core, libopencv-imgproc, libglx0, libgl1, libhdf5, libvtk, tesseract-ocr, libonnx" ) # RPM From 6811cdfd8c530050b5b1716f40d2453cd24aa647 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 12:48:44 +0000 Subject: [PATCH 14/25] build linux packages correctly --- SerialPrograms/Scripts/Linux/PKGBUILD | 2 +- SerialPrograms/Scripts/Linux/packages.sh | 0 SerialPrograms/cmake/CPack.cmake | 22 +++++++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) mode change 100644 => 100755 SerialPrograms/Scripts/Linux/packages.sh diff --git a/SerialPrograms/Scripts/Linux/PKGBUILD b/SerialPrograms/Scripts/Linux/PKGBUILD index fd4d9c1a13..3c80ac0fbf 100644 --- a/SerialPrograms/Scripts/Linux/PKGBUILD +++ b/SerialPrograms/Scripts/Linux/PKGBUILD @@ -1,5 +1,5 @@ pkgname=pokemon-automation -pkgver=0.62.5 +pkgver=1 pkgrel=1 pkgdesc="Pokemon Automation Serial Programs" arch=('x86_64') diff --git a/SerialPrograms/Scripts/Linux/packages.sh b/SerialPrograms/Scripts/Linux/packages.sh old mode 100644 new mode 100755 diff --git a/SerialPrograms/cmake/CPack.cmake b/SerialPrograms/cmake/CPack.cmake index 1abdc33071..26984ea4fe 100644 --- a/SerialPrograms/cmake/CPack.cmake +++ b/SerialPrograms/cmake/CPack.cmake @@ -29,6 +29,21 @@ install( DESTINATION share/licenses/SerialPrograms ) +# Discord Partner Library +install( + FILES ${CMAKE_SOURCE_DIR}/../3rdPartyBinaries/discord_social_sdk_linux/lib/release/libdiscord_partner_sdk.so + DESTINATION lib + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +) + +# ONNX Runtime Library +install( + FILES ${CMAKE_BINARY_DIR}/onnxruntime-linux-x64-1.23.0/lib/libonnxruntime.so.1.23.0 + DESTINATION lib + RENAME libonnxruntime.so.1 + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +) + ### CPack Config set(CPACK_GENERATOR "DEB;RPM;TGZ") set(CPACK_PACKAGE_NAME "pokemon-automation") @@ -39,9 +54,10 @@ set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}-${CMAKE_SY # Debian set(CPACK_DEBIAN_PACKAGE_MAINTAINER "PokemonAutomation") set(CPACK_DEBIAN_PACKAGE_DEPENDS - "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, qt6-image-formats-plugins, \ - gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-ugly, \ - libopencv-core, libopencv-imgproc, libglx0, libgl1, libhdf5, libvtk, tesseract-ocr, libonnx" + "libqt6core6, libqt6gui6, libqt6widgets6, libqt6multimedia6, libqt6serialport6, libqt6multimediawidgets6, \ + qt6-image-formats-plugins, gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad, \ + gstreamer1.0-plugins-ugly, libopencv-core410, libopencv-imgproc410, libglx0, libgl1, libhdf5-310, libvtk9.3, \ + tesseract-ocr" ) # RPM From e8bd6badbb802d8badd3e411c60852b301bb6bbf Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 14:38:25 +0000 Subject: [PATCH 15/25] updated linux build guide --- .../BuildInstructions/Build-Ubuntu-Qt6.8.2.md | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md b/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md index ad65c8191a..244553a620 100644 --- a/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md +++ b/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md @@ -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 +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 ``` @@ -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```
From 1dc5dd7021ca09f1e6d5fbbcd8f0be2dec3e2bbe Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 15:07:17 +0000 Subject: [PATCH 16/25] add Firmware to packages --- SerialPrograms/Scripts/Linux/PKGBUILD | 2 ++ SerialPrograms/cmake/CPack.cmake | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/SerialPrograms/Scripts/Linux/PKGBUILD b/SerialPrograms/Scripts/Linux/PKGBUILD index 3c80ac0fbf..c1d11569b5 100644 --- a/SerialPrograms/Scripts/Linux/PKGBUILD +++ b/SerialPrograms/Scripts/Linux/PKGBUILD @@ -43,6 +43,8 @@ package() { 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 \ diff --git a/SerialPrograms/cmake/CPack.cmake b/SerialPrograms/cmake/CPack.cmake index 26984ea4fe..daa6063809 100644 --- a/SerialPrograms/cmake/CPack.cmake +++ b/SerialPrograms/cmake/CPack.cmake @@ -11,6 +11,12 @@ install( DESTINATION share/SerialPrograms/Resources ) +# Firmware +install( + DIRECTORY ${CMAKE_BINARY_DIR}/Firmware/ + DESTINATION share/SerialPrograms/Firmware +) + # App icon install( FILES ${CMAKE_SOURCE_DIR}/../IconResource/SerialPrograms.png From aa6833bf0bde77a3f78352687bac6fbfacaaca91 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Sun, 15 Mar 2026 18:04:07 +0000 Subject: [PATCH 17/25] Revert "ignore empty frames from capture card" This reverts commit 562a9f4d26e8fc530f5c3b897d64912d908f7e6a. --- .../VideoPipeline/Backends/CameraWidgetQt6.5.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp b/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp index 84b15855ff..28229c3293 100644 --- a/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp +++ b/SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.cpp @@ -190,9 +190,6 @@ void CameraVideoSource::set_video_output(QGraphicsVideoItem& item){ &m_camera->camera(), [&](const QVideoFrame& frame){ // This runs on the QCamera's thread. So it is off the critical path. - if (frame.size().isEmpty() || frame.bytesPerLine(0) == 0) - return; // Ignore empty frames - WallClock now = current_time(); if (!m_last_frame.push_frame(frame, now)){ return; From 3f812f2be89a563c4a34fe3d6b82c90aad52057c Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Thu, 19 Mar 2026 17:56:03 +0000 Subject: [PATCH 18/25] suppress sleep on linux using dbus inhibitor lock --- SerialPrograms/CMakeLists.txt | 5 + .../Environment/SystemSleep.cpp | 2 + .../Environment/SystemSleep_Linux.tpp | 165 ++++++++++++++++++ SerialPrograms/cmake/SourceFiles.cmake | 1 + 4 files changed, 173 insertions(+) create mode 100644 SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index fa52cb5b28..58b8be4f1c 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -460,6 +460,11 @@ else() # macOS and Linux message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") endif() endif () + + # Systemd DBus Library + find_package(sdbus-c++ REQUIRED) + target_link_libraries(SerialProgramsLib PRIVATE sdbus-c++) + target_link_libraries(SerialPrograms PRIVATE sdbus-c++) endif() # end Linux # Find OpenCV diff --git a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp index b679e936c3..3988946c81 100644 --- a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp +++ b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp @@ -11,6 +11,8 @@ #include "SystemSleep_Windows.tpp" #elif __APPLE__ #include "SystemSleep_Apple.tpp" +#elif __linux__ +#include "SystemSleep_Linux.tpp" #else namespace PokemonAutomation{ SystemSleepController& SystemSleepController::instance(){ diff --git a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp new file mode 100644 index 0000000000..a6940957ed --- /dev/null +++ b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp @@ -0,0 +1,165 @@ +/* OS Sleep (Linux) + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include +#include "Common/Cpp/Concurrency/ConditionVariable.h" +#include "Common/Cpp/Concurrency/AsyncTask.h" +#include "Common/Cpp/Concurrency/ThreadPool.h" +#include "CommonFramework/Logging/Logger.h" +#include "CommonFramework/Tools/GlobalThreadPools.h" +#include "SystemSleep.h" + +namespace PokemonAutomation{ + + +class LinuxSleepController final : public SystemSleepController{ +public: + LinuxSleepController() + : m_screen_on_requests(0) + , m_no_sleep_requests(0) + , m_stopping(false) + , m_thread(GlobalThreadPools::unlimited_normal().dispatch_now_blocking( + [this]{ thread_loop(); }) + ) + {} + virtual ~LinuxSleepController(){ + stop(); + } + virtual void stop() noexcept override{ + if (!m_thread){ + return; + } + { + std::lock_guard lg(m_lock); + m_stopping = true; + } + m_cv.notify_all(); + m_thread.wait_and_ignore_exceptions(); + m_inhibit_fd.reset(); + if (m_state.load(std::memory_order_relaxed) != SleepSuppress::NONE){ + try{ + global_logger_tagged().log( + "Destroying LinuxSleepController with active requests...", + COLOR_RED + ); + }catch (...){} + } + } + + virtual void push_screen_on() override{ + std::lock_guard lg(m_lock); + m_screen_on_requests++; + m_cv.notify_all(); + } + virtual void pop_screen_on() override{ + std::lock_guard lg(m_lock); + m_screen_on_requests--; + m_cv.notify_all(); + } + virtual void push_no_sleep() override{ + std::lock_guard lg(m_lock); + m_no_sleep_requests++; + m_cv.notify_all(); + } + virtual void pop_no_sleep() override{ + std::lock_guard lg(m_lock); + m_no_sleep_requests--; + m_cv.notify_all(); + } + +private: + void thread_loop() + { + auto connection = sdbus::createSystemBusConnection(); + auto proxy = sdbus::createProxy( + *connection, + sdbus::BusName{"org.freedesktop.login1"}, + sdbus::ObjectPath{"/org/freedesktop/login1"} + ); + + while (true) + { + std::unique_lock lg(m_lock); + if (m_stopping) + { + return; + } + + SleepSuppress before_state = m_state.load(std::memory_order_relaxed); + SleepSuppress after_state = SleepSuppress::NONE; + + bool need_inhibit = false; + std::string what; + if (m_no_sleep_requests > 0) + { + need_inhibit = true; + what = "sleep"; + after_state = SleepSuppress::NO_SLEEP; + } + else if (m_screen_on_requests > 0) + { + need_inhibit = true; + what = "idle"; + after_state = SleepSuppress::SCREEN_ON; + } + if (need_inhibit && !m_inhibit_fd) + { + try + { + sdbus::UnixFd fd; + proxy->callMethod("Inhibit") + .onInterface("org.freedesktop.login1.Manager") + .withArguments(what, "PokemonAutomation", "Keeping system awake", "block") + .storeResultsTo(fd); + m_inhibit_fd = std::make_unique(std::move(fd)); + + global_logger_tagged().log("Acquired sleep inhibitor", COLOR_BLUE); + } + + catch (const sdbus::Error &e) + { + global_logger_tagged().log(std::string("DBus error: ") + e.what(), COLOR_RED); + } + } + else if (!need_inhibit && m_inhibit_fd) + { + m_inhibit_fd.reset(); + global_logger_tagged().log("Released sleep inhibitor", COLOR_BLUE); + } + + if (before_state != after_state) + { + m_state.store(after_state, std::memory_order_release); + notify_listeners(after_state); + } + + m_cv.wait(lg); + } + } + +private: + size_t m_screen_on_requests = 0; + size_t m_no_sleep_requests = 0; + + bool m_stopping; + ConditionVariable m_cv; + AsyncTask m_thread; + + std::unique_ptr m_inhibit_fd; +}; + + +SystemSleepController& SystemSleepController::instance(){ + static LinuxSleepController controller; + return controller; +} + + + + + + +} diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index a68eb0d930..f84ceacca7 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -361,6 +361,7 @@ file(GLOB LIBRARY_SOURCES Source/CommonFramework/Environment/SystemSleep.cpp Source/CommonFramework/Environment/SystemSleep.h Source/CommonFramework/Environment/SystemSleep_Apple.tpp + Source/CommonFramework/Environment/SystemSleep_Linux.tpp Source/CommonFramework/Environment/SystemSleep_Windows.tpp Source/CommonFramework/ErrorReports/ErrorReports.cpp Source/CommonFramework/ErrorReports/ErrorReports.h From b51b950e2da4a4fff198da06292118e878608aea Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Thu, 19 Mar 2026 21:52:16 +0000 Subject: [PATCH 19/25] Revert "suppress sleep on linux using dbus inhibitor lock" This reverts commit 3f812f2be89a563c4a34fe3d6b82c90aad52057c. --- SerialPrograms/CMakeLists.txt | 5 - .../Environment/SystemSleep.cpp | 2 - .../Environment/SystemSleep_Linux.tpp | 165 ------------------ SerialPrograms/cmake/SourceFiles.cmake | 1 - 4 files changed, 173 deletions(-) delete mode 100644 SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 58b8be4f1c..fa52cb5b28 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -460,11 +460,6 @@ else() # macOS and Linux message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") endif() endif () - - # Systemd DBus Library - find_package(sdbus-c++ REQUIRED) - target_link_libraries(SerialProgramsLib PRIVATE sdbus-c++) - target_link_libraries(SerialPrograms PRIVATE sdbus-c++) endif() # end Linux # Find OpenCV diff --git a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp index 3988946c81..b679e936c3 100644 --- a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp +++ b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep.cpp @@ -11,8 +11,6 @@ #include "SystemSleep_Windows.tpp" #elif __APPLE__ #include "SystemSleep_Apple.tpp" -#elif __linux__ -#include "SystemSleep_Linux.tpp" #else namespace PokemonAutomation{ SystemSleepController& SystemSleepController::instance(){ diff --git a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp b/SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp deleted file mode 100644 index a6940957ed..0000000000 --- a/SerialPrograms/Source/CommonFramework/Environment/SystemSleep_Linux.tpp +++ /dev/null @@ -1,165 +0,0 @@ -/* OS Sleep (Linux) - * - * From: https://github.com/PokemonAutomation/Arduino-Source - * - */ - -#include -#include "Common/Cpp/Concurrency/ConditionVariable.h" -#include "Common/Cpp/Concurrency/AsyncTask.h" -#include "Common/Cpp/Concurrency/ThreadPool.h" -#include "CommonFramework/Logging/Logger.h" -#include "CommonFramework/Tools/GlobalThreadPools.h" -#include "SystemSleep.h" - -namespace PokemonAutomation{ - - -class LinuxSleepController final : public SystemSleepController{ -public: - LinuxSleepController() - : m_screen_on_requests(0) - , m_no_sleep_requests(0) - , m_stopping(false) - , m_thread(GlobalThreadPools::unlimited_normal().dispatch_now_blocking( - [this]{ thread_loop(); }) - ) - {} - virtual ~LinuxSleepController(){ - stop(); - } - virtual void stop() noexcept override{ - if (!m_thread){ - return; - } - { - std::lock_guard lg(m_lock); - m_stopping = true; - } - m_cv.notify_all(); - m_thread.wait_and_ignore_exceptions(); - m_inhibit_fd.reset(); - if (m_state.load(std::memory_order_relaxed) != SleepSuppress::NONE){ - try{ - global_logger_tagged().log( - "Destroying LinuxSleepController with active requests...", - COLOR_RED - ); - }catch (...){} - } - } - - virtual void push_screen_on() override{ - std::lock_guard lg(m_lock); - m_screen_on_requests++; - m_cv.notify_all(); - } - virtual void pop_screen_on() override{ - std::lock_guard lg(m_lock); - m_screen_on_requests--; - m_cv.notify_all(); - } - virtual void push_no_sleep() override{ - std::lock_guard lg(m_lock); - m_no_sleep_requests++; - m_cv.notify_all(); - } - virtual void pop_no_sleep() override{ - std::lock_guard lg(m_lock); - m_no_sleep_requests--; - m_cv.notify_all(); - } - -private: - void thread_loop() - { - auto connection = sdbus::createSystemBusConnection(); - auto proxy = sdbus::createProxy( - *connection, - sdbus::BusName{"org.freedesktop.login1"}, - sdbus::ObjectPath{"/org/freedesktop/login1"} - ); - - while (true) - { - std::unique_lock lg(m_lock); - if (m_stopping) - { - return; - } - - SleepSuppress before_state = m_state.load(std::memory_order_relaxed); - SleepSuppress after_state = SleepSuppress::NONE; - - bool need_inhibit = false; - std::string what; - if (m_no_sleep_requests > 0) - { - need_inhibit = true; - what = "sleep"; - after_state = SleepSuppress::NO_SLEEP; - } - else if (m_screen_on_requests > 0) - { - need_inhibit = true; - what = "idle"; - after_state = SleepSuppress::SCREEN_ON; - } - if (need_inhibit && !m_inhibit_fd) - { - try - { - sdbus::UnixFd fd; - proxy->callMethod("Inhibit") - .onInterface("org.freedesktop.login1.Manager") - .withArguments(what, "PokemonAutomation", "Keeping system awake", "block") - .storeResultsTo(fd); - m_inhibit_fd = std::make_unique(std::move(fd)); - - global_logger_tagged().log("Acquired sleep inhibitor", COLOR_BLUE); - } - - catch (const sdbus::Error &e) - { - global_logger_tagged().log(std::string("DBus error: ") + e.what(), COLOR_RED); - } - } - else if (!need_inhibit && m_inhibit_fd) - { - m_inhibit_fd.reset(); - global_logger_tagged().log("Released sleep inhibitor", COLOR_BLUE); - } - - if (before_state != after_state) - { - m_state.store(after_state, std::memory_order_release); - notify_listeners(after_state); - } - - m_cv.wait(lg); - } - } - -private: - size_t m_screen_on_requests = 0; - size_t m_no_sleep_requests = 0; - - bool m_stopping; - ConditionVariable m_cv; - AsyncTask m_thread; - - std::unique_ptr m_inhibit_fd; -}; - - -SystemSleepController& SystemSleepController::instance(){ - static LinuxSleepController controller; - return controller; -} - - - - - - -} diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 5890df225c..846f06ef95 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -364,7 +364,6 @@ file(GLOB LIBRARY_SOURCES Source/CommonFramework/Environment/SystemSleep.cpp Source/CommonFramework/Environment/SystemSleep.h Source/CommonFramework/Environment/SystemSleep_Apple.tpp - Source/CommonFramework/Environment/SystemSleep_Linux.tpp Source/CommonFramework/Environment/SystemSleep_Windows.tpp Source/CommonFramework/ErrorReports/ErrorReports.cpp Source/CommonFramework/ErrorReports/ErrorReports.h From dcc01b1dd2e2a4c75f07347e014ed2e9920a4a5f Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 20 Mar 2026 10:51:07 +0000 Subject: [PATCH 20/25] Revert "onnx gpu hw accel for linux" This reverts commit 91b9570e54cab7c108a3e479887bc24a41703d7b. --- .../ML/Models/ML_ONNXRuntimeHelpers.cpp | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp index ce1447b6b2..822345f76c 100644 --- a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp +++ b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp @@ -86,28 +86,6 @@ if (use_gpu){ std::cout << "DirectML execution provider not available, falling back to CPU: " << e.what() << std::endl; } } -#elif defined(__linux__) - // Try CUDA first for NVIDIA GPUs (best performance) - // See: https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html - try { - OrtCUDAProviderOptions cuda_options{}; - cuda_options.device_id = 0; - so.AppendExecutionProvider_CUDA(cuda_options); - std::cout << "Using CUDA execution provider for GPU acceleration" << std::endl; - } catch (const Ort::Exception& e) { - std::cout << "CUDA execution provider not available, trying ROCm: " << e.what() << std::endl; - - // Try ROCm next for AMD GPUs - // See: https://onnxruntime.ai/docs/execution-providers/ROCm-ExecutionProvider.html - try { - OrtROCMProviderOptions rocm_options{}; - rocm_options.device_id = 0; - so.AppendExecutionProvider_ROCM(rocm_options); - std::cout << "Using ROCm execution provider for GPU acceleration" << std::endl; - } catch (const Ort::Exception& e) { - std::cout << "ROCm execution provider not available, falling back to CPU: " << e.what() << std::endl; - } - } #endif } From 0c030a5988e38c81927702859db7784b36188b2d Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 20 Mar 2026 10:51:07 +0000 Subject: [PATCH 21/25] Revert "fix compile using onnxruntime 1.24.x" This reverts commit 18966ad5b0ee08448872e783d0f0f2b6856c4873. --- SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp index 822345f76c..2171a6ea82 100644 --- a/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp +++ b/SerialPrograms/Source/ML/Models/ML_ONNXRuntimeHelpers.cpp @@ -203,7 +203,10 @@ void print_model_input_output_info(const Ort::Session& session){ } Ort::Env create_ORT_env(){ - // Bit redundant now, but still might be useful to add logging or other init? + if (Ort::Global::api_ == nullptr){ + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Onnx API returned a null pointer."); + } + return Ort::Env(); } From 0daf090a3b2194e211d7a0acb4a0e68160e9d221 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 20 Mar 2026 10:51:07 +0000 Subject: [PATCH 22/25] Revert "detect system onnxruntime with pkg-config" This reverts commit 0dd6834fa381e3c5e7543c4e3c9b9e8502e1d6f9. --- SerialPrograms/CMakeLists.txt | 137 +++++++++++++++------------------- 1 file changed, 62 insertions(+), 75 deletions(-) diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index fa52cb5b28..d0429851e8 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -379,87 +379,74 @@ else() # macOS and Linux # extract it, and then link it up # Set the ONNXRUNTIME version and arch, allows for quick updates - pkg_check_modules(ONNXRUNTIME QUIET libonnxruntime) - - if(ONNXRUNTIME_FOUND) - message(STATUS "Found system installed ONNX Runtime") - - message(STATUS "Found ONNX Include Dirs: ${ONNXRUNTIME_INCLUDE_DIRS}") - message(STATUS "Found ONNX Library: ${ONNXRUNTIME_LIBRARIES}") - - target_include_directories(SerialProgramsLib PUBLIC ${ONNXRUNTIME_INCLUDE_DIRS}) - target_link_libraries(SerialProgramsLib PUBLIC ${ONNXRUNTIME_LIBRARIES}) - - else() - set(ONNXRUNTIME_VERSION "1.23.0") - set(ONNXRUNTIME_ARCH "x64") - set(ONNXRUNTIME_DIR_NAME "onnxruntime-linux-${ONNXRUNTIME_ARCH}-${ONNXRUNTIME_VERSION}") - set(ONNXRUNTIME_TGZ_NAME "${ONNXRUNTIME_DIR_NAME}.tgz") - # build up the URL based on the version and name - set(ONNXRUNTIME_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/${ONNXRUNTIME_TGZ_NAME}") - - # Cache variable is editable by users *and* is properly stored - set(ONNX_ROOT_PATH "" CACHE PATH "Path to the root of a pre-installed ONNX Runtime (e.g., /path/to/onnxruntime-linux-x64-1.23.0)") - - # Download the onnxruntime if it doesn't exist or if the path is bad - if(NOT ONNX_ROOT_PATH OR NOT EXISTS "${ONNX_ROOT_PATH}/include/onnxruntime_cxx_api.h") - set(EXTRACTED_ONNX_PATH "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_DIR_NAME}") - - if(NOT IS_DIRECTORY ${EXTRACTED_ONNX_PATH}) - message(STATUS "ONNX_ROOT_PATH not found. Downloading ONNX Runtime v${ONNXRUNTIME_VERSION}...") - - # logic for downloading... - set(DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_TGZ_NAME}") - file(DOWNLOAD - ${ONNXRUNTIME_URL} - ${DOWNLOAD_LOCATION} - SHOW_PROGRESS - STATUS download_status - ) - list(GET download_status 0 error_code) - if(NOT error_code EQUAL 0) - list(GET download_status 1 error_message) - message(FATAL_ERROR "Failed to download ONNX Runtime: ${error_message}") - endif() - - # logic for extracting the tarball to our working directory - message(STATUS "Extracting ONNX Runtime...") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf "${DOWNLOAD_LOCATION}" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) + set(ONNXRUNTIME_VERSION "1.23.0") + set(ONNXRUNTIME_ARCH "x64") + set(ONNXRUNTIME_DIR_NAME "onnxruntime-linux-${ONNXRUNTIME_ARCH}-${ONNXRUNTIME_VERSION}") + set(ONNXRUNTIME_TGZ_NAME "${ONNXRUNTIME_DIR_NAME}.tgz") + # build up the URL based on the version and name + set(ONNXRUNTIME_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/${ONNXRUNTIME_TGZ_NAME}") + + # Cache variable is editable by users *and* is properly stored + set(ONNX_ROOT_PATH "" CACHE PATH "Path to the root of a pre-installed ONNX Runtime (e.g., /path/to/onnxruntime-linux-x64-1.23.0)") + + # Download the onnxruntime if it doesn't exist or if the path is bad + if(NOT ONNX_ROOT_PATH OR NOT EXISTS "${ONNX_ROOT_PATH}/include/onnxruntime_cxx_api.h") + set(EXTRACTED_ONNX_PATH "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_DIR_NAME}") + + if(NOT IS_DIRECTORY ${EXTRACTED_ONNX_PATH}) + message(STATUS "ONNX_ROOT_PATH not found. Downloading ONNX Runtime v${ONNXRUNTIME_VERSION}...") + + # logic for downloading... + set(DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/${ONNXRUNTIME_TGZ_NAME}") + file(DOWNLOAD + ${ONNXRUNTIME_URL} + ${DOWNLOAD_LOCATION} + SHOW_PROGRESS + STATUS download_status + ) + list(GET download_status 0 error_code) + if(NOT error_code EQUAL 0) + list(GET download_status 1 error_message) + message(FATAL_ERROR "Failed to download ONNX Runtime: ${error_message}") endif() - # Update the ONNX_ROOT_PATH to point to our downloaded version, force ensures we update it - set(ONNX_ROOT_PATH "${EXTRACTED_ONNX_PATH}" CACHE PATH "Path to the downloaded ONNX Runtime" FORCE) - message(STATUS "Using downloaded ONNX Runtime at: ${ONNX_ROOT_PATH}") - else() - message(STATUS "Using user-provided ONNX Runtime at: ${ONNX_ROOT_PATH}") + # logic for extracting the tarball to our working directory + message(STATUS "Extracting ONNX Runtime...") + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xzf "${DOWNLOAD_LOCATION}" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) endif() - # configure and find headers from the onnxruntime - find_path(ONNX_INCLUDE_DIRS - NAMES onnxruntime_cxx_api.h - HINTS "${ONNX_ROOT_PATH}/include" - REQUIRED - ) + # Update the ONNX_ROOT_PATH to point to our downloaded version, force ensures we update it + set(ONNX_ROOT_PATH "${EXTRACTED_ONNX_PATH}" CACHE PATH "Path to the downloaded ONNX Runtime" FORCE) + message(STATUS "Using downloaded ONNX Runtime at: ${ONNX_ROOT_PATH}") + else() + message(STATUS "Using user-provided ONNX Runtime at: ${ONNX_ROOT_PATH}") + endif() - find_library(ONNX_RUNTIME_LIB - NAMES onnxruntime - HINTS "${ONNX_ROOT_PATH}/lib" - REQUIRED - ) + # configure and find headers from the onnxruntime + find_path(ONNX_INCLUDE_DIRS + NAMES onnxruntime_cxx_api.h + HINTS "${ONNX_ROOT_PATH}/include" + REQUIRED + ) - if(ONNX_INCLUDE_DIRS AND ONNX_RUNTIME_LIB) - # only link if it was found, otherwise we error out - message(STATUS "Found ONNX Include Dirs: ${ONNX_INCLUDE_DIRS}") - message(STATUS "Found ONNX Library: ${ONNX_RUNTIME_LIB}") - target_include_directories(SerialProgramsLib PUBLIC "${ONNX_INCLUDE_DIRS}") - target_link_libraries(SerialProgramsLib PUBLIC "${ONNX_RUNTIME_LIB}") - else() - message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") - endif() - endif () + find_library(ONNX_RUNTIME_LIB + NAMES onnxruntime + HINTS "${ONNX_ROOT_PATH}/lib" + REQUIRED + ) + + if(ONNX_INCLUDE_DIRS AND ONNX_RUNTIME_LIB) + # only link if it was found, otherwise we error out + message(STATUS "Found ONNX Include Dirs: ${ONNX_INCLUDE_DIRS}") + message(STATUS "Found ONNX Library: ${ONNX_RUNTIME_LIB}") + target_include_directories(SerialProgramsLib PUBLIC "${ONNX_INCLUDE_DIRS}") + target_link_libraries(SerialProgramsLib PUBLIC "${ONNX_RUNTIME_LIB}") + else() + message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") + endif() endif() # end Linux # Find OpenCV From ac14f380dc0cec686bd26e2793fc353a7da47802 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 20 Mar 2026 11:11:36 +0000 Subject: [PATCH 23/25] Revert "default auto-reset to 0 on linux builds to prevent black frames on reset" This reverts commit 04a61e076277a461c493bb3679e7fac2013b233c. --- .../CommonFramework/VideoPipeline/VideoPipelineOptions.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h index c1f7dc20bb..e7a4d19133 100644 --- a/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h +++ b/SerialPrograms/Source/CommonFramework/VideoPipeline/VideoPipelineOptions.h @@ -34,13 +34,9 @@ class VideoPipelineOptions : public GroupOption{ , AUTO_RESET_SECONDS( "Video Auto-Reset:
" "Attempt to reset the video if this many seconds has elapsed since the last video frame (in order to fix issues with RDP disconnection, etc).
" - "This option is not supported by all video frameworks. Set to a value of 0 to disable Auto-Reset.", + "This option is not supported by all video frameworks.", LockMode::UNLOCK_WHILE_RUNNING, -#if defined(__linux__) - 0 // Default to disabled on linux, auto-resets briefly output black frames -#else 5 -#endif ) { PA_ADD_OPTION(VIDEO_BACKEND); From 1bf50f3650f759511bb8ccaa2f5acc02fe909149 Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 20 Mar 2026 11:11:36 +0000 Subject: [PATCH 24/25] Revert "Default to gstreamer backend to prevent capture card flickering" This reverts commit 8379cf2dcc33b84bcf4448715cfe0eef6735662f. --- SerialPrograms/Source/CommonFramework/Main.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/SerialPrograms/Source/CommonFramework/Main.cpp b/SerialPrograms/Source/CommonFramework/Main.cpp index ad1c5d6e63..d231c2080d 100644 --- a/SerialPrograms/Source/CommonFramework/Main.cpp +++ b/SerialPrograms/Source/CommonFramework/Main.cpp @@ -209,12 +209,6 @@ int main(int argc, char *argv[]){ set_program_path(argv[0]); #endif -#if defined(__linux__) - // Qt multimedia, default to gstreamer to prevent flickering - if (qEnvironmentVariableIsEmpty("QT_MEDIA_BACKEND")) - qputenv("QT_MEDIA_BACKEND", "gstreamer"); -#endif - // So far, this is only needed on Mac where static initialization is fucked up. PokemonAutomation::register_all_statics(); From 4cd65cbc499812966442c8d27a88bfea261cf90f Mon Sep 17 00:00:00 2001 From: ConnorC432 Date: Fri, 20 Mar 2026 14:21:43 +0000 Subject: [PATCH 25/25] libsystemd-dev build requirement --- SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md b/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md index 244553a620..198091f76c 100644 --- a/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md +++ b/SerialPrograms/BuildInstructions/Build-Ubuntu-Qt6.8.2.md @@ -7,7 +7,7 @@ Note that our Linux setup might not work. The video display can flicker to the p Install the following build requirements, these steps will use ubuntu packages but the steps will be the same on your distro: ``` -git cmake ninja-build gcc g++ qt6-base-dev qt6-multimedia-dev qt6-serialport-dev libopencv-dev libonnx-dev libasound2-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