diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index b57867838..e73cbc0cb 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -25,6 +25,23 @@ typedef F3 = Pointer Function(Pointer, int); typedef F3Dart = Pointer Function(Pointer, Int32); typedef HandleEvent = Future Function(Map evt); +/// The Linux bundle keeps the core library at lib/librustdesk.so next to the +/// executable. Prefer that copy, mirroring flutter/linux/main.cc: the plain +/// name relies on the loader search path, which repackaged installs may not +/// cover. https://github.com/rustdesk/rustdesk/discussions/14407 +DynamicLibrary _openLinuxCoreLib() { + final bundled = + '${File(Platform.resolvedExecutable).parent.path}/lib/librustdesk.so'; + try { + if (File(bundled).existsSync()) { + return DynamicLibrary.open(bundled); + } + } catch (e) { + debugPrint("Failed to load '$bundled': $e"); + } + return DynamicLibrary.open('librustdesk.so'); +} + /// FFI wrapper around the native Rust core. /// Hides the platform differences. class PlatformFFI { @@ -120,7 +137,7 @@ class PlatformFFI { final dylib = isAndroid ? DynamicLibrary.open('librustdesk.so') : isLinux - ? DynamicLibrary.open('librustdesk.so') + ? _openLinuxCoreLib() : isWindows ? DynamicLibrary.open('librustdesk.dll') : diff --git a/flutter/linux/main.cc b/flutter/linux/main.cc index a7c0419c9..a4621767a 100644 --- a/flutter/linux/main.cc +++ b/flutter/linux/main.cc @@ -1,4 +1,8 @@ #include +#include +#include +#include +#include #include "my_application.h" #define RUSTDESK_LIB_PATH "librustdesk.so" @@ -7,8 +11,36 @@ bool gIsConnectionManager = false; void print_help_install_pkg(const char* so); +// The bundle keeps the core library at lib/librustdesk.so next to the +// executable. Resolve that path explicitly instead of relying on the +// runner's RPATH, which repackaged installs may strip. +// https://github.com/rustdesk/rustdesk/discussions/14407 +static void* dlopen_bundled_lib() { + char exe_path[PATH_MAX]; + ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); + if (len <= 0 || len >= (ssize_t)(sizeof(exe_path) - 1)) return nullptr; + exe_path[len] = '\0'; + char* last_slash = strrchr(exe_path, '/'); + if (last_slash == nullptr) return nullptr; + *last_slash = '\0'; + char lib_path[PATH_MAX + sizeof("/lib/" RUSTDESK_LIB_PATH)]; + snprintf(lib_path, sizeof(lib_path), "%s/lib/%s", exe_path, RUSTDESK_LIB_PATH); + if (access(lib_path, F_OK) != 0) return nullptr; + void* librustdesk = dlopen(lib_path, RTLD_LAZY); + if (!librustdesk) { + char* error = dlerror(); + if (error != nullptr) { + fprintf(stderr, "Failed to load \"%s\": %s\n", lib_path, error); + } + } + return librustdesk; +} + bool flutter_rustdesk_core_main() { - void* librustdesk = dlopen(RUSTDESK_LIB_PATH, RTLD_LAZY); + void* librustdesk = dlopen_bundled_lib(); + if (!librustdesk) { + librustdesk = dlopen(RUSTDESK_LIB_PATH, RTLD_LAZY); + } if (!librustdesk) { fprintf(stderr,"Failed to load \"librustdesk.so\"\n"); char* error;