summaryrefslogtreecommitdiff
path: root/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2019-08-13 12:47:11 +0200
committerTobias Hunger <tobias.hunger@qt.io>2019-08-29 07:28:26 +0000
commitfb21b78444fa2ff18fecaf45db36bd72b3dfe734 (patch)
treefd33b814e925bd748579b7222cfcfc2120ae409c /src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
parentb7e4046a173a2c42ede92934cc05c0f76486db5e (diff)
downloadqt-creator-fb21b78444fa2ff18fecaf45db36bd72b3dfe734.tar.gz
Autotools: Introduce AutotoolsBuildSystem
Introduce AutotoolsBuildSystem and slim down AutotoolsProject. Change-Id: I68296152f9ecd5d14198c8d0b36a06c2d1b162ec Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp')
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
new file mode 100644
index 0000000000..1adf9e003d
--- /dev/null
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Openismus GmbH.
+** Author: Peter Penz (ppenz@openismus.com)
+** Author: Patricia Santana Cruz (patriciasantanacruz@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "autotoolsbuildsystem.h"
+
+#include "makefileparserthread.h"
+#include "makestep.h"
+
+#include <cpptools/cppprojectupdater.h>
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/target.h>
+#include <qtsupport/qtcppkitinfo.h>
+
+#include <utils/filesystemwatcher.h>
+
+using namespace ProjectExplorer;
+
+namespace AutotoolsProjectManager {
+namespace Internal {
+
+AutotoolsBuildSystem::AutotoolsBuildSystem(Project *project)
+ : BuildSystem(project)
+ , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
+{
+ connect(project, &Project::activeBuildConfigurationChanged, this, [this]() { requestParse(); });
+
+ connect(project, &Project::projectFileIsDirty, this, [this]() { requestParse(); });
+}
+
+AutotoolsBuildSystem::~AutotoolsBuildSystem()
+{
+ delete m_cppCodeModelUpdater;
+
+ if (m_makefileParserThread) {
+ m_makefileParserThread->wait();
+ delete m_makefileParserThread;
+ m_makefileParserThread = nullptr;
+ }
+}
+
+void AutotoolsBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
+{
+ if (m_makefileParserThread) {
+ // The thread is still busy parsing a previous configuration.
+ // Wait until the thread has been finished and delete it.
+ // TODO: Discuss whether blocking is acceptable.
+ disconnect(m_makefileParserThread,
+ &QThread::finished,
+ this,
+ &AutotoolsBuildSystem::makefileParsingFinished);
+ m_makefileParserThread->wait();
+ delete m_makefileParserThread;
+ m_makefileParserThread = nullptr;
+ }
+
+ // Parse the makefile asynchronously in a thread
+ m_makefileParserThread = new MakefileParserThread(project()->projectFilePath().toString(),
+ std::move(ctx.guard));
+
+ connect(m_makefileParserThread,
+ &MakefileParserThread::finished,
+ this,
+ &AutotoolsBuildSystem::makefileParsingFinished);
+ m_makefileParserThread->start();
+}
+
+void AutotoolsBuildSystem::makefileParsingFinished()
+{
+ // The finished() signal is from a previous makefile-parser-thread
+ // and can be skipped. This can happen, if the thread has emitted the
+ // finished() signal during the execution of AutotoolsBuildSystem::loadProjectTree().
+ // In this case the signal is in the message queue already and deleting
+ // the thread of course does not remove the signal again.
+ if (sender() != m_makefileParserThread)
+ return;
+
+ if (m_makefileParserThread->isCanceled()) {
+ // The parsing has been cancelled by the user. Don't show any
+ // project data at all.
+ m_makefileParserThread->deleteLater();
+ m_makefileParserThread = nullptr;
+ return;
+ }
+
+ if (m_makefileParserThread->hasError())
+ qWarning("Parsing of makefile contained errors.");
+
+ m_files.clear();
+
+ QVector<Utils::FilePath> filesToWatch;
+
+ // Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
+ const QFileInfo fileInfo = project()->projectFilePath().toFileInfo();
+ const QDir dir = fileInfo.absoluteDir();
+ const QStringList files = m_makefileParserThread->sources();
+ foreach (const QString& file, files)
+ m_files.append(dir.absoluteFilePath(file));
+
+ // Watch for changes of Makefile.am files. If a Makefile.am file
+ // has been changed, the project tree must be reparsed.
+ const QStringList makefiles = m_makefileParserThread->makefiles();
+ foreach (const QString &makefile, makefiles) {
+ const QString absMakefile = dir.absoluteFilePath(makefile);
+
+ m_files.append(absMakefile);
+
+ filesToWatch.append(Utils::FilePath::fromString(absMakefile));
+ }
+
+ // Add configure.ac file to project and watch for changes.
+ const QLatin1String configureAc(QLatin1String("configure.ac"));
+ const QFile configureAcFile(fileInfo.absolutePath() + QLatin1Char('/') + configureAc);
+ if (configureAcFile.exists()) {
+ const QString absConfigureAc = dir.absoluteFilePath(configureAc);
+ m_files.append(absConfigureAc);
+
+ filesToWatch.append(Utils::FilePath::fromString(absConfigureAc));
+ }
+
+ auto newRoot = std::make_unique<ProjectNode>(project()->projectDirectory());
+ for (const QString &f : m_files) {
+ const Utils::FilePath path = Utils::FilePath::fromString(f);
+ newRoot->addNestedNode(std::make_unique<FileNode>(path,
+ FileNode::fileTypeForFileName(path)));
+ }
+ project()->setRootProjectNode(std::move(newRoot));
+ project()->setExtraProjectFiles(filesToWatch);
+
+ updateCppCodeModel();
+
+ m_makefileParserThread->deleteLater();
+ m_makefileParserThread = nullptr;
+}
+
+static QStringList filterIncludes(const QString &absSrc, const QString &absBuild,
+ const QStringList &in)
+{
+ QStringList result;
+ foreach (const QString i, in) {
+ QString out = i;
+ out.replace(QLatin1String("$(top_srcdir)"), absSrc);
+ out.replace(QLatin1String("$(abs_top_srcdir)"), absSrc);
+
+ out.replace(QLatin1String("$(top_builddir)"), absBuild);
+ out.replace(QLatin1String("$(abs_top_builddir)"), absBuild);
+
+ result << out;
+ }
+
+ return result;
+}
+
+void AutotoolsBuildSystem::updateCppCodeModel()
+{
+ QtSupport::CppKitInfo kitInfo(project());
+ QTC_ASSERT(kitInfo.isValid(), return );
+
+ const Utils::FilePath projectFilePath = project()->projectFilePath();
+
+ CppTools::RawProjectPart rpp;
+ rpp.setDisplayName(project()->displayName());
+ rpp.setProjectFileLocation(projectFilePath.toString());
+ rpp.setQtVersion(kitInfo.projectPartQtVersion);
+ const QStringList cflags = m_makefileParserThread->cflags();
+ QStringList cxxflags = m_makefileParserThread->cxxflags();
+ if (cxxflags.isEmpty())
+ cxxflags = cflags;
+ rpp.setFlagsForC({kitInfo.cToolChain, cflags});
+ rpp.setFlagsForCxx({kitInfo.cxxToolChain, cxxflags});
+
+ const QString absSrc = project()->projectDirectory().toString();
+ const Target *target = project()->activeTarget();
+ BuildConfiguration *bc = target ? target->activeBuildConfiguration() : nullptr;
+
+ const QString absBuild = bc ? bc->buildDirectory().toString() : QString();
+
+ rpp.setIncludePaths(filterIncludes(absSrc, absBuild, m_makefileParserThread->includePaths()));
+ rpp.setMacros(m_makefileParserThread->macros());
+ rpp.setFiles(m_files);
+
+ m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
+}
+
+} // namespace Internal
+} // namespace AutotoolsProjectManager