2016-01-15 14:57:40 +01:00
|
|
|
/****************************************************************************
|
2011-11-29 14:19:28 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 Openismus GmbH.
|
|
|
|
** Author: Peter Penz (ppenz@openismus.com)
|
|
|
|
** Author: Patricia Santana Cruz (patriciasantanacruz@gmail.com)
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-11-29 14:19:28 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2011-11-29 14:19:28 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** 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
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2011-11-29 14:19:28 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2011-11-29 14:19:28 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2011-11-29 14:19:28 +01:00
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
#include "autotoolsbuildsystem.h"
|
|
|
|
|
2011-11-29 14:19:28 +01:00
|
|
|
#include "makefileparserthread.h"
|
2019-08-13 12:47:11 +02:00
|
|
|
#include "makestep.h"
|
2011-11-29 14:19:28 +01:00
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
#include <cpptools/cppprojectupdater.h>
|
2011-11-29 14:19:28 +01:00
|
|
|
#include <projectexplorer/buildconfiguration.h>
|
2012-04-24 15:49:09 +02:00
|
|
|
#include <projectexplorer/target.h>
|
2019-01-04 12:35:28 +01:00
|
|
|
#include <qtsupport/qtcppkitinfo.h>
|
2019-08-13 12:47:11 +02:00
|
|
|
|
2012-07-25 09:48:48 +02:00
|
|
|
#include <utils/filesystemwatcher.h>
|
2011-11-29 14:19:28 +01:00
|
|
|
|
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
namespace AutotoolsProjectManager {
|
|
|
|
namespace Internal {
|
|
|
|
|
2019-10-25 09:55:32 +02:00
|
|
|
AutotoolsBuildSystem::AutotoolsBuildSystem(Target *target)
|
|
|
|
: BuildSystem(target)
|
2019-08-15 12:20:49 +02:00
|
|
|
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
2011-11-29 14:19:28 +01:00
|
|
|
{
|
2019-10-25 09:55:32 +02:00
|
|
|
connect(target, &Target::activeBuildConfigurationChanged, this, [this]() { requestParse(); });
|
2019-08-15 12:20:49 +02:00
|
|
|
|
2019-10-25 09:55:32 +02:00
|
|
|
connect(target->project(), &Project::projectFileIsDirty, this, [this]() { requestParse(); });
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
AutotoolsBuildSystem::~AutotoolsBuildSystem()
|
2011-11-29 14:19:28 +01:00
|
|
|
{
|
2017-02-06 16:59:53 +01:00
|
|
|
delete m_cppCodeModelUpdater;
|
|
|
|
|
2017-03-03 17:10:00 +01:00
|
|
|
if (m_makefileParserThread) {
|
2011-11-29 14:19:28 +01:00
|
|
|
m_makefileParserThread->wait();
|
|
|
|
delete m_makefileParserThread;
|
2017-03-03 17:10:00 +01:00
|
|
|
m_makefileParserThread = nullptr;
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-25 09:55:32 +02:00
|
|
|
void AutotoolsBuildSystem::triggerParsing()
|
2011-11-29 14:19:28 +01:00
|
|
|
{
|
2017-06-13 14:41:14 +02:00
|
|
|
if (m_makefileParserThread) {
|
2019-08-13 12:47:11 +02:00
|
|
|
// The thread is still busy parsing a previous configuration.
|
2011-11-29 14:19:28 +01:00
|
|
|
// Wait until the thread has been finished and delete it.
|
|
|
|
// TODO: Discuss whether blocking is acceptable.
|
2019-08-13 12:47:11 +02:00
|
|
|
disconnect(m_makefileParserThread,
|
|
|
|
&QThread::finished,
|
|
|
|
this,
|
|
|
|
&AutotoolsBuildSystem::makefileParsingFinished);
|
2011-11-29 14:19:28 +01:00
|
|
|
m_makefileParserThread->wait();
|
|
|
|
delete m_makefileParserThread;
|
2018-11-04 09:50:14 +01:00
|
|
|
m_makefileParserThread = nullptr;
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the makefile asynchronously in a thread
|
2019-10-25 09:55:32 +02:00
|
|
|
m_makefileParserThread = new MakefileParserThread(this);
|
2011-11-29 14:19:28 +01:00
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
connect(m_makefileParserThread,
|
|
|
|
&MakefileParserThread::finished,
|
|
|
|
this,
|
|
|
|
&AutotoolsBuildSystem::makefileParsingFinished);
|
2011-11-29 14:19:28 +01:00
|
|
|
m_makefileParserThread->start();
|
|
|
|
}
|
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
void AutotoolsBuildSystem::makefileParsingFinished()
|
2011-11-29 14:19:28 +01:00
|
|
|
{
|
|
|
|
// The finished() signal is from a previous makefile-parser-thread
|
|
|
|
// and can be skipped. This can happen, if the thread has emitted the
|
2019-08-13 12:47:11 +02:00
|
|
|
// finished() signal during the execution of AutotoolsBuildSystem::loadProjectTree().
|
2011-11-29 14:19:28 +01:00
|
|
|
// 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();
|
2017-06-13 14:41:14 +02:00
|
|
|
m_makefileParserThread = nullptr;
|
2011-11-29 14:19:28 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_makefileParserThread->hasError())
|
|
|
|
qWarning("Parsing of makefile contained errors.");
|
|
|
|
|
2019-01-16 16:07:00 +01:00
|
|
|
m_files.clear();
|
2019-08-15 12:20:49 +02:00
|
|
|
|
|
|
|
QVector<Utils::FilePath> filesToWatch;
|
2011-11-29 14:19:28 +01:00
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
// Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
|
2019-10-25 09:55:32 +02:00
|
|
|
const QFileInfo fileInfo = projectFilePath().toFileInfo();
|
2011-11-29 14:19:28 +01:00
|
|
|
const QDir dir = fileInfo.absoluteDir();
|
2017-06-13 14:41:14 +02:00
|
|
|
const QStringList files = m_makefileParserThread->sources();
|
2011-11-29 14:19:28 +01:00
|
|
|
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();
|
2011-11-30 15:08:34 +01:00
|
|
|
foreach (const QString &makefile, makefiles) {
|
2017-06-13 14:41:14 +02:00
|
|
|
const QString absMakefile = dir.absoluteFilePath(makefile);
|
2011-11-29 14:19:28 +01:00
|
|
|
|
2017-06-13 14:41:14 +02:00
|
|
|
m_files.append(absMakefile);
|
|
|
|
|
2019-08-15 12:20:49 +02:00
|
|
|
filesToWatch.append(Utils::FilePath::fromString(absMakefile));
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
|
|
|
|
2011-11-30 15:08:34 +01:00
|
|
|
// Add configure.ac file to project and watch for changes.
|
2011-11-29 14:19:28 +01:00
|
|
|
const QLatin1String configureAc(QLatin1String("configure.ac"));
|
2012-04-03 11:53:55 +02:00
|
|
|
const QFile configureAcFile(fileInfo.absolutePath() + QLatin1Char('/') + configureAc);
|
2011-11-29 14:19:28 +01:00
|
|
|
if (configureAcFile.exists()) {
|
2017-06-13 14:41:14 +02:00
|
|
|
const QString absConfigureAc = dir.absoluteFilePath(configureAc);
|
|
|
|
m_files.append(absConfigureAc);
|
|
|
|
|
2019-08-15 12:20:49 +02:00
|
|
|
filesToWatch.append(Utils::FilePath::fromString(absConfigureAc));
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
auto newRoot = std::make_unique<ProjectNode>(project()->projectDirectory());
|
2017-06-13 14:41:14 +02:00
|
|
|
for (const QString &f : m_files) {
|
2019-05-28 13:49:26 +02:00
|
|
|
const Utils::FilePath path = Utils::FilePath::fromString(f);
|
2019-02-25 12:08:58 +01:00
|
|
|
newRoot->addNestedNode(std::make_unique<FileNode>(path,
|
|
|
|
FileNode::fileTypeForFileName(path)));
|
2017-03-10 17:30:40 +01:00
|
|
|
}
|
2019-08-13 12:47:11 +02:00
|
|
|
project()->setRootProjectNode(std::move(newRoot));
|
|
|
|
project()->setExtraProjectFiles(filesToWatch);
|
2016-09-30 21:10:32 +02:00
|
|
|
|
2011-11-29 14:19:28 +01:00
|
|
|
updateCppCodeModel();
|
|
|
|
|
|
|
|
m_makefileParserThread->deleteLater();
|
2017-06-13 14:41:14 +02:00
|
|
|
m_makefileParserThread = nullptr;
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
|
|
|
|
2015-07-09 01:28:04 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
void AutotoolsBuildSystem::updateCppCodeModel()
|
2011-11-29 14:19:28 +01:00
|
|
|
{
|
2019-11-20 12:12:53 +01:00
|
|
|
QtSupport::CppKitInfo kitInfo(kit());
|
2019-08-13 12:47:11 +02:00
|
|
|
QTC_ASSERT(kitInfo.isValid(), return );
|
|
|
|
|
|
|
|
const Utils::FilePath projectFilePath = project()->projectFilePath();
|
2011-11-29 14:19:28 +01:00
|
|
|
|
2019-08-28 18:22:45 +02:00
|
|
|
RawProjectPart rpp;
|
2019-08-13 12:47:11 +02:00
|
|
|
rpp.setDisplayName(project()->displayName());
|
|
|
|
rpp.setProjectFileLocation(projectFilePath.toString());
|
2019-01-04 12:35:28 +01:00
|
|
|
rpp.setQtVersion(kitInfo.projectPartQtVersion);
|
2013-04-29 02:31:43 +04:00
|
|
|
const QStringList cflags = m_makefileParserThread->cflags();
|
|
|
|
QStringList cxxflags = m_makefileParserThread->cxxflags();
|
|
|
|
if (cxxflags.isEmpty())
|
|
|
|
cxxflags = cflags;
|
2019-01-04 12:35:28 +01:00
|
|
|
rpp.setFlagsForC({kitInfo.cToolChain, cflags});
|
|
|
|
rpp.setFlagsForCxx({kitInfo.cxxToolChain, cxxflags});
|
2012-04-24 15:49:09 +02:00
|
|
|
|
2019-08-13 12:47:11 +02:00
|
|
|
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();
|
2015-07-09 01:28:04 +02:00
|
|
|
|
2017-02-06 16:59:53 +01:00
|
|
|
rpp.setIncludePaths(filterIncludes(absSrc, absBuild, m_makefileParserThread->includePaths()));
|
2017-02-07 15:00:38 +01:00
|
|
|
rpp.setMacros(m_makefileParserThread->macros());
|
2017-02-06 16:59:53 +01:00
|
|
|
rpp.setFiles(m_files);
|
2013-04-28 19:24:49 +04:00
|
|
|
|
2019-10-25 09:55:32 +02:00
|
|
|
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {rpp}});
|
2011-11-29 14:19:28 +01:00
|
|
|
}
|
2019-08-13 12:47:11 +02:00
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
} // namespace AutotoolsProjectManager
|