Changeset View
Standalone View
projectmanagers/cmake/cmakemanager.cpp
Show All 27 Lines | |||||
28 | #include "debug.h" | 28 | #include "debug.h" | ||
29 | #include "settings/cmakepreferences.h" | 29 | #include "settings/cmakepreferences.h" | ||
30 | #include <projectmanagers/custommake/makefileresolver/makefileresolver.h> | 30 | #include <projectmanagers/custommake/makefileresolver/makefileresolver.h> | ||
31 | #include "cmakecodecompletionmodel.h" | 31 | #include "cmakecodecompletionmodel.h" | ||
32 | #include "cmakenavigationwidget.h" | 32 | #include "cmakenavigationwidget.h" | ||
33 | #include "icmakedocumentation.h" | 33 | #include "icmakedocumentation.h" | ||
34 | #include "cmakemodelitems.h" | 34 | #include "cmakemodelitems.h" | ||
35 | #include "testing/ctestutils.h" | 35 | #include "testing/ctestutils.h" | ||
36 | #include "cmakeserverimportjob.h" | ||||
36 | 37 | | |||
37 | #include <QDir> | 38 | #include <QDir> | ||
38 | #include <QReadWriteLock> | 39 | #include <QReadWriteLock> | ||
39 | #include <QThread> | 40 | #include <QThread> | ||
40 | #include <QFileSystemWatcher> | 41 | #include <QFileSystemWatcher> | ||
41 | #include <QTimer> | 42 | #include <QTimer> | ||
42 | #include <qjsondocument.h> | 43 | #include <qjsondocument.h> | ||
43 | 44 | | |||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Line(s) | |||||
107 | { | 108 | { | ||
108 | parseLock()->lockForWrite(); | 109 | parseLock()->lockForWrite(); | ||
109 | // By locking the parse-mutexes, we make sure that parse jobs get a chance to finish in a good state | 110 | // By locking the parse-mutexes, we make sure that parse jobs get a chance to finish in a good state | ||
110 | parseLock()->unlock(); | 111 | parseLock()->unlock(); | ||
111 | } | 112 | } | ||
112 | 113 | | |||
113 | bool CMakeManager::hasBuildInfo(ProjectBaseItem* item) const | 114 | bool CMakeManager::hasBuildInfo(ProjectBaseItem* item) const | ||
114 | { | 115 | { | ||
115 | return m_projects[item->project()].jsonData.files.contains(item->path()); | 116 | return m_projects[item->project()].compilationData.files.contains(item->path()); | ||
116 | } | 117 | } | ||
117 | 118 | | |||
118 | Path CMakeManager::buildDirectory(KDevelop::ProjectBaseItem *item) const | 119 | Path CMakeManager::buildDirectory(KDevelop::ProjectBaseItem *item) const | ||
119 | { | 120 | { | ||
120 | // CMakeFolderItem *fi=dynamic_cast<CMakeFolderItem*>(item); | 121 | // CMakeFolderItem *fi=dynamic_cast<CMakeFolderItem*>(item); | ||
121 | // Path ret; | 122 | // Path ret; | ||
122 | // ProjectBaseItem* parent = fi ? fi->formerParent() : item->parent(); | 123 | // ProjectBaseItem* parent = fi ? fi->formerParent() : item->parent(); | ||
123 | // if (parent) | 124 | // if (parent) | ||
Show All 9 Lines | |||||
133 | 134 | | |||
134 | KDevelop::ProjectFolderItem* CMakeManager::import( KDevelop::IProject *project ) | 135 | KDevelop::ProjectFolderItem* CMakeManager::import( KDevelop::IProject *project ) | ||
135 | { | 136 | { | ||
136 | CMake::checkForNeedingConfigure(project); | 137 | CMake::checkForNeedingConfigure(project); | ||
137 | 138 | | |||
138 | return AbstractFileManagerPlugin::import(project); | 139 | return AbstractFileManagerPlugin::import(project); | ||
139 | } | 140 | } | ||
140 | 141 | | |||
142 | Q_GLOBAL_STATIC_WITH_ARGS(bool, s_serverSupported, (false)) | ||||
mwolff: for PODs, you don't need Q_GLOBAL_STATIC. simply make this a
namespace {
static bool… | |||||
mwolff: this is not used anywhere now? | |||||
143 | | ||||
141 | KJob* CMakeManager::createImportJob(ProjectFolderItem* item) | 144 | KJob* CMakeManager::createImportJob(ProjectFolderItem* item) | ||
142 | { | 145 | { | ||
143 | auto project = item->project(); | 146 | auto project = item->project(); | ||
144 | 147 | | |||
145 | QList<KJob*> jobs; | 148 | QList<KJob*> jobs; | ||
146 | 149 | | |||
150 | if (s_serverSupported) { | ||||
151 | auto job = new CMakeServerImportJob(project, this); | ||||
Somewhy is not working:
zhigalin: Somewhy is not working:
> kdevelop.projectmanagers.cmake: cmake server socket error… | |||||
152 | connect(job, &CMakeServerImportJob::result, this, [this, job](){ | ||||
153 | if (job->error() != 0) { | ||||
154 | qCDebug(CMAKE) << "couldn't load successfully" << job->project()->name(); | ||||
make this a warning? also, do we want to show the user that? this can be serious and render the whole cmake support useless after all, right? mwolff: make this a warning? also, do we want to show the user that? this can be serious and render the… | |||||
155 | m_projects.remove(job->project()); | ||||
156 | } else { | ||||
157 | integrateData(job->projectData(), job->project()); | ||||
158 | } | ||||
159 | }); | ||||
160 | jobs << job; | ||||
161 | } else { | ||||
162 | // parse the JSON file | ||||
163 | CMakeImportJsonJob* job = new CMakeImportJsonJob(project, this); | ||||
164 | | ||||
147 | // create the JSON file if it doesn't exist | 165 | // create the JSON file if it doesn't exist | ||
148 | auto commandsFile = CMake::commandsFile(project); | 166 | auto commandsFile = CMake::commandsFile(project); | ||
149 | if (!QFileInfo::exists(commandsFile.toLocalFile())) { | 167 | if (!QFileInfo::exists(commandsFile.toLocalFile())) { | ||
150 | qCDebug(CMAKE) << "couldn't find commands file:" << commandsFile << "- now trying to reconfigure"; | 168 | qCDebug(CMAKE) << "couldn't find commands file:" << commandsFile << "- now trying to reconfigure"; | ||
arrowd: Why comment this? | |||||
151 | jobs << builder()->configure(project); | 169 | jobs << builder()->configure(project); | ||
152 | } | 170 | } | ||
Who will delete the server when it is available? this looks like you are piling up servers until the CMakeManager is deleted at shutdown. You probably want to use a unique_ptr here and transfer ownership into the import job when the server is available mwolff: Who will delete the server when it is available? this looks like you are piling up servers… | |||||
153 | 171 | | |||
154 | // parse the JSON file | 172 | connect(job, &CMakeImportJsonJob::result, this, [this, job](){ | ||
155 | CMakeImportJob* job = new CMakeImportJob(project, this); | 173 | if (job->error() != 0) { | ||
156 | connect(job, &CMakeImportJob::result, this, &CMakeManager::importFinished); | 174 | qCDebug(CMAKE) << "couldn't load successfully" << job->project()->name(); | ||
warning, and see above? actually the whole code is duplicated - move this into a proper slot? or at least share the lambda body? mwolff: warning, and see above? actually the whole code is duplicated - move this into a proper slot? | |||||
As is we can't, they should inherit from the same class. I don't think it's a big deal at the moment... apol: As is we can't, they should inherit from the same class. I don't think it's a big deal at the… | |||||
175 | m_projects.remove(job->project()); | ||||
176 | } else { | ||||
177 | integrateData(job->projectData(), job->project()); | ||||
178 | } | ||||
179 | }); | ||||
157 | jobs << job; | 180 | jobs << job; | ||
181 | } | ||||
158 | 182 | | |||
159 | // generate the file system listing | 183 | // generate the file system listing | ||
160 | jobs << KDevelop::AbstractFileManagerPlugin::createImportJob(item); | 184 | jobs << KDevelop::AbstractFileManagerPlugin::createImportJob(item); | ||
161 | 185 | | |||
162 | Q_ASSERT(!jobs.contains(nullptr)); | 186 | Q_ASSERT(!jobs.contains(nullptr)); | ||
163 | ExecuteCompositeJob* composite = new ExecuteCompositeJob(this, jobs); | 187 | ExecuteCompositeJob* composite = new ExecuteCompositeJob(this, jobs); | ||
164 | // even if the cmake call failed, we want to load the project so that the project can be worked on | 188 | // even if the cmake call failed, we want to load the project so that the project can be worked on | ||
165 | composite->setAbortOnError(false); | 189 | composite->setAbortOnError(false); | ||
166 | return composite; | 190 | return composite; | ||
167 | } | 191 | } | ||
168 | 192 | | |||
169 | // QList<ProjectFolderItem*> CMakeManager::parse(ProjectFolderItem*) | 193 | // QList<ProjectFolderItem*> CMakeManager::parse(ProjectFolderItem*) | ||
170 | // { return QList< ProjectFolderItem* >(); } | 194 | // { return QList< ProjectFolderItem* >(); } | ||
171 | // | 195 | // | ||
172 | // | 196 | // | ||
173 | 197 | | |||
174 | QList<KDevelop::ProjectTargetItem*> CMakeManager::targets() const | 198 | QList<KDevelop::ProjectTargetItem*> CMakeManager::targets() const | ||
175 | { | 199 | { | ||
176 | QList<KDevelop::ProjectTargetItem*> ret; | 200 | QList<KDevelop::ProjectTargetItem*> ret; | ||
177 | foreach(IProject* p, m_projects.keys()) | 201 | foreach(IProject* p, m_projects.keys()) | ||
178 | { | 202 | { | ||
179 | ret+=p->projectItem()->targetList(); | 203 | ret+=p->projectItem()->targetList(); | ||
180 | } | 204 | } | ||
mwolff: these shouldn't be QPointer, or? | |||||
181 | return ret; | 205 | return ret; | ||
182 | } | 206 | } | ||
183 | 207 | | |||
184 | CMakeFile CMakeManager::fileInformation(KDevelop::ProjectBaseItem* item) const | 208 | CMakeFile CMakeManager::fileInformation(KDevelop::ProjectBaseItem* item) const | ||
185 | { | 209 | { | ||
186 | const CMakeJsonData & data = m_projects[item->project()].jsonData; | 210 | const auto & data = m_projects[item->project()].compilationData; | ||
187 | QHash<KDevelop::Path, CMakeFile>::const_iterator it = data.files.constFind(item->path()); | 211 | QHash<KDevelop::Path, CMakeFile>::const_iterator it = data.files.constFind(item->path()); | ||
188 | 212 | | |||
189 | if (it == data.files.constEnd()) { | 213 | if (it == data.files.constEnd()) { | ||
190 | // if the item path contains a symlink, then we will not find it in the lookup table | 214 | // if the item path contains a symlink, then we will not find it in the lookup table | ||
191 | // as that only only stores canonicalized paths. Thus, we fallback to | 215 | // as that only only stores canonicalized paths. Thus, we fallback to | ||
192 | // to the canonicalized path and see if that brings up any matches | 216 | // to the canonicalized path and see if that brings up any matches | ||
193 | const auto canonicalized = Path(QFileInfo(item->path().toLocalFile()).canonicalFilePath()); | 217 | const auto canonicalized = Path(QFileInfo(item->path().toLocalFile()).canonicalFilePath()); | ||
194 | it = data.files.constFind(canonicalized); | 218 | it = data.files.constFind(canonicalized); | ||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Line(s) | 304 | ) | |||
281 | new CMakeTargetItem(folder, name); | 305 | new CMakeTargetItem(folder, name); | ||
282 | } | 306 | } | ||
283 | 307 | | |||
284 | foreach (ProjectFolderItem* children, folder->folderList()) { | 308 | foreach (ProjectFolderItem* children, folder->folderList()) { | ||
285 | populateTargets(children, targets); | 309 | populateTargets(children, targets); | ||
286 | } | 310 | } | ||
287 | } | 311 | } | ||
288 | 312 | | |||
289 | void CMakeManager::importFinished(KJob* j) | 313 | void CMakeManager::integrateData(const CMakeProjectData &data, KDevelop::IProject* project) | ||
290 | { | 314 | { | ||
291 | CMakeImportJob* job = qobject_cast<CMakeImportJob*>(j); | | |||
292 | Q_ASSERT(job); | | |||
293 | | ||||
294 | auto project = job->project(); | | |||
295 | if (job->error() != 0) { | | |||
296 | qCDebug(CMAKE) << "Import failed for project" << project->name() << job->errorText(); | | |||
297 | m_projects.remove(project); | | |||
298 | } | | |||
299 | | ||||
300 | qCDebug(CMAKE) << "Successfully imported project" << project->name(); | | |||
301 | | ||||
302 | CMakeProjectData data; | | |||
303 | data.watcher->addPath(CMake::commandsFile(project).toLocalFile()); | | |||
304 | data.watcher->addPath(CMake::targetDirectoriesFile(project).toLocalFile()); | | |||
305 | data.jsonData = job->jsonData(); | | |||
306 | data.targets = job->targets(); | | |||
307 | connect(data.watcher.data(), &QFileSystemWatcher::fileChanged, this, &CMakeManager::dirtyFile); | 315 | connect(data.watcher.data(), &QFileSystemWatcher::fileChanged, this, &CMakeManager::dirtyFile); | ||
308 | connect(data.watcher.data(), &QFileSystemWatcher::directoryChanged, this, &CMakeManager::dirtyFile); | 316 | connect(data.watcher.data(), &QFileSystemWatcher::directoryChanged, this, &CMakeManager::dirtyFile); | ||
309 | m_projects[job->project()] = data; | 317 | m_projects[project] = data; | ||
310 | | ||||
311 | populateTargets(job->project()->projectItem(), job->targets()); | | |||
312 | 318 | | |||
313 | CTestUtils::createTestSuites(job->testSuites(), project); | 319 | populateTargets(project->projectItem(), data.targets); | ||
320 | CTestUtils::createTestSuites(data.testSuites(), project); | ||||
314 | } | 321 | } | ||
315 | 322 | | |||
316 | // void CMakeManager::deletedWatchedDirectory(IProject* p, const QUrl &dir) | 323 | // void CMakeManager::deletedWatchedDirectory(IProject* p, const QUrl &dir) | ||
317 | // { | 324 | // { | ||
318 | // if(p->folder().equals(dir, QUrl::CompareWithoutTrailingSlash)) { | 325 | // if(p->folder().equals(dir, QUrl::CompareWithoutTrailingSlash)) { | ||
319 | // ICore::self()->projectController()->closeProject(p); | 326 | // ICore::self()->projectController()->closeProject(p); | ||
320 | // } else { | 327 | // } else { | ||
321 | // if(dir.fileName()=="CMakeLists.txt") { | 328 | // if(dir.fileName()=="CMakeLists.txt") { | ||
▲ Show 20 Lines • Show All 561 Lines • Show Last 20 Lines |
for PODs, you don't need Q_GLOBAL_STATIC. simply make this a
namespace {
static bool s_serverSupported = false;
}
on a conceptual level - this depends on the cmake binary that can be selected for every project, no? So this should not be a static at all, but rather a per-project property?