Mercurial > hg > svcore
comparison plugin/PluginScan.cpp @ 1251:67aee57e32c8 3.0-integration
Merge from branch piper
author | Chris Cannam |
---|---|
date | Fri, 04 Nov 2016 14:57:03 +0000 |
parents | d45a16c232bd |
children | a99641535e02 |
comparison
equal
deleted
inserted
replaced
1241:c6bdf247016a | 1251:67aee57e32c8 |
---|---|
13 */ | 13 */ |
14 | 14 |
15 #include "PluginScan.h" | 15 #include "PluginScan.h" |
16 | 16 |
17 #include "base/Debug.h" | 17 #include "base/Debug.h" |
18 #include "base/Preferences.h" | |
18 #include "base/HelperExecPath.h" | 19 #include "base/HelperExecPath.h" |
19 | 20 |
21 #ifdef HAVE_PLUGIN_CHECKER_HELPER | |
20 #include "checker/knownplugins.h" | 22 #include "checker/knownplugins.h" |
23 #else | |
24 class KnownPlugins {}; | |
25 #endif | |
21 | 26 |
22 #include <QMutex> | 27 #include <QMutex> |
23 #include <QCoreApplication> | 28 #include <QCoreApplication> |
24 | 29 |
25 using std::string; | 30 using std::string; |
26 | 31 |
27 //#define DEBUG_PLUGIN_SCAN 1 | 32 class PluginScan::Logger |
28 | 33 #ifdef HAVE_PLUGIN_CHECKER_HELPER |
29 class PluginScan::Logger : public PluginCandidates::LogCallback | 34 : public PluginCandidates::LogCallback |
35 #endif | |
30 { | 36 { |
31 protected: | 37 protected: |
32 void log(std::string message) { | 38 void log(std::string message) { |
33 #ifdef DEBUG_PLUGIN_SCAN | |
34 cerr << "PluginScan: " << message; | |
35 #endif | |
36 SVDEBUG << "PluginScan: " << message; | 39 SVDEBUG << "PluginScan: " << message; |
37 } | 40 } |
38 }; | 41 }; |
39 | 42 |
40 PluginScan *PluginScan::getInstance() | 43 PluginScan *PluginScan::getInstance() |
45 if (!m_instance) m_instance = new PluginScan(); | 48 if (!m_instance) m_instance = new PluginScan(); |
46 mutex.unlock(); | 49 mutex.unlock(); |
47 return m_instance; | 50 return m_instance; |
48 } | 51 } |
49 | 52 |
50 PluginScan::PluginScan() : m_kp(0), m_succeeded(false), m_logger(new Logger) { | 53 PluginScan::PluginScan() : m_succeeded(false), m_logger(new Logger) { |
51 } | 54 } |
52 | 55 |
53 PluginScan::~PluginScan() { | 56 PluginScan::~PluginScan() { |
57 QMutexLocker locker(&m_mutex); | |
54 clear(); | 58 clear(); |
55 delete m_logger; | 59 delete m_logger; |
56 } | 60 } |
57 | 61 |
58 void | 62 void |
59 PluginScan::scan() | 63 PluginScan::scan() |
60 { | 64 { |
61 QStringList helperPaths = | 65 #ifdef HAVE_PLUGIN_CHECKER_HELPER |
62 HelperExecPath::getHelperExecutables("plugin-checker-helper"); | 66 |
67 QMutexLocker locker(&m_mutex); | |
68 | |
69 bool inProcess = Preferences::getInstance()->getRunPluginsInProcess(); | |
70 | |
71 HelperExecPath hep(inProcess ? | |
72 HelperExecPath::NativeArchitectureOnly : | |
73 HelperExecPath::AllInstalled); | |
74 | |
75 QString helperName("plugin-checker-helper"); | |
76 auto helpers = hep.getHelperExecutables(helperName); | |
63 | 77 |
64 clear(); | 78 clear(); |
65 | 79 |
66 for (auto p: helperPaths) { | 80 for (auto p: helpers) { |
81 SVDEBUG << "NOTE: PluginScan: Found helper: " << p.executable << endl; | |
82 } | |
83 | |
84 if (helpers.empty()) { | |
85 SVDEBUG << "NOTE: No plugin checker helpers found in installation;" | |
86 << " found none of the following:" << endl; | |
87 for (auto d: hep.getHelperCandidatePaths(helperName)) { | |
88 SVDEBUG << "NOTE: " << d << endl; | |
89 } | |
90 } | |
91 | |
92 for (auto p: helpers) { | |
67 try { | 93 try { |
68 KnownPlugins *kp = new KnownPlugins(p.toStdString(), m_logger); | 94 KnownPlugins *kp = new KnownPlugins |
69 m_kp.push_back(kp); | 95 (p.executable.toStdString(), m_logger); |
96 if (m_kp.find(p.tag) != m_kp.end()) { | |
97 SVDEBUG << "WARNING: PluginScan::scan: Duplicate tag " << p.tag | |
98 << " for helpers" << endl; | |
99 continue; | |
100 } | |
101 m_kp[p.tag] = kp; | |
70 m_succeeded = true; | 102 m_succeeded = true; |
71 } catch (const std::exception &e) { | 103 } catch (const std::exception &e) { |
72 cerr << "ERROR: PluginScan::scan: " << e.what() | 104 SVDEBUG << "ERROR: PluginScan::scan: " << e.what() |
73 << " (with helper path = " << p << ")" << endl; | 105 << " (with helper path = " << p.executable << ")" << endl; |
74 } | 106 } |
75 } | 107 } |
108 | |
109 #endif | |
110 } | |
111 | |
112 bool | |
113 PluginScan::scanSucceeded() const | |
114 { | |
115 QMutexLocker locker(&m_mutex); | |
116 return m_succeeded; | |
76 } | 117 } |
77 | 118 |
78 void | 119 void |
79 PluginScan::clear() | 120 PluginScan::clear() |
80 { | 121 { |
81 for (auto &p: m_kp) delete p; | 122 for (auto &p: m_kp) { |
123 delete p.second; | |
124 } | |
82 m_kp.clear(); | 125 m_kp.clear(); |
83 m_succeeded = false; | 126 m_succeeded = false; |
84 } | 127 } |
85 | 128 |
86 QStringList | 129 QList<PluginScan::Candidate> |
87 PluginScan::getCandidateLibrariesFor(PluginType type) const | 130 PluginScan::getCandidateLibrariesFor(PluginType type) const |
88 { | 131 { |
132 #ifdef HAVE_PLUGIN_CHECKER_HELPER | |
133 | |
134 QMutexLocker locker(&m_mutex); | |
135 | |
89 KnownPlugins::PluginType kpt; | 136 KnownPlugins::PluginType kpt; |
90 switch (type) { | 137 switch (type) { |
91 case VampPlugin: kpt = KnownPlugins::VampPlugin; break; | 138 case VampPlugin: kpt = KnownPlugins::VampPlugin; break; |
92 case LADSPAPlugin: kpt = KnownPlugins::LADSPAPlugin; break; | 139 case LADSPAPlugin: kpt = KnownPlugins::LADSPAPlugin; break; |
93 case DSSIPlugin: kpt = KnownPlugins::DSSIPlugin; break; | 140 case DSSIPlugin: kpt = KnownPlugins::DSSIPlugin; break; |
94 default: throw std::logic_error("Inconsistency in plugin type enums"); | 141 default: throw std::logic_error("Inconsistency in plugin type enums"); |
95 } | 142 } |
96 | 143 |
97 QStringList candidates; | 144 QList<Candidate> candidates; |
98 for (auto kp: m_kp) { | 145 |
146 for (auto rec: m_kp) { | |
147 | |
148 KnownPlugins *kp = rec.second; | |
149 | |
99 auto c = kp->getCandidateLibrariesFor(kpt); | 150 auto c = kp->getCandidateLibrariesFor(kpt); |
100 for (auto s: c) candidates.push_back(s.c_str()); | 151 |
101 } | 152 SVDEBUG << "PluginScan: helper \"" << kp->getHelperExecutableName() |
153 << "\" likes " << c.size() << " libraries of type " | |
154 << kp->getTagFor(kpt) << endl; | |
155 | |
156 for (auto s: c) { | |
157 candidates.push_back({ s.c_str(), rec.first }); | |
158 } | |
159 | |
160 if (type != VampPlugin) { | |
161 // We are only interested in querying multiple helpers | |
162 // when dealing with Vamp plugins, for which we can use | |
163 // external servers and so in some cases can support | |
164 // additional architectures. Other plugin formats are | |
165 // loaded directly and so must match the host, which is | |
166 // what the first helper is supposed to handle -- so | |
167 // break after the first one if not querying Vamp | |
168 break; | |
169 } | |
170 } | |
171 | |
102 return candidates; | 172 return candidates; |
173 | |
174 #else | |
175 return {}; | |
176 #endif | |
103 } | 177 } |
104 | 178 |
105 QString | 179 QString |
106 PluginScan::getStartupFailureReport() const | 180 PluginScan::getStartupFailureReport() const |
107 { | 181 { |
182 #ifdef HAVE_PLUGIN_CHECKER_HELPER | |
183 | |
184 QMutexLocker locker(&m_mutex); | |
185 | |
108 if (!m_succeeded) { | 186 if (!m_succeeded) { |
109 return QObject::tr("<b>Failed to scan for plugins</b>" | 187 return QObject::tr("<b>Failed to scan for plugins</b>" |
110 "<p>Failed to scan for plugins at startup. Possibly " | 188 "<p>Failed to scan for plugins at startup. Possibly " |
111 "the plugin checker helper program was not correctly " | 189 "the plugin checker helper program was not correctly " |
112 "installed alongside %1?</p>") | 190 "installed alongside %1?</p>") |
118 "(internal error?)</p>"); | 196 "(internal error?)</p>"); |
119 } | 197 } |
120 | 198 |
121 QString report; | 199 QString report; |
122 for (auto kp: m_kp) { | 200 for (auto kp: m_kp) { |
123 report += QString::fromStdString(kp->getFailureReport()); | 201 report += QString::fromStdString(kp.second->getFailureReport()); |
124 } | 202 } |
125 if (report == "") { | 203 if (report == "") { |
126 return report; | 204 return report; |
127 } | 205 } |
128 | 206 |
130 "<p>Failed to load one or more plugin libraries:</p>") | 208 "<p>Failed to load one or more plugin libraries:</p>") |
131 + report | 209 + report |
132 + QObject::tr("<p>These plugins may be incompatible with the system, " | 210 + QObject::tr("<p>These plugins may be incompatible with the system, " |
133 "and will be ignored during this run of %1.</p>") | 211 "and will be ignored during this run of %1.</p>") |
134 .arg(QCoreApplication::applicationName()); | 212 .arg(QCoreApplication::applicationName()); |
135 } | 213 |
136 | 214 #else |
215 return ""; | |
216 #endif | |
217 } | |
218 |