Библиотеки платформы Steam для Linux, вызывающие неправильное поведение приложения Qt

В настоящее время у меня возникают трудности с очень простым приложением запуска, которое предназначено для отображения веб-страницы и имеет несколько кнопок для запуска игры. Когда вы щелкаете ссылку внутри панели запуска, она просто запускает веб-браузер по умолчанию со ссылкой, а не принимает и обрабатывает запросы навигации.

Однако при запуске через Steam ссылки не открываются в новом веб-браузере. Точное поведение зависит от среды, у меня были отчеты о зависании копий gvfs-open и xdg-open, хотя в моей среде он просто указывает мышью, что firefox открывается на долю секунды и ничего не делает (включая процессы, запущенные вообще в соответствии с strace , возможно, имеет какое-то отношение к системе передачи сообщений KDE, я не знаю). К сожалению, есть также сообщения о том, что он работает нормально. И поэтому у меня возникла проблема с определением точной проблемы в результате.

Мне удалось сузить круг проблем до изменения Steam LD_LIBARRY_PATH исполняемого файла для использования платформ Steam Linux. Я связал все библиотеки, необходимые лаунчеру, с лаунчером.

Вот минимальное воспроизводимое руководство:

main.cpp

#include <QApplication>
#include <QWebFrame>
#include <QDesktopServices>
#include <QNetworkRequest>
#include <QMessageBox>
#include <QWebView>

class WebPage : public QWebPage {
public:
  bool acceptNavigationRequest(QWebFrame*, const QNetworkRequest &request, NavigationType) {
    QDesktopServices::openUrl(request.url());
    return false;
  }
};

class WebView : public QWebView {
public:
  QWebView* createWindow(QWebPage::WebWindowType) {
    WebView* res = new WebView;
    WebPage* page = new WebPage;
    res->setPage(page);
    return res;
  }
};

int main(int argc, char *argv[]) {
  QApplication a(argc, argv);

  WebView v;
  v.load(QUrl("http://example.com/"));
  v.show();

  return a.exec();
}

лаунчер.про

QT += core gui network webkitwidgets widgets

TARGET = launcher
TEMPLATE = app

SOURCES = main.cpp

Вам также потребуется скопировать и связать следующие библиотеки (стандартное развертывание Qt):

libQt5Widgets.so libQt5Gui.so libQt5Core.so libQt5Network.so libQt5WebKitWidgets.so libQt5WebKit.so libQt5MultimediaWidgets.so libQt5OpenGL.so libQt5PrintSupport.so libQt5Multimedia.so libQt5Sensors.so libQt5Quick.so libQt5Qml.so libQt5Sql.so libQt5Positioning.so libQt5DBus.so libicui18n. так libicuuc.so libicudata.so libssl.so libcrypto.so libstdc++.so libgcc_s.so

И в подкаталоге под названием платформы:

libqxcb.so

И, наконец, скрипт, чтобы связать это вместе:

launch_launcher.sh

#!/bin/sh -e

cd "$(dirname "$0")"

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./launcher

Наконец, установите Steam и установите его LD_LIBRARY_PATH как свой собственный, экспортируйте его и запустите launch_launcher.sh (эти точные пути зависят от вашей установки Steam).

По сути, если убрать $LD_LIBRARY_PATH из скрипта launch_launcher, чтобы в строке читалось только LD_LIBRARY_PATH=. ./launcher, то ссылки работают. Однако при включенном $LD_LIBRARY_PATH ссылки не работают. Нам нужно, чтобы $LD_LIBRARY_PATH работало, чтобы использовать библиотеки платформы Steam Linux (что позволяет игре работать).

Каков наилучший способ устранения этой проблемы? Как я могу найти ответственную библиотеку и исключить ее или иным образом обойти эту проблему?


person OmnipotentEntity    schedule 11.03.2015    source источник
comment
в launch_launcher.sh можете ли вы вывести все значение LD_LIBRARY_PATH и попытаться явно установить его при будущих запусках? то есть echo $LD_LIBRARY_PATH # sample-output: .:A:B:C:D:E модифицированный скрипт запуска: LD_LIBRARY_PATH=.:A:B:C ./launcher   -  person Fox    schedule 20.03.2015
comment
а что касается решения проблемы после изоляции, то мне нужно глубже вникнуть в это   -  person Fox    schedule 20.03.2015
comment
@Fox, LD_LIBRARY_PATH - это то, что Steam устанавливает. Обычно это довольно долго и отличается от системы к системе и от пользователя к пользователю (поскольку Steam устанавливает себя под ~/.steam/). Простое изменение LD_LIBRARY_PATH не поможет, потому что мне нужен полный Steam, предоставленный LD_LIBRARY_PATH для игры, но Steam предоставил LD_LIBRARY_PATH также, кажется, мешает QDesktopServices. Так что дело не в том, чтобы найти правильный LD_LIBRARY_PATH, потому что его, кажется, не существует.   -  person OmnipotentEntity    schedule 20.03.2015
comment
Я добавлю ответ, чтобы объяснить это лучше.   -  person Fox    schedule 22.03.2015


Ответы (2)


Итак, я обращаюсь к этой части (как объяснялось в предыдущем комментарии к вопросу)

Каков наилучший способ устранения этой проблемы? Как я могу найти ответственную библиотеку

а не это

и исключить его или иным образом обойти эту проблему?

Причина в том, что если вы используете конфигурацию Linux с поддержкой Steam, LD_LIBRARY_PATH должны быть параметром последней инстанции для любого приложения (особенно коммерческого). Если это мешает другим библиотекам/приложениям, это их ошибка.

Таким образом, ваш подход к выделению репродукции в принципе верен. Логическое расширение (как в комментарии) продолжить:

LD_LIBRARY_PATH={myentry}:A:B:C
./launcher

вместо

LD_LIBRARY_PATH={myentry}:${LD_LIBRARY_PATH}
./launcher

это позволяет вам выбирать среди «A:B:C» (который является текущим LD_LIBRARY_PATH, включая записи библиотеки Steam) и определять, если оставить какие-либо записи, чтобы ваше приложение снова начало работать.

Что касается его решения, это зависит от нескольких переменных в вашей системе (ваш дистрибутив, другие установленные библиотеки в LD_LIBRARY_PATH, ваша версия Qt и версия Qt KDE). Вы можете попробовать:

  1. поиск обходных путей - это может быть так же просто, как замена файла библиотеки, или патч Qt, или одна функция, которую вы вызываете из своей основной функции (аналогично ответу @fbucek).
  2. регистрация отчетов об ошибках с помощью Steam и Qt — так что этот обходной путь не специфичен для вашей системы и не будет сломан снова со следующим обновлением Steam.

изменить: вы заметили, что это QDesktopServices, который затронут - я, скорее всего, предположил бы, что версии Qt различаются между двумя версиями KDE, вашей и Steam.

person Fox    schedule 22.03.2015
comment
Извините, я неправильно понял смысл вашего поста. Вы совершенно правы в том, что это правильный способ решения этой проблемы. Прошу прощения за настойчивость. Я попробую это в следующий раз, когда буду работать над этой проблемой, и буду держать вас в курсе. - person OmnipotentEntity; 22.03.2015
comment
не беспокойтесь :) - исходный комментарий был немного краток. Надеюсь, вы получите решение. - person Fox; 23.03.2015

Я предполагаю, что у вас проблема более сложная. Просто подумал, что можно попробовать.

1) Возможно, вашему приложению не нужно использовать LD_LIBRARY_PATH

Чтобы не связываться с LD_LIBRARY_PATH в вашем приложении, вы можете указать путь поиска библиотеки в свою программу. (решение для линукса)

App structue
/app/bin
/app/lib    // where all my libraries are including Qt libraries

.про файл

QMAKE_RPATHDIR = \$\$ORIGIN/../lib
QMAKE_LFLAGS_RELEASE += \'-Wl,-rpath,$${QMAKE_RPATHDIR}\'
QMAKE_RPATHDIR =

(не помню, почему это выглядит так глупо в моем старом приложении, но оно работает, и на данный момент я не на Linux, чтобы упростить его)

2) Установите LD_LIBRARY_PATH только для процессов внутри вашего приложения (чтобы не усложнять LD_LIBARY_PATH. путь к вашему приложению, steam и т. д.)

Я не знаю, в каком контексте выполняется новый браузер, но если это ваше приложение, вы можете использовать этот подход. Это гарантирует, что только процессы в вашем приложении будут иметь этот LD_LIBRARY_PATH.

Вы можете установить LD_LIBRARY_PATH в своем приложении, используя

setenv("LD_LIBRARY_PATH", yourPath.toLatin1().data(), 1)
// You can test it using
QProcessEnvironment::systemEnvironment().value("LD_LIBRARY_PATH");

Я предполагаю, что вы не используете QProcess, поэтому о настройке среды для самого процесса не может быть и речи.

person fbucek    schedule 16.03.2015