diff options
author | Tobias Hunger <tobias.hunger@qt.io> | 2019-08-13 12:47:11 +0200 |
---|---|---|
committer | Tobias Hunger <tobias.hunger@qt.io> | 2019-08-29 07:28:26 +0000 |
commit | fb21b78444fa2ff18fecaf45db36bd72b3dfe734 (patch) | |
tree | fd33b814e925bd748579b7222cfcfc2120ae409c /src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp | |
parent | b7e4046a173a2c42ede92934cc05c0f76486db5e (diff) | |
download | qt-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.cpp | 209 |
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 |