1 /*
2 paths.cpp
3
4 This file is part of GammaRay, the Qt application inspection and
5 manipulation tool.
6
7 Copyright (C) 2013-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
8 Author: Volker Krause <volker.krause@kdab.com>
9
10 Licensees holding valid commercial KDAB GammaRay licenses may use this file in
11 accordance with GammaRay Commercial License Agreement provided with the Software.
12
13 Contact info@kdab.com if any conditions of this licensing are not clear to you.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 2 of the License, or
18 (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 */
28
29 #include <config-gammaray.h>
30 #include "paths.h"
31 #include "selflocator.h"
32
33 #include <QCoreApplication>
34 #include <QDebug>
35 #include <QDir>
36 #include <QFileInfo>
37 #include <QLibraryInfo>
38 #include <QMutex>
39
40 namespace GammaRay {
41
42 struct PathData
43 {
44 QString rootPath;
45 QMutex mutex; // rootPath is set from the probe setting receiver thread
46 };
47
48 Q_GLOBAL_STATIC(PathData, s_pathData)
49
50 namespace Paths {
51
rootPath()52 QString rootPath()
53 {
54 QMutexLocker locker(&s_pathData()->mutex);
55 if (s_pathData()->rootPath.isEmpty()) {
56 QFileInfo fi(SelfLocator::findMe());
57 fi.setFile(fi.absolutePath() + QLatin1String("/" GAMMARAY_INVERSE_LIB_DIR));
58 if (fi.isDir())
59 s_pathData()->rootPath = fi.absoluteFilePath();
60 }
61 Q_ASSERT(!s_pathData()->rootPath.isEmpty());
62 return s_pathData()->rootPath;
63 }
64
setRootPath(const QString & rootPath)65 void setRootPath(const QString &rootPath)
66 {
67 Q_ASSERT(!rootPath.isEmpty());
68 Q_ASSERT(QDir(rootPath).exists());
69 Q_ASSERT(QDir(rootPath).isAbsolute());
70
71 QMutexLocker locker(&s_pathData()->mutex);
72 s_pathData()->rootPath = rootPath;
73 }
74
setRelativeRootPath(const char * relativeRootPath)75 void setRelativeRootPath(const char *relativeRootPath)
76 {
77 Q_ASSERT(relativeRootPath);
78 setRootPath(QCoreApplication::applicationDirPath() + QDir::separator()
79 + QLatin1String(relativeRootPath));
80 }
81
probePath(const QString & probeABI,const QString & rootPath)82 QString probePath(const QString &probeABI, const QString &rootPath)
83 {
84 #ifndef GAMMARAY_INSTALL_QT_LAYOUT
85 return rootPath + QDir::separator()
86 + QLatin1String(GAMMARAY_PLUGIN_INSTALL_DIR) + QDir::separator()
87 + QLatin1String(GAMMARAY_PLUGIN_VERSION) + QDir::separator()
88 + probeABI;
89 #else
90 Q_UNUSED(probeABI);
91 return rootPath + QDir::separator() + QLatin1String(GAMMARAY_PROBE_INSTALL_DIR);
92 #endif
93 }
94
binPath()95 QString binPath()
96 {
97 return rootPath() + QDir::separator() + QLatin1String(GAMMARAY_BIN_INSTALL_DIR);
98 }
99
libexecPath()100 QString libexecPath()
101 {
102 return rootPath() + QDir::separator() + QLatin1String(GAMMARAY_LIBEXEC_INSTALL_DIR);
103 }
104
currentProbePath()105 QString currentProbePath()
106 {
107 return probePath(QStringLiteral(GAMMARAY_PROBE_ABI));
108 }
109
addPluginPath(QStringList & list,const QString & path)110 static void addPluginPath(QStringList &list, const QString &path)
111 {
112 QFileInfo fi(path);
113 if (!fi.isDir())
114 return;
115 list.push_back(fi.canonicalFilePath());
116 }
117
pluginPaths(const QString & probeABI)118 QStringList pluginPaths(const QString &probeABI)
119 {
120 QStringList l;
121 // TODO based on environment variable for custom plugins
122
123 // based on rootPath()
124 addPluginPath(l, rootPath() + QLatin1String("/" GAMMARAY_PLUGIN_INSTALL_DIR "/" GAMMARAY_PLUGIN_VERSION "/") + probeABI);
125 addPluginPath(l, rootPath() + QLatin1String("/" GAMMARAY_PLUGIN_INSTALL_DIR));
126
127 // based on Qt plugin search paths
128 foreach (const auto &path, QCoreApplication::libraryPaths()) {
129 addPluginPath(l, path + QLatin1String("/gammaray/" GAMMARAY_PLUGIN_VERSION "/") + probeABI);
130 addPluginPath(l, path + QLatin1String("/gammaray"));
131
132 #if defined(Q_OS_ANDROID) && QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
133 addPluginPath(l, path);
134 #endif
135 }
136
137 // based on Qt's own install layout and/or qt.conf
138 const auto path = QLibraryInfo::location(QLibraryInfo::PluginsPath);
139 addPluginPath(l, path + QLatin1String("/gammaray/" GAMMARAY_PLUGIN_VERSION "/") + probeABI);
140 addPluginPath(l, path + QLatin1String("/gammaray"));
141
142
143 return l;
144 }
145
targetPluginPaths(const QString & probeABI)146 QStringList targetPluginPaths(const QString& probeABI)
147 {
148 QStringList l;
149
150 // based on rootPath()
151 addPluginPath(l, rootPath() + QLatin1String("/" GAMMARAY_TARGET_PLUGIN_INSTALL_DIR "/" GAMMARAY_PLUGIN_VERSION "/") + probeABI);
152 addPluginPath(l, rootPath() + QLatin1String("/" GAMMARAY_TARGET_PLUGIN_INSTALL_DIR));
153
154 // based on Qt plugin search paths
155 foreach (const auto &path, QCoreApplication::libraryPaths()) {
156 addPluginPath(l, path + QLatin1String("/gammaray/" GAMMARAY_PLUGIN_VERSION "/") + probeABI + QLatin1String("/target"));
157 addPluginPath(l, path + QLatin1String("/gammaray-target"));
158 }
159
160 // based on Qt's own install layout and/or qt.conf
161 const auto path = QLibraryInfo::location(QLibraryInfo::PluginsPath);
162 addPluginPath(l, path + QLatin1String("/gammaray/" GAMMARAY_PLUGIN_VERSION "/") + probeABI + QLatin1String("/target"));
163 addPluginPath(l, path + QLatin1String("/gammaray-target"));
164
165 return l;
166 }
167
currentPluginsPath()168 QString currentPluginsPath()
169 {
170 #ifndef GAMMARAY_INSTALL_QT_LAYOUT
171 return probePath(QStringLiteral(GAMMARAY_PROBE_ABI));
172 #else
173 return rootPath() + QDir::separator() + QStringLiteral(GAMMARAY_PLUGIN_INSTALL_DIR);
174 #endif
175 }
176
libraryExtension()177 QString libraryExtension()
178 {
179 #ifdef Q_OS_WIN
180 return QStringLiteral(".dll");
181 #elif defined(Q_OS_MAC)
182 return QStringLiteral(".dylib");
183 #elif defined(Q_OS_ANDROID) && QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
184 return QLatin1Char('_') + QLatin1String(ANDROID_ABI) + QLatin1String(".so");
185 #else
186 return QStringLiteral(".so");
187 #endif
188 }
189
pluginExtension()190 QString pluginExtension()
191 {
192 #ifdef Q_OS_MAC
193 return QStringLiteral(".so");
194 #else
195 return libraryExtension();
196 #endif
197 }
198
documentationPath()199 QString documentationPath()
200 {
201 return rootPath() + QLatin1Char('/') + QLatin1String(GAMMARAY_QCH_INSTALL_DIR);
202 }
203 }
204 }
205