on xenial help sign in
Drop unity-mir hard-link and dynamically load according to the environment used, to prevent the wrong platform-api symbols ending up in the global linkage namespace
commitdc3b578dd0f7c85c4ca97e8d6ceec6a46868f3e3 authorRicardo Mendoza <ricardo.mendoza@canonical.com> dateMon 9 Sep 2013, 19:02 (13 years ago) parentcddf513
2 files changed+46−9
CMakeLists.txt+1−1 main.cpp+45−8
CMakeLists.txt+1−1
@@ -121,7 +121,7 @@ target_link_libraries(${SHELL_APP}
121121 ${Qt5Qml_LIBRARIES}
122122 ${Qt5Quick_LIBRARIES}
123123 ${XCB_LDFLAGS}
124− ${UNITY-MIR_LDFLAGS}
124+ ${CMAKE_DL_LIBS}
125125 )
126126
127127# install binaries
main.cpp+45−8
@@ -25,17 +25,17 @@
2525#include <QtQml/QQmlContext>
2626#include <qpa/qplatformnativeinterface.h>
2727#include <QLibrary>
28+#include <QDebug>
2829#include <libintl.h>
29−
30−// Unity-Mir
31−#include <unity-mir/qmirserver.h>
32−#include <unity-mir/qmirserverapplication.h>
30+#include <dlfcn.h>
3331
3432// local
3533#include "paths.h"
3634#include "MouseTouchAdaptor.h"
3735#include "ApplicationArguments.h"
3836
37+#include <unity-mir/qmirserver.h>
38+
3939namespace {
4040
4141void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
@@ -76,7 +76,7 @@ void resolveIconTheme() {
7676}
7777} // namespace {
7878
79−int startShell(int argc, const char** argv, ShellServerConfiguration* server)
79+int startShell(int argc, const char** argv, void* server)
8080{
8181 /* Workaround Qt platform integration plugin not advertising itself
8282 as having the following capabilities:
@@ -91,7 +91,17 @@ int startShell(int argc, const char** argv, ShellServerConfiguration* server)
9191 QGuiApplication::setApplicationName("Unity 8");
9292 QGuiApplication *application;
9393 if (isUbuntuMirServer) {
94− application = new QMirServerApplication(argc, (char**)argv, server);
94+ QLibrary unityMir("/usr/lib/arm-linux-gnueabihf/libunity-mir.so.1.0.0");
95+ unityMir.load();
96+
97+ typedef QGuiApplication* (*createServerApplication_t)(int&, const char **, void*);
98+ createServerApplication_t createQMirServerApplication = (createServerApplication_t) unityMir.resolve("createQMirServerApplication");
99+ if (!createQMirServerApplication) {
100+ qDebug() << "unable to resolve symbol: createQMirServerApplication";
101+ return 4;
102+ }
103+
104+ application = createQMirServerApplication(argc, argv, server);
95105 } else {
96106 application = new QGuiApplication(argc, (char**)argv);
97107 }
@@ -179,8 +189,35 @@ int main(int argc, const char *argv[])
179189 // For ubuntumirserver/ubuntumirclient
180190 if (qgetenv("QT_QPA_PLATFORM").startsWith("ubuntumir")) {
181191 setenv("QT_QPA_PLATFORM", "ubuntumirserver", 1);
182− QMirServer mirServer(argc, argv);
183− return mirServer.runWithClient(startShell);
192+
193+ // if we use unity-mir directly, we link straight to mirserver, which exports
194+ // the same symbols as qtubuntu, so if running on SF, the linker finds the mir
195+ // symbols first and uses them! Crash!
196+ // load the triangle library
197+ QLibrary unityMir("/usr/lib/arm-linux-gnueabihf/libunity-mir.so.1.0.0");
198+ unityMir.load();
199+ if (!unityMir.isLoaded()) {
200+ qDebug() << "Library unity-mir not found/loaded";
201+ return 1;
202+ }
203+
204+ typedef QMirServer* (*createServer_t)(int, const char **);
205+ createServer_t createQMirServer = (createServer_t) unityMir.resolve("createQMirServer");
206+ if (!createQMirServer) {
207+ qDebug() << "unable to resolve symbol: createQMirServer";
208+ return 2;
209+ }
210+
211+ QMirServer* mirServer = createQMirServer(argc, argv);
212+
213+ typedef int (*runWithClient_t)(QMirServer*, std::function<int(int, const char**, void*)>);
214+ runWithClient_t runWithClient = (runWithClient_t) unityMir.resolve("runQMirServerWithClient");
215+ if (!runWithClient) {
216+ qDebug() << "unable to resolve symbol: runWithClient";
217+ return 3;
218+ }
219+
220+ return runWithClient(mirServer, startShell);
184221 } else {
185222 return startShell(argc, argv, nullptr);
186223 }