comparison plugin/PluginScan.cpp @ 1527:710e6250a401 zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:14 +0100
parents d7fdc77252c6
children 830972646ccd
comparison
equal deleted inserted replaced
1324:d4a28d1479a8 1527:710e6250a401
16 16
17 #include "base/Debug.h" 17 #include "base/Debug.h"
18 #include "base/Preferences.h" 18 #include "base/Preferences.h"
19 #include "base/HelperExecPath.h" 19 #include "base/HelperExecPath.h"
20 20
21 #ifdef HAVE_PLUGIN_CHECKER_HELPER 21 #include <sstream>
22 #include "checker/knownplugins.h"
23 #else
24 class KnownPlugins {};
25 #endif
26 22
27 #include <QMutex> 23 #include <QMutex>
28 #include <QCoreApplication> 24 #include <QCoreApplication>
29 25
30 using std::string; 26 using std::string;
55 51
56 PluginScan::~PluginScan() { 52 PluginScan::~PluginScan() {
57 QMutexLocker locker(&m_mutex); 53 QMutexLocker locker(&m_mutex);
58 clear(); 54 clear();
59 delete m_logger; 55 delete m_logger;
56 SVDEBUG << "PluginScan::~PluginScan completed" << endl;
60 } 57 }
61 58
62 void 59 void
63 PluginScan::scan() 60 PluginScan::scan()
64 { 61 {
70 67
71 HelperExecPath hep(inProcess ? 68 HelperExecPath hep(inProcess ?
72 HelperExecPath::NativeArchitectureOnly : 69 HelperExecPath::NativeArchitectureOnly :
73 HelperExecPath::AllInstalled); 70 HelperExecPath::AllInstalled);
74 71
75 QString helperName("plugin-checker-helper"); 72 QString helperName("vamp-plugin-load-checker");
76 auto helpers = hep.getHelperExecutables(helperName); 73 auto helpers = hep.getHelperExecutables(helperName);
77 74
78 clear(); 75 clear();
79 76
80 for (auto p: helpers) { 77 for (auto p: helpers) {
89 } 86 }
90 } 87 }
91 88
92 for (auto p: helpers) { 89 for (auto p: helpers) {
93 try { 90 try {
94 KnownPlugins *kp = new KnownPlugins 91 KnownPluginCandidates *kp = new KnownPluginCandidates
95 (p.executable.toStdString(), m_logger); 92 (p.executable.toStdString(), m_logger);
96 if (m_kp.find(p.tag) != m_kp.end()) { 93 if (m_kp.find(p.tag) != m_kp.end()) {
97 SVDEBUG << "WARNING: PluginScan::scan: Duplicate tag " << p.tag 94 SVDEBUG << "WARNING: PluginScan::scan: Duplicate tag " << p.tag
98 << " for helpers" << endl; 95 << " for helpers" << endl;
99 continue; 96 continue;
104 SVDEBUG << "ERROR: PluginScan::scan: " << e.what() 101 SVDEBUG << "ERROR: PluginScan::scan: " << e.what()
105 << " (with helper path = " << p.executable << ")" << endl; 102 << " (with helper path = " << p.executable << ")" << endl;
106 } 103 }
107 } 104 }
108 105
106 SVDEBUG << "PluginScan::scan complete" << endl;
109 #endif 107 #endif
110 } 108 }
111 109
112 bool 110 bool
113 PluginScan::scanSucceeded() const 111 PluginScan::scanSucceeded() const
147 145
148 QList<Candidate> candidates; 146 QList<Candidate> candidates;
149 147
150 for (auto rec: m_kp) { 148 for (auto rec: m_kp) {
151 149
152 KnownPlugins *kp = rec.second; 150 KnownPluginCandidates *kp = rec.second;
153 151
154 auto c = kp->getCandidateLibrariesFor(kpt); 152 auto c = kp->getCandidateLibrariesFor(kpt);
155 153
156 SVDEBUG << "PluginScan: helper \"" << kp->getHelperExecutableName() 154 SVDEBUG << "PluginScan: helper \"" << kp->getHelperExecutableName()
157 << "\" likes " << c.size() << " libraries of type " 155 << "\" likes " << c.size() << " libraries of type "
178 #else 176 #else
179 return {}; 177 return {};
180 #endif 178 #endif
181 } 179 }
182 180
181 #ifdef HAVE_PLUGIN_CHECKER_HELPER
182 QString
183 PluginScan::formatFailureReport(QString tag,
184 std::vector<PluginCandidates::FailureRec> failures) const
185 {
186 int n = int(failures.size());
187 int i = 0;
188
189 std::ostringstream os;
190
191 os << "<ul>";
192 for (auto f: failures) {
193 os << "<li>" + f.library;
194
195 SVDEBUG << "PluginScan::formatFailureReport: tag is \"" << tag
196 << "\", failure code is " << int(f.code) << ", message is \""
197 << f.message << "\"" << endl;
198
199 QString userMessage = QString::fromStdString(f.message);
200
201 switch (f.code) {
202
203 case PluginCheckCode::FAIL_LIBRARY_NOT_FOUND:
204 userMessage = QObject::tr("Library file could not be opened");
205 break;
206
207 case PluginCheckCode::FAIL_WRONG_ARCHITECTURE:
208 if (tag == "64" || (sizeof(void *) == 8 && tag == "")) {
209 userMessage = QObject::tr
210 ("Library has wrong architecture - possibly a 32-bit plugin installed in a 64-bit plugin folder");
211 } else if (tag == "32" || (sizeof(void *) == 4 && tag == "")) {
212 userMessage = QObject::tr
213 ("Library has wrong architecture - possibly a 64-bit plugin installed in a 32-bit plugin folder");
214 }
215 break;
216
217 case PluginCheckCode::FAIL_DEPENDENCY_MISSING:
218 userMessage = QObject::tr
219 ("Library depends on another library that cannot be found: %1")
220 .arg(userMessage);
221 break;
222
223 case PluginCheckCode::FAIL_NOT_LOADABLE:
224 userMessage = QObject::tr
225 ("Library cannot be loaded: %1").arg(userMessage);
226 break;
227
228 case PluginCheckCode::FAIL_DESCRIPTOR_MISSING:
229 userMessage = QObject::tr
230 ("Not a valid plugin library (no descriptor found)");
231 break;
232
233 case PluginCheckCode::FAIL_NO_PLUGINS:
234 userMessage = QObject::tr
235 ("Library contains no plugins");
236 break;
237
238 case PluginCheckCode::FAIL_OTHER:
239 if (userMessage == "") {
240 userMessage = QObject::tr
241 ("Unknown error");
242 }
243 break;
244
245 case PluginCheckCode::SUCCESS:
246 // success shouldn't happen here!
247 break;
248 }
249
250 os << "<br><i>" + userMessage.toStdString() + "</i>";
251 os << "</li>";
252
253 if (n > 10) {
254 if (++i == 5) {
255 os << "<li>";
256 os << QObject::tr("... and %n further failure(s)",
257 "", n - i)
258 .toStdString();
259 os << "</li>";
260 break;
261 }
262 }
263 }
264 os << "</ul>";
265
266 return QString::fromStdString(os.str());
267 }
268 #endif
269
183 QString 270 QString
184 PluginScan::getStartupFailureReport() const 271 PluginScan::getStartupFailureReport() const
185 { 272 {
186 #ifdef HAVE_PLUGIN_CHECKER_HELPER 273 #ifdef HAVE_PLUGIN_CHECKER_HELPER
187 274
188 QMutexLocker locker(&m_mutex); 275 QMutexLocker locker(&m_mutex);
189 276
190 if (!m_succeeded) { 277 if (!m_succeeded) {
191 return QObject::tr("<b>Failed to scan for plugins</b>" 278 return QObject::tr("<b>Failed to scan for plugins</b>"
192 "<p>Failed to scan for plugins at startup. Possibly " 279 "<p>Failed to scan for plugins at startup. Possibly "
193 "the plugin checker helper program was not correctly " 280 "the plugin checker program was not correctly "
194 "installed alongside %1?</p>") 281 "installed alongside %1?</p>")
195 .arg(QCoreApplication::applicationName()); 282 .arg(QCoreApplication::applicationName());
196 } 283 }
197 if (m_kp.empty()) { 284 if (m_kp.empty()) {
198 return QObject::tr("<b>Did not scan for plugins</b>" 285 return QObject::tr("<b>Did not scan for plugins</b>"
199 "<p>Apparently no scan for plugins was attempted " 286 "<p>Apparently no scan for plugins was attempted "
200 "(internal error?)</p>"); 287 "(internal error?)</p>");
201 } 288 }
202 289
203 QString report; 290 QString report;
204 for (auto kp: m_kp) { 291 for (auto kp: m_kp) {
205 report += QString::fromStdString(kp.second->getFailureReport()); 292 auto failures = kp.second->getFailures();
293 if (!failures.empty()) {
294 report += formatFailureReport(kp.first, failures);
295 }
206 } 296 }
207 if (report == "") { 297 if (report == "") {
208 return report; 298 return report;
209 } 299 }
210 300
211 return QObject::tr("<b>Failed to load plugins</b>" 301 return QObject::tr("<b>Failed to load plugins</b>"
212 "<p>Failed to load one or more plugin libraries:</p>") 302 "<p>Failed to load one or more plugin libraries:</p>")
213 + report 303 + report
214 + QObject::tr("<p>These plugins may be incompatible with the system, " 304 + QObject::tr("<p>These plugins may be incompatible with the system, "
215 "and will be ignored during this run of %1.</p>") 305 "and will be ignored during this run of %1.</p>")
216 .arg(QCoreApplication::applicationName()); 306 .arg(QCoreApplication::applicationName());
217 307
218 #else 308 #else