forked from qt-creator/qt-creator
Clang: Add Process Generator
So far we only compiled the precompiled headers only sequentially. The process generator is creating, managing a queue of processes to compile the PCHs parallel. Change-Id: I8075def4ef9e6b0191bbd51b3631d1c51ec7b361 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
#include <connectionserver.h>
|
#include <connectionserver.h>
|
||||||
#include <environment.h>
|
#include <environment.h>
|
||||||
#include <pchcreator.h>
|
#include <pchcreator.h>
|
||||||
|
#include <pchgenerator.h>
|
||||||
#include <pchmanagerserver.h>
|
#include <pchmanagerserver.h>
|
||||||
#include <pchmanagerclientproxy.h>
|
#include <pchmanagerclientproxy.h>
|
||||||
#include <projectparts.h>
|
#include <projectparts.h>
|
||||||
@@ -36,12 +37,16 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QProcess>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
using ClangBackEnd::ClangPathWatcher;
|
using ClangBackEnd::ClangPathWatcher;
|
||||||
using ClangBackEnd::ConnectionServer;
|
using ClangBackEnd::ConnectionServer;
|
||||||
using ClangBackEnd::PchCreator;
|
using ClangBackEnd::PchCreator;
|
||||||
|
using ClangBackEnd::PchGenerator;
|
||||||
using ClangBackEnd::PchManagerClientProxy;
|
using ClangBackEnd::PchManagerClientProxy;
|
||||||
using ClangBackEnd::PchManagerServer;
|
using ClangBackEnd::PchManagerServer;
|
||||||
using ClangBackEnd::ProjectParts;
|
using ClangBackEnd::ProjectParts;
|
||||||
@@ -60,6 +65,11 @@ public:
|
|||||||
return QString(CLANG_COMPILER_PATH);
|
return QString(CLANG_COMPILER_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint hardwareConcurrency() const
|
||||||
|
{
|
||||||
|
return std::thread::hardware_concurrency();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTemporaryDir temporaryDirectory;
|
QTemporaryDir temporaryDirectory;
|
||||||
};
|
};
|
||||||
@@ -96,13 +106,17 @@ int main(int argc, char *argv[])
|
|||||||
StringCache<Utils::SmallString> filePathCache;
|
StringCache<Utils::SmallString> filePathCache;
|
||||||
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache);
|
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache);
|
||||||
ApplicationEnvironment environment;
|
ApplicationEnvironment environment;
|
||||||
|
PchGenerator<QProcess> pchGenerator(environment);
|
||||||
PchCreator pchCreator(environment, filePathCache);
|
PchCreator pchCreator(environment, filePathCache);
|
||||||
|
pchCreator.setGenerator(&pchGenerator);
|
||||||
ProjectParts projectParts;
|
ProjectParts projectParts;
|
||||||
PchManagerServer clangPchManagerServer(filePathCache,
|
PchManagerServer clangPchManagerServer(filePathCache,
|
||||||
includeWatcher,
|
includeWatcher,
|
||||||
pchCreator,
|
pchCreator,
|
||||||
projectParts);
|
projectParts);
|
||||||
includeWatcher.setNotifier(&clangPchManagerServer);
|
includeWatcher.setNotifier(&clangPchManagerServer);
|
||||||
|
pchGenerator.setNotifier(&clangPchManagerServer);
|
||||||
|
|
||||||
ConnectionServer<PchManagerServer, PchManagerClientProxy> connectionServer(connection);
|
ConnectionServer<PchManagerServer, PchManagerClientProxy> connectionServer(connection);
|
||||||
connectionServer.start();
|
connectionServer.start();
|
||||||
connectionServer.setServer(&clangPchManagerServer);
|
connectionServer.setServer(&clangPchManagerServer);
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ SOURCES += \
|
|||||||
$$PWD/pchcreatorinterface.cpp \
|
$$PWD/pchcreatorinterface.cpp \
|
||||||
$$PWD/clangpathwatcherinterface.cpp \
|
$$PWD/clangpathwatcherinterface.cpp \
|
||||||
$$PWD/projectpartsinterface.cpp \
|
$$PWD/projectpartsinterface.cpp \
|
||||||
$$PWD/clangpathwatchernotifier.cpp
|
$$PWD/clangpathwatchernotifier.cpp \
|
||||||
|
$$PWD/pchgeneratornotifierinterface.cpp \
|
||||||
|
$$PWD/pchgeneratorinterface.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/clangpchmanagerbackend_global.h \
|
$$PWD/clangpchmanagerbackend_global.h \
|
||||||
@@ -30,4 +32,7 @@ HEADERS += \
|
|||||||
$$PWD/clangpathwatcherinterface.h \
|
$$PWD/clangpathwatcherinterface.h \
|
||||||
$$PWD/projectpartsinterface.h \
|
$$PWD/projectpartsinterface.h \
|
||||||
$$PWD/clangpathwatchernotifier.h \
|
$$PWD/clangpathwatchernotifier.h \
|
||||||
$$PWD/changedfilepathcompressor.h
|
$$PWD/changedfilepathcompressor.h \
|
||||||
|
$$PWD/pchgenerator.h \
|
||||||
|
$$PWD/pchgeneratornotifierinterface.h \
|
||||||
|
$$PWD/pchgeneratorinterface.h
|
||||||
|
|||||||
@@ -64,16 +64,18 @@ public:
|
|||||||
llvm::StringRef /*relativePath*/,
|
llvm::StringRef /*relativePath*/,
|
||||||
const clang::Module */*imported*/) override
|
const clang::Module */*imported*/) override
|
||||||
{
|
{
|
||||||
auto fileUID = file->getUID();
|
if (file) {
|
||||||
|
auto fileUID = file->getUID();
|
||||||
|
|
||||||
flagIncludeAlreadyRead(file);
|
flagIncludeAlreadyRead(file);
|
||||||
|
|
||||||
if (isNotInExcludedIncludeUID(fileUID)) {
|
if (isNotInExcludedIncludeUID(fileUID)) {
|
||||||
auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
|
auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
|
||||||
if (notAlreadyIncluded.first) {
|
if (notAlreadyIncluded.first) {
|
||||||
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
|
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
|
||||||
uint includeId = m_filePathCache.stringId({fileName.data(), fileName.size()});
|
uint includeId = m_filePathCache.stringId({fileName.data(), fileName.size()});
|
||||||
m_includeIds.emplace_back(includeId);
|
m_includeIds.emplace_back(includeId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class Environment
|
|||||||
public:
|
public:
|
||||||
virtual QString pchBuildDirectory() const = 0;
|
virtual QString pchBuildDirectory() const = 0;
|
||||||
virtual QString clangCompilerPath() const = 0;
|
virtual QString clangCompilerPath() const = 0;
|
||||||
|
virtual uint hardwareConcurrency() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
@@ -45,10 +44,12 @@ PchCreator::PchCreator(Environment &environment, StringCache<Utils::SmallString>
|
|||||||
|
|
||||||
PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
|
PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
|
||||||
Environment &environment,
|
Environment &environment,
|
||||||
StringCache<Utils::SmallString> &filePathCache)
|
StringCache<Utils::SmallString> &filePathCache,
|
||||||
|
PchGeneratorInterface *pchGenerator)
|
||||||
: m_projectParts(std::move(projectsParts)),
|
: m_projectParts(std::move(projectsParts)),
|
||||||
m_environment(environment),
|
m_environment(environment),
|
||||||
m_filePathCache(filePathCache)
|
m_filePathCache(filePathCache),
|
||||||
|
m_pchGenerator(pchGenerator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,23 +259,17 @@ std::unique_ptr<QFile> PchCreator::generateGlobalPchHeaderFile()
|
|||||||
generateGlobalPchHeaderFileContent());
|
generateGlobalPchHeaderFileContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchCreator::generatePch(const Utils::SmallStringVector &clangCompilerArguments)
|
void PchCreator::generatePch(Utils::SmallStringVector &&compilerArguments,
|
||||||
|
ProjectPartPch &&projectPartPch)
|
||||||
{
|
{
|
||||||
QProcess process;
|
m_pchGenerator->startTask(std::move(compilerArguments), std::move(projectPartPch));
|
||||||
process.setProcessChannelMode(QProcess::ForwardedChannels);
|
|
||||||
|
|
||||||
process.start(m_environment.clangCompilerPath(),
|
|
||||||
convertToQStringList(clangCompilerArguments));
|
|
||||||
process.waitForFinished(100000);
|
|
||||||
|
|
||||||
checkIfProcessHasError(process);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchCreator::generateGlobalPch()
|
void PchCreator::generateGlobalPch()
|
||||||
{
|
{
|
||||||
generateGlobalPchHeaderFile();
|
generateGlobalPchHeaderFile();
|
||||||
|
|
||||||
generatePch(generateGlobalClangCompilerArguments());
|
generatePch(generateGlobalClangCompilerArguments(), ProjectPartPch());
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList PchCreator::convertToQStringList(const Utils::SmallStringVector &compilerArguments)
|
QStringList PchCreator::convertToQStringList(const Utils::SmallStringVector &compilerArguments)
|
||||||
@@ -310,14 +305,6 @@ QByteArray PchCreator::globalProjectHash() const
|
|||||||
return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchCreator::checkIfProcessHasError(const QProcess &process)
|
|
||||||
{
|
|
||||||
if (process.exitCode()) {
|
|
||||||
const std::string errorString = process.errorString().toStdString();
|
|
||||||
throw PchNotCreatedError(errorString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::SmallString PchCreator::generateGlobalPchFilePathWithoutExtension() const
|
Utils::SmallString PchCreator::generateGlobalPchFilePathWithoutExtension() const
|
||||||
{
|
{
|
||||||
QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
|
QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
|
||||||
@@ -449,27 +436,25 @@ Utils::SmallStringVector PchCreator::generateProjectPartClangCompilerArguments(
|
|||||||
return compilerArguments;
|
return compilerArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ProjectPartPch, IdPaths> PchCreator::generateProjectPartPch(
|
IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &projectPart)
|
||||||
const V2::ProjectPartContainer &projectPart)
|
|
||||||
{
|
{
|
||||||
auto includes = generateProjectPartPchIncludes(projectPart);
|
auto includes = generateProjectPartPchIncludes(projectPart);
|
||||||
auto content = generatePchIncludeFileContent(includes);
|
auto content = generatePchIncludeFileContent(includes);
|
||||||
auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart);
|
auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart);
|
||||||
auto pchFilePath = generateProjectPartPchFilePath(projectPart);
|
auto pchFilePath = generateProjectPartPchFilePath(projectPart);
|
||||||
auto file = generatePchHeaderFile(pchIncludeFilePath, content);
|
generatePchHeaderFile(pchIncludeFilePath, content);
|
||||||
|
|
||||||
generatePch(generateProjectPartClangCompilerArguments(projectPart));
|
generatePch(generateProjectPartClangCompilerArguments(projectPart),
|
||||||
|
{projectPart.projectPartId().clone(), std::move(pchFilePath)});
|
||||||
|
|
||||||
return {{projectPart.projectPartId().clone(), std::move(pchFilePath)},
|
return {projectPart.projectPartId().clone(), std::move(includes)};
|
||||||
{projectPart.projectPartId().clone(), includes}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchCreator::generatePchs()
|
void PchCreator::generatePchs()
|
||||||
{
|
{
|
||||||
for (const V2::ProjectPartContainer &projectPart : m_projectParts) {
|
for (const V2::ProjectPartContainer &projectPart : m_projectParts) {
|
||||||
auto projectInfos = generateProjectPartPch(projectPart);
|
auto includePaths = generateProjectPartPch(projectPart);
|
||||||
m_projectPartPchs.push_back(projectInfos.first);
|
m_projectsIncludeIds.push_back(std::move(includePaths));
|
||||||
m_projectsIncludeIds.push_back(projectInfos.second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,16 +465,16 @@ void PchCreator::generatePchs(V2::ProjectPartContainers &&projectsParts)
|
|||||||
generatePchs();
|
generatePchs();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ProjectPartPch> PchCreator::takeProjectPartPchs()
|
|
||||||
{
|
|
||||||
return std::move(m_projectPartPchs);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<IdPaths> PchCreator::takeProjectsIncludes()
|
std::vector<IdPaths> PchCreator::takeProjectsIncludes()
|
||||||
{
|
{
|
||||||
return std::move(m_projectsIncludeIds);
|
return std::move(m_projectsIncludeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PchCreator::setGenerator(PchGeneratorInterface *pchGenerator)
|
||||||
|
{
|
||||||
|
m_pchGenerator = pchGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<QFile> PchCreator::generatePchHeaderFile(
|
std::unique_ptr<QFile> PchCreator::generatePchHeaderFile(
|
||||||
const Utils::SmallString &filePath,
|
const Utils::SmallString &filePath,
|
||||||
const Utils::SmallString &content)
|
const Utils::SmallString &content)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "pchcreatorinterface.h"
|
#include "pchcreatorinterface.h"
|
||||||
|
|
||||||
|
#include "pchgeneratorinterface.h"
|
||||||
#include "stringcache.h"
|
#include "stringcache.h"
|
||||||
#include "idpaths.h"
|
#include "idpaths.h"
|
||||||
|
|
||||||
@@ -50,12 +51,14 @@ public:
|
|||||||
StringCache<Utils::SmallString> &filePathCache);
|
StringCache<Utils::SmallString> &filePathCache);
|
||||||
PchCreator(V2::ProjectPartContainers &&projectsParts,
|
PchCreator(V2::ProjectPartContainers &&projectsParts,
|
||||||
Environment &environment,
|
Environment &environment,
|
||||||
StringCache<Utils::SmallString> &filePathCache);
|
StringCache<Utils::SmallString> &filePathCache,
|
||||||
|
PchGeneratorInterface *pchGenerator);
|
||||||
|
|
||||||
void generatePchs(V2::ProjectPartContainers &&projectsParts) override;
|
void generatePchs(V2::ProjectPartContainers &&projectsParts) override;
|
||||||
std::vector<ProjectPartPch> takeProjectPartPchs() override;
|
|
||||||
std::vector<IdPaths> takeProjectsIncludes() override;
|
std::vector<IdPaths> takeProjectsIncludes() override;
|
||||||
|
|
||||||
|
void setGenerator(PchGeneratorInterface *pchGenerator);
|
||||||
|
|
||||||
unitttest_public:
|
unitttest_public:
|
||||||
Utils::SmallStringVector generateGlobalHeaderPaths() const;
|
Utils::SmallStringVector generateGlobalHeaderPaths() const;
|
||||||
Utils::SmallStringVector generateGlobalSourcePaths() const;
|
Utils::SmallStringVector generateGlobalSourcePaths() const;
|
||||||
@@ -70,7 +73,8 @@ unitttest_public:
|
|||||||
Utils::SmallString generatePchIncludeFileContent(const std::vector<uint> &includeIds) const;
|
Utils::SmallString generatePchIncludeFileContent(const std::vector<uint> &includeIds) const;
|
||||||
Utils::SmallString generateGlobalPchHeaderFileContent() const;
|
Utils::SmallString generateGlobalPchHeaderFileContent() const;
|
||||||
std::unique_ptr<QFile> generateGlobalPchHeaderFile();
|
std::unique_ptr<QFile> generateGlobalPchHeaderFile();
|
||||||
void generatePch(const Utils::SmallStringVector &commandLineArguments);
|
void generatePch(Utils::SmallStringVector &&commandLineArguments,
|
||||||
|
ProjectPartPch &&projectPartPch);
|
||||||
void generateGlobalPch();
|
void generateGlobalPch();
|
||||||
|
|
||||||
Utils::SmallString globalPchContent() const;
|
Utils::SmallString globalPchContent() const;
|
||||||
@@ -97,7 +101,7 @@ unitttest_public:
|
|||||||
const V2::ProjectPartContainer &projectPart) const;
|
const V2::ProjectPartContainer &projectPart) const;
|
||||||
Utils::SmallStringVector generateProjectPartClangCompilerArguments(
|
Utils::SmallStringVector generateProjectPartClangCompilerArguments(
|
||||||
const V2::ProjectPartContainer &projectPart) const;
|
const V2::ProjectPartContainer &projectPart) const;
|
||||||
std::pair<ProjectPartPch, IdPaths> generateProjectPartPch(
|
IdPaths generateProjectPartPch(
|
||||||
const V2::ProjectPartContainer &projectPart);
|
const V2::ProjectPartContainer &projectPart);
|
||||||
static std::unique_ptr<QFile> generatePchHeaderFile(
|
static std::unique_ptr<QFile> generatePchHeaderFile(
|
||||||
const Utils::SmallString &filePath,
|
const Utils::SmallString &filePath,
|
||||||
@@ -108,7 +112,6 @@ unitttest_public:
|
|||||||
private:
|
private:
|
||||||
static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart);
|
static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart);
|
||||||
QByteArray globalProjectHash() const;
|
QByteArray globalProjectHash() const;
|
||||||
static void checkIfProcessHasError(const QProcess &process);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
V2::ProjectPartContainers m_projectParts;
|
V2::ProjectPartContainers m_projectParts;
|
||||||
@@ -116,6 +119,7 @@ private:
|
|||||||
std::vector<IdPaths> m_projectsIncludeIds;
|
std::vector<IdPaths> m_projectsIncludeIds;
|
||||||
Environment &m_environment;
|
Environment &m_environment;
|
||||||
StringCache<Utils::SmallString> &m_filePathCache;
|
StringCache<Utils::SmallString> &m_filePathCache;
|
||||||
|
PchGeneratorInterface *m_pchGenerator = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ public:
|
|||||||
virtual ~PchCreatorInterface();
|
virtual ~PchCreatorInterface();
|
||||||
|
|
||||||
virtual void generatePchs(V2::ProjectPartContainers &&projectsParts) = 0;
|
virtual void generatePchs(V2::ProjectPartContainers &&projectsParts) = 0;
|
||||||
virtual std::vector<ProjectPartPch> takeProjectPartPchs() = 0;
|
|
||||||
virtual std::vector<IdPaths> takeProjectsIncludes() = 0;
|
virtual std::vector<IdPaths> takeProjectsIncludes() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
165
src/tools/clangpchmanagerbackend/source/pchgenerator.h
Normal file
165
src/tools/clangpchmanagerbackend/source/pchgenerator.h
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "environment.h"
|
||||||
|
#include "pchgeneratorinterface.h"
|
||||||
|
#include "pchgeneratornotifierinterface.h"
|
||||||
|
|
||||||
|
#include <projectpartpch.h>
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
template <typename Process>
|
||||||
|
class PchGenerator final : public PchGeneratorInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PchGenerator(Environment &environment,
|
||||||
|
PchGeneratorNotifierInterface *notifier=nullptr)
|
||||||
|
: m_environment(environment),
|
||||||
|
m_notifier(notifier)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~PchGenerator()
|
||||||
|
{
|
||||||
|
cleanupAllProcesses();
|
||||||
|
}
|
||||||
|
|
||||||
|
void startTask(Utils::SmallStringVector &&compilerArguments, ProjectPartPch &&projectPartPch) override
|
||||||
|
{
|
||||||
|
addTask(std::move(compilerArguments), std::move(projectPartPch));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNotifier(PchGeneratorNotifierInterface *notifier)
|
||||||
|
{
|
||||||
|
m_notifier = notifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
unitttest_public:
|
||||||
|
Process *addTask(Utils::SmallStringVector &&compilerArguments, ProjectPartPch &&projectPartPch)
|
||||||
|
{
|
||||||
|
auto process = std::make_unique<Process>();
|
||||||
|
Process *processPointer = process.get();
|
||||||
|
|
||||||
|
process->setProcessChannelMode(QProcess::ForwardedChannels);
|
||||||
|
process->setArguments(compilerArguments);
|
||||||
|
process->setProgram(m_environment.clangCompilerPath());
|
||||||
|
|
||||||
|
connectProcess(processPointer, std::move(projectPartPch));
|
||||||
|
|
||||||
|
if (!deferProcess())
|
||||||
|
startProcess(std::move(process));
|
||||||
|
else
|
||||||
|
m_deferredProcesses.push(std::move(process));
|
||||||
|
|
||||||
|
return processPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connectProcess(Process *process, ProjectPartPch &&projectPartPch)
|
||||||
|
{
|
||||||
|
auto finishedCallback = [=,projectPartPch=std::move(projectPartPch)] (int exitCode, QProcess::ExitStatus exitStatus) {
|
||||||
|
deleteProcess(process);
|
||||||
|
activateNextDeferredProcess();
|
||||||
|
m_notifier->taskFinished(generateTaskFinishStatus(exitCode, exitStatus), projectPartPch);
|
||||||
|
};
|
||||||
|
|
||||||
|
QObject::connect(process,
|
||||||
|
static_cast<void (Process::*)(int, QProcess::ExitStatus)>(&Process::finished),
|
||||||
|
std::move(finishedCallback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void startProcess(std::unique_ptr<Process> &&process)
|
||||||
|
{
|
||||||
|
process->start();
|
||||||
|
m_runningProcesses.push_back(std::move(process));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::unique_ptr<Process>> &runningProcesses() const
|
||||||
|
{
|
||||||
|
return m_runningProcesses;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::queue<std::unique_ptr<Process>> &deferredProcesses() const
|
||||||
|
{
|
||||||
|
return m_deferredProcesses;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteProcess(Process *process)
|
||||||
|
{
|
||||||
|
auto found = std::find_if(m_runningProcesses.begin(),
|
||||||
|
m_runningProcesses.end(),
|
||||||
|
[=] (const std::unique_ptr<Process> &entry) {
|
||||||
|
return entry.get() == process;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (found != m_runningProcesses.end()) {
|
||||||
|
std::unique_ptr<Process> avoidDoubleDeletedProcess = std::move(*found);
|
||||||
|
m_runningProcesses.erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanupAllProcesses()
|
||||||
|
{
|
||||||
|
std::vector<std::unique_ptr<Process>> runningProcesses = std::move(m_runningProcesses);
|
||||||
|
std::queue<std::unique_ptr<Process>> deferredProcesses = std::move(m_deferredProcesses);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TaskFinishStatus generateTaskFinishStatus(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
{
|
||||||
|
if (exitCode != 0 || exitStatus != QProcess::NormalExit)
|
||||||
|
return TaskFinishStatus::Unsuccessfully;
|
||||||
|
else
|
||||||
|
return TaskFinishStatus::Successfully;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deferProcess() const
|
||||||
|
{
|
||||||
|
return m_environment.hardwareConcurrency() <= m_runningProcesses.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void activateNextDeferredProcess()
|
||||||
|
{
|
||||||
|
if (!m_deferredProcesses.empty()) {
|
||||||
|
std::unique_ptr<Process> process = std::move(m_deferredProcesses.front());
|
||||||
|
m_deferredProcesses.pop();
|
||||||
|
|
||||||
|
startProcess(std::move(process));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<Process>> m_runningProcesses;
|
||||||
|
std::queue<std::unique_ptr<Process>> m_deferredProcesses;
|
||||||
|
Environment &m_environment;
|
||||||
|
PchGeneratorNotifierInterface *m_notifier=nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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 "pchgeneratorinterface.h"
|
||||||
|
|
||||||
|
ClangBackEnd::PchGeneratorInterface::~PchGeneratorInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/smallstringvector.h>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class ProjectPartPch;
|
||||||
|
|
||||||
|
class PchGeneratorInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~PchGeneratorInterface();
|
||||||
|
|
||||||
|
virtual void startTask(Utils::SmallStringVector &&compilerArguments,
|
||||||
|
ProjectPartPch &&projectPartPch) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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 "pchgeneratornotifierinterface.h"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
PchGeneratorNotifierInterface::~PchGeneratorNotifierInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, TaskFinishStatus status)
|
||||||
|
{
|
||||||
|
enum class TaskFinishStatus
|
||||||
|
{
|
||||||
|
Successfully,
|
||||||
|
Unsuccessfully
|
||||||
|
};
|
||||||
|
|
||||||
|
if (status == ClangBackEnd::TaskFinishStatus::Successfully)
|
||||||
|
out << "Successfully";
|
||||||
|
else
|
||||||
|
out << "Unsuccessfully";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
|
class ProjectPartPch;
|
||||||
|
|
||||||
|
enum class TaskFinishStatus
|
||||||
|
{
|
||||||
|
Successfully,
|
||||||
|
Unsuccessfully
|
||||||
|
};
|
||||||
|
|
||||||
|
class PchGeneratorNotifierInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~PchGeneratorNotifierInterface();
|
||||||
|
|
||||||
|
virtual void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, TaskFinishStatus status);
|
||||||
|
|
||||||
|
} // namespace ClangBackEnd
|
||||||
@@ -58,8 +58,6 @@ void PchManagerServer::updatePchProjectParts(UpdatePchProjectPartsMessage &&mess
|
|||||||
{
|
{
|
||||||
m_pchCreator.generatePchs(m_projectParts.update(message.takeProjectsParts()));
|
m_pchCreator.generatePchs(m_projectParts.update(message.takeProjectsParts()));
|
||||||
|
|
||||||
client()->precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage(m_pchCreator.takeProjectPartPchs()));
|
|
||||||
|
|
||||||
m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
|
m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +72,13 @@ void PchManagerServer::pathsWithIdsChanged(const Utils::SmallStringVector &ids)
|
|||||||
{
|
{
|
||||||
m_pchCreator.generatePchs(m_projectParts.projects(ids));
|
m_pchCreator.generatePchs(m_projectParts.projects(ids));
|
||||||
|
|
||||||
client()->precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage(m_pchCreator.takeProjectPartPchs()));
|
|
||||||
|
|
||||||
m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
|
m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PchManagerServer::taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch)
|
||||||
|
{
|
||||||
|
if (status == TaskFinishStatus::Successfully)
|
||||||
|
client()->precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage({projectPartPch.clone()}));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "clangpathwatcherinterface.h"
|
#include "clangpathwatcherinterface.h"
|
||||||
#include "clangpathwatchernotifier.h"
|
#include "clangpathwatchernotifier.h"
|
||||||
#include "pchcreatorinterface.h"
|
#include "pchcreatorinterface.h"
|
||||||
|
#include "pchgeneratornotifierinterface.h"
|
||||||
#include "pchmanagerserverinterface.h"
|
#include "pchmanagerserverinterface.h"
|
||||||
#include "projectpartsinterface.h"
|
#include "projectpartsinterface.h"
|
||||||
#include "stringcache.h"
|
#include "stringcache.h"
|
||||||
@@ -36,7 +37,9 @@ namespace ClangBackEnd {
|
|||||||
|
|
||||||
class SourceRangesAndDiagnosticsForQueryMessage;
|
class SourceRangesAndDiagnosticsForQueryMessage;
|
||||||
|
|
||||||
class PchManagerServer : public PchManagerServerInterface, public ClangPathWatcherNotifier
|
class PchManagerServer : public PchManagerServerInterface,
|
||||||
|
public ClangPathWatcherNotifier,
|
||||||
|
public PchGeneratorNotifierInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PchManagerServer(StringCache<Utils::SmallString> &filePathCache,
|
PchManagerServer(StringCache<Utils::SmallString> &filePathCache,
|
||||||
@@ -50,6 +53,7 @@ public:
|
|||||||
void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
|
void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
|
||||||
|
|
||||||
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
|
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
|
||||||
|
void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringCache<Utils::SmallString> &m_filePathCache;
|
StringCache<Utils::SmallString> &m_filePathCache;
|
||||||
|
|||||||
88
tests/unit/unittest/fakeprocess.cpp
Normal file
88
tests/unit/unittest/fakeprocess.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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 "fakeprocess.h"
|
||||||
|
|
||||||
|
FakeProcess::FakeProcess()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeProcess::~FakeProcess()
|
||||||
|
{
|
||||||
|
if (m_isStarted && !m_isFinished)
|
||||||
|
emit finished(0, QProcess::NormalExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::finishUnsuccessfully()
|
||||||
|
{
|
||||||
|
m_isFinished = true;
|
||||||
|
emit finished(1, QProcess::NormalExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::finishByCrash()
|
||||||
|
{
|
||||||
|
m_isFinished = true;
|
||||||
|
emit finished(0, QProcess::CrashExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::finish()
|
||||||
|
{
|
||||||
|
m_isFinished = true;
|
||||||
|
emit finished(0, QProcess::NormalExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::setArguments(const QStringList &arguments)
|
||||||
|
{
|
||||||
|
m_arguments = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::setProgram(const QString &program)
|
||||||
|
{
|
||||||
|
m_applicationPath = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::setProcessChannelMode(QProcess::ProcessChannelMode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeProcess::start()
|
||||||
|
{
|
||||||
|
m_isStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FakeProcess::isStarted() const
|
||||||
|
{
|
||||||
|
return m_isStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QStringList &FakeProcess::arguments() const
|
||||||
|
{
|
||||||
|
return m_arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &FakeProcess::applicationPath() const
|
||||||
|
{
|
||||||
|
return m_applicationPath;
|
||||||
|
}
|
||||||
62
tests/unit/unittest/fakeprocess.h
Normal file
62
tests/unit/unittest/fakeprocess.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
class FakeProcess : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FakeProcess();
|
||||||
|
~FakeProcess();
|
||||||
|
|
||||||
|
void finishUnsuccessfully();
|
||||||
|
void finishByCrash();
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void setArguments(const QStringList &arguments);
|
||||||
|
void setProgram(const QString &program);
|
||||||
|
|
||||||
|
void setProcessChannelMode(QProcess::ProcessChannelMode mode);
|
||||||
|
|
||||||
|
|
||||||
|
bool isStarted() const;
|
||||||
|
|
||||||
|
const QStringList &arguments() const;
|
||||||
|
const QString &applicationPath() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList m_arguments;
|
||||||
|
QString m_applicationPath;
|
||||||
|
bool m_isFinished = false;
|
||||||
|
bool m_isStarted = false;
|
||||||
|
};
|
||||||
@@ -36,8 +36,6 @@ class MockPchCreator : public ClangBackEnd::PchCreatorInterface
|
|||||||
public:
|
public:
|
||||||
MOCK_METHOD1(generatePchs,
|
MOCK_METHOD1(generatePchs,
|
||||||
void(const std::vector<ClangBackEnd::V2::ProjectPartContainer> &projectParts));
|
void(const std::vector<ClangBackEnd::V2::ProjectPartContainer> &projectParts));
|
||||||
MOCK_METHOD0(takeProjectPartPchs,
|
|
||||||
std::vector<ClangBackEnd::ProjectPartPch>());
|
|
||||||
MOCK_METHOD0(takeProjectsIncludes,
|
MOCK_METHOD0(takeProjectsIncludes,
|
||||||
std::vector<ClangBackEnd::IdPaths>());
|
std::vector<ClangBackEnd::IdPaths>());
|
||||||
|
|
||||||
|
|||||||
38
tests/unit/unittest/mockpchgeneratornotifier.h
Normal file
38
tests/unit/unittest/mockpchgeneratornotifier.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "googletest.h"
|
||||||
|
|
||||||
|
#include <pchgeneratornotifierinterface.h>
|
||||||
|
|
||||||
|
class MockPchGeneratorNotifier : public ClangBackEnd::PchGeneratorNotifierInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MOCK_METHOD2(taskFinished,
|
||||||
|
void (ClangBackEnd::TaskFinishStatus status,
|
||||||
|
const ClangBackEnd::ProjectPartPch &projectPartPch));
|
||||||
|
};
|
||||||
@@ -25,9 +25,12 @@
|
|||||||
|
|
||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
|
||||||
|
#include "fakeprocess.h"
|
||||||
|
#include "mockpchgeneratornotifier.h"
|
||||||
#include "testenvironment.h"
|
#include "testenvironment.h"
|
||||||
|
|
||||||
#include <pchcreator.h>
|
#include <pchcreator.h>
|
||||||
|
#include <pchgenerator.h>
|
||||||
#include <stringcache.h>
|
#include <stringcache.h>
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@@ -70,9 +73,12 @@ protected:
|
|||||||
{header2Path.clone()},
|
{header2Path.clone()},
|
||||||
{main2Path.clone()}};
|
{main2Path.clone()}};
|
||||||
TestEnvironment environment;
|
TestEnvironment environment;
|
||||||
|
NiceMock<MockPchGeneratorNotifier> mockPchGeneratorNotifier;
|
||||||
|
ClangBackEnd::PchGenerator<FakeProcess> generator{environment, &mockPchGeneratorNotifier};
|
||||||
ClangBackEnd::PchCreator creator{{projectPart1.clone(),projectPart2.clone()},
|
ClangBackEnd::PchCreator creator{{projectPart1.clone(),projectPart2.clone()},
|
||||||
environment,
|
environment,
|
||||||
filePathCache};
|
filePathCache,
|
||||||
|
&generator};
|
||||||
};
|
};
|
||||||
|
|
||||||
using PchCreatorSlowTest = PchCreator;
|
using PchCreatorSlowTest = PchCreator;
|
||||||
@@ -116,7 +122,7 @@ TEST_F(PchCreator, CreateGlobalCommandLine)
|
|||||||
ASSERT_THAT(arguments, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header", "-I", TESTDATA_DIR, "-x" , "c++-header", "-Wno-pragma-once-outside-header"));
|
ASSERT_THAT(arguments, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header", "-I", TESTDATA_DIR, "-x" , "c++-header", "-Wno-pragma-once-outside-header"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchCreator, CreateGlobalPchIncludes)
|
TEST_F(PchCreatorVerySlowTest, CreateGlobalPchIncludes)
|
||||||
{
|
{
|
||||||
auto includeIds = creator.generateGlobalPchIncludeIds();
|
auto includeIds = creator.generateGlobalPchIncludeIds();
|
||||||
|
|
||||||
@@ -167,13 +173,6 @@ TEST_F(PchCreator, CreateGlobalClangCompilerArguments)
|
|||||||
Not(Contains(environment.clangCompilerPath()))));
|
Not(Contains(environment.clangCompilerPath()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchCreatorVerySlowTest, CreateGlobalPch)
|
|
||||||
{
|
|
||||||
creator.generateGlobalPch();
|
|
||||||
|
|
||||||
ASSERT_TRUE(QFileInfo::exists(creator.generateGlobalPchFilePath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(PchCreator, CreateProjectPartCommandLine)
|
TEST_F(PchCreator, CreateProjectPartCommandLine)
|
||||||
{
|
{
|
||||||
auto commandLine = creator.generateProjectPartCommandLine(projectPart1);
|
auto commandLine = creator.generateProjectPartCommandLine(projectPart1);
|
||||||
@@ -258,23 +257,34 @@ TEST_F(PchCreatorVerySlowTest, CreatePartPchs)
|
|||||||
{
|
{
|
||||||
creator.generateGlobalPch();
|
creator.generateGlobalPch();
|
||||||
|
|
||||||
auto projectPartPchAndIdPath = creator.generateProjectPartPch(projectPart1);
|
auto includePaths = creator.generateProjectPartPch(projectPart1);
|
||||||
|
|
||||||
ASSERT_THAT(projectPartPchAndIdPath.first.id(), projectPart1.projectPartId());
|
ASSERT_THAT(includePaths.id, projectPart1.projectPartId());
|
||||||
ASSERT_THAT(projectPartPchAndIdPath.first.path(), creator.generateProjectPartPchFilePath(projectPart1));
|
ASSERT_THAT(includePaths.paths, UnorderedElementsAre(1, 2, 3));
|
||||||
ASSERT_THAT(projectPartPchAndIdPath.second.id, projectPart1.projectPartId());
|
}
|
||||||
ASSERT_THAT(projectPartPchAndIdPath.second.paths, UnorderedElementsAre(1, 2, 3));
|
|
||||||
|
TEST_F(PchCreatorVerySlowTest, IncludesForCreatePchsForProjectParts)
|
||||||
|
{
|
||||||
|
creator.generatePchs();
|
||||||
|
|
||||||
|
ASSERT_THAT(creator.takeProjectsIncludes(),
|
||||||
|
ElementsAre(Field(&IdPaths::id, "project1"),
|
||||||
|
Field(&IdPaths::id, "project2")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchCreatorVerySlowTest, ProjectPartPchsForCreatePchsForProjectParts)
|
TEST_F(PchCreatorVerySlowTest, ProjectPartPchsForCreatePchsForProjectParts)
|
||||||
{
|
{
|
||||||
creator.generatePchs();
|
EXPECT_CALL(mockPchGeneratorNotifier,
|
||||||
|
taskFinished(ClangBackEnd::TaskFinishStatus::Successfully,
|
||||||
|
Property(&ProjectPartPch::id, "project1")));
|
||||||
|
EXPECT_CALL(mockPchGeneratorNotifier,
|
||||||
|
taskFinished(ClangBackEnd::TaskFinishStatus::Successfully,
|
||||||
|
Property(&ProjectPartPch::id, "project2")));
|
||||||
|
|
||||||
ASSERT_THAT(creator.takeProjectPartPchs(),
|
creator.generatePchs();
|
||||||
ElementsAre(Property(&ProjectPartPch::id, "project1"),
|
|
||||||
Property(&ProjectPartPch::id, "project2")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
|
TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
|
||||||
{
|
{
|
||||||
creator.generatePchs();
|
creator.generatePchs();
|
||||||
|
|||||||
224
tests/unit/unittest/pchgenerator-test.cpp
Normal file
224
tests/unit/unittest/pchgenerator-test.cpp
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** 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 "googletest.h"
|
||||||
|
|
||||||
|
#include "fakeprocess.h"
|
||||||
|
#include "testenvironment.h"
|
||||||
|
#include "mockpchgeneratornotifier.h"
|
||||||
|
|
||||||
|
#include <pchgenerator.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::Contains;
|
||||||
|
using testing::Eq;
|
||||||
|
using testing::NiceMock;
|
||||||
|
using testing::Not;
|
||||||
|
using testing::PrintToString;
|
||||||
|
using ClangBackEnd::TaskFinishStatus;
|
||||||
|
|
||||||
|
MATCHER_P(ContainsProcess, process,
|
||||||
|
std::string(negation ? "isn't" : "is")
|
||||||
|
+ " process " + PrintToString(process))
|
||||||
|
{
|
||||||
|
auto found = std::find_if(arg.begin(),
|
||||||
|
arg.end(),
|
||||||
|
[&] (const std::unique_ptr<FakeProcess> &processOwner) {
|
||||||
|
return processOwner.get() == process;
|
||||||
|
});
|
||||||
|
|
||||||
|
return found != arg.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
class PchGenerator : public testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
TestEnvironment environment;
|
||||||
|
NiceMock<MockPchGeneratorNotifier> mockNotifier;
|
||||||
|
ClangBackEnd::PchGenerator<FakeProcess> generator{environment, &mockNotifier};
|
||||||
|
Utils::SmallStringVector compilerArguments = {"-DXXXX", "-Ifoo"};
|
||||||
|
ClangBackEnd::ProjectPartPch projectPartPch{"projectPartId", "/path/to/pch"};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const std::unique_ptr<FakeProcess> &first, FakeProcess *const second)
|
||||||
|
{
|
||||||
|
return first.get() == second;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ProcessFinished)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Successfully, std::move(projectPartPch)));
|
||||||
|
|
||||||
|
generator.startTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ProcessFinishedForDeferredProcess)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
generator.startTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Successfully, std::move(projectPartPch)))
|
||||||
|
.Times(3);
|
||||||
|
|
||||||
|
generator.startTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
process->finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ProcessSuccessfullyFinished)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Unsuccessfully, std::move(projectPartPch)));
|
||||||
|
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
process->finishUnsuccessfully();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ProcessSuccessfullyFinishedByWrongExitCode)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Unsuccessfully, std::move(projectPartPch)));
|
||||||
|
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
process->finishUnsuccessfully();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, AddTaskAddsProcessToProcesses)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_THAT(generator.runningProcesses(), ContainsProcess(process));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, RemoveProcessAfterFinishingProcess)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
process->finish();
|
||||||
|
|
||||||
|
ASSERT_THAT(generator.runningProcesses(), Not(ContainsProcess(process)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ProcessSuccessfullyFinishedByCrash)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockNotifier, taskFinished(TaskFinishStatus::Unsuccessfully, std::move(projectPartPch)));
|
||||||
|
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
process->finishByCrash();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, CreateProcess)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_THAT(generator.runningProcesses(), ContainsProcess(process));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, DeleteProcess)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
generator.deleteProcess(process);
|
||||||
|
|
||||||
|
ASSERT_THAT(generator.runningProcesses(), Not(ContainsProcess(process)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, StartProcessApplicationPath)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_THAT(process->applicationPath(), environment.clangCompilerPath());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, SetCompilerArguments)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_THAT(process->arguments(), compilerArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ProcessIsStartedAfterAddingTask)
|
||||||
|
{
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_TRUE(process->isStarted());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, DeferProcess)
|
||||||
|
{
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
auto deferProcess = generator.deferProcess();
|
||||||
|
|
||||||
|
ASSERT_TRUE(deferProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ThirdTaskIsDeferred)
|
||||||
|
{
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_THAT(process, generator.deferredProcesses().back().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, ThirdTaskIsNotRunning)
|
||||||
|
{
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
ASSERT_THAT(generator.runningProcesses(), Not(ContainsProcess(process)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, DoNotDeferProcess)
|
||||||
|
{
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
auto deferProcess = generator.deferProcess();
|
||||||
|
|
||||||
|
ASSERT_FALSE(deferProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, DoNotActivateIfNothingIsDeferred)
|
||||||
|
{
|
||||||
|
generator.activateNextDeferredProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchGenerator, AfterActivationProcessIsRunning)
|
||||||
|
{
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
auto process = generator.addTask(compilerArguments.clone(), projectPartPch.clone());
|
||||||
|
|
||||||
|
generator.activateNextDeferredProcess();
|
||||||
|
|
||||||
|
ASSERT_THAT(generator.runningProcesses(), ContainsProcess(process));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -47,6 +47,7 @@ using testing::IsEmpty;
|
|||||||
|
|
||||||
using Utils::SmallString;
|
using Utils::SmallString;
|
||||||
using ClangBackEnd::V2::ProjectPartContainer;
|
using ClangBackEnd::V2::ProjectPartContainer;
|
||||||
|
using ClangBackEnd::TaskFinishStatus;
|
||||||
|
|
||||||
class PchManagerServer : public ::testing::Test
|
class PchManagerServer : public ::testing::Test
|
||||||
{
|
{
|
||||||
@@ -76,18 +77,28 @@ protected:
|
|||||||
{main2Path.clone()}};
|
{main2Path.clone()}};
|
||||||
std::vector<ClangBackEnd::V2::ProjectPartContainer> projectParts{projectPart1, projectPart2};
|
std::vector<ClangBackEnd::V2::ProjectPartContainer> projectParts{projectPart1, projectPart2};
|
||||||
ClangBackEnd::UpdatePchProjectPartsMessage updatePchProjectPartsMessage{Utils::clone(projectParts)};
|
ClangBackEnd::UpdatePchProjectPartsMessage updatePchProjectPartsMessage{Utils::clone(projectParts)};
|
||||||
std::vector<ClangBackEnd::ProjectPartPch> projectPartPchs{{projectPart1.projectPartId().clone(), "/path1/to/pch"},
|
ClangBackEnd::ProjectPartPch projectPartPch1{projectPart1.projectPartId().clone(), "/path1/to/pch"};
|
||||||
{projectPart2.projectPartId().clone(), "/path2/to/pch"}};
|
ClangBackEnd::ProjectPartPch projectPartPch2{projectPart2.projectPartId().clone(), "/path2/to/pch"};
|
||||||
ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage{Utils::clone(projectPartPchs)};
|
std::vector<ClangBackEnd::ProjectPartPch> projectPartPchs{projectPartPch1, projectPartPch2};
|
||||||
|
ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage1{{projectPartPch1}};
|
||||||
|
ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage2{{projectPartPch2}};
|
||||||
ClangBackEnd::RemovePchProjectPartsMessage removePchProjectPartsMessage{{projectPart1.projectPartId().clone(),
|
ClangBackEnd::RemovePchProjectPartsMessage removePchProjectPartsMessage{{projectPart1.projectPartId().clone(),
|
||||||
projectPart2.projectPartId().clone()}};
|
projectPart2.projectPartId().clone()}};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(PchManagerServer, CallPrecompiledHeadersUpdatedInClientForUpdate)
|
TEST_F(PchManagerServer, CallPrecompiledHeadersForSuccessfullyFinishedTask)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage));
|
EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage1));
|
||||||
|
|
||||||
server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
|
server.taskFinished(TaskFinishStatus::Successfully, projectPartPch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchManagerServer, DoNotCallPrecompiledHeadersForUnsuccessfullyFinishedTask)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage1))
|
||||||
|
.Times(0);
|
||||||
|
|
||||||
|
server.taskFinished(TaskFinishStatus::Unsuccessfully, projectPartPch1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchManagerServer, CallBuildInPchCreator)
|
TEST_F(PchManagerServer, CallBuildInPchCreator)
|
||||||
@@ -150,15 +161,6 @@ TEST_F(PchManagerServer, CallGeneratePchsInPchCreatorForIncludeChange)
|
|||||||
server.pathsWithIdsChanged({projectPartId1});
|
server.pathsWithIdsChanged({projectPartId1});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PchManagerServer, CallPrecompiledHeadersUpdatedInClientForIncludeChange)
|
|
||||||
{
|
|
||||||
server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
|
|
||||||
|
|
||||||
EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage));
|
|
||||||
|
|
||||||
server.pathsWithIdsChanged({projectPartId1});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(PchManagerServer, CallUpdateIdPathsInFileSystemWatcherForIncludeChange)
|
TEST_F(PchManagerServer, CallUpdateIdPathsInFileSystemWatcherForIncludeChange)
|
||||||
{
|
{
|
||||||
server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
|
server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
|
||||||
@@ -172,8 +174,6 @@ void PchManagerServer::SetUp()
|
|||||||
{
|
{
|
||||||
server.setClient(&mockPchManagerClient);
|
server.setClient(&mockPchManagerClient);
|
||||||
|
|
||||||
ON_CALL(mockPchCreator, takeProjectPartPchs())
|
|
||||||
.WillByDefault(Return(projectPartPchs));
|
|
||||||
ON_CALL(mockProjectParts, update(projectParts))
|
ON_CALL(mockProjectParts, update(projectParts))
|
||||||
.WillByDefault(Return(projectParts));
|
.WillByDefault(Return(projectParts));
|
||||||
ON_CALL(mockProjectParts, projects(Utils::SmallStringVector{{projectPartId1}}))
|
ON_CALL(mockProjectParts, projects(Utils::SmallStringVector{{projectPartId1}}))
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ public:
|
|||||||
return QString::fromUtf8(CLANG_COMPILER_PATH);
|
return QString::fromUtf8(CLANG_COMPILER_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint hardwareConcurrency() const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTemporaryDir temporaryDirectory;
|
QTemporaryDir temporaryDirectory;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ SOURCES += \
|
|||||||
projectparts-test.cpp \
|
projectparts-test.cpp \
|
||||||
stringcache-test.cpp \
|
stringcache-test.cpp \
|
||||||
changedfilepathcompressor-test.cpp \
|
changedfilepathcompressor-test.cpp \
|
||||||
faketimer.cpp
|
faketimer.cpp \
|
||||||
|
pchgenerator-test.cpp \
|
||||||
|
fakeprocess.cpp
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -148,7 +150,9 @@ HEADERS += \
|
|||||||
mockprojectparts.h \
|
mockprojectparts.h \
|
||||||
mockclangpathwatchernotifier.h \
|
mockclangpathwatchernotifier.h \
|
||||||
mockchangedfilepathcompressor.h \
|
mockchangedfilepathcompressor.h \
|
||||||
faketimer.h
|
faketimer.h \
|
||||||
|
mockpchgeneratornotifier.h \
|
||||||
|
fakeprocess.h
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
|||||||
Reference in New Issue
Block a user