forked from qt-creator/qt-creator
Clang: Add environment variables for extra clang flags
Different variables for clang code model and clang static analyzer. Task-number: QTCREATORBUG-19329 Change-Id: I64abdefb8c646a6f45f789a61abf75198e7ca3b8 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -61,6 +61,7 @@
|
|||||||
#include <utils/checkablemessagebox.h>
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/temporarydirectory.h>
|
#include <utils/temporarydirectory.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
@@ -71,6 +72,40 @@ using namespace Utils;
|
|||||||
|
|
||||||
static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol")
|
static Q_LOGGING_CATEGORY(LOG, "qtc.clangstaticanalyzer.runcontrol")
|
||||||
|
|
||||||
|
static QStringList splitArgs(QString &argsString)
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
Utils::QtcProcess::ArgIterator it(&argsString);
|
||||||
|
while (it.next())
|
||||||
|
result.append(it.value());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t Size>
|
||||||
|
static QStringList extraOptions(const char(&environment)[Size])
|
||||||
|
{
|
||||||
|
if (!qEnvironmentVariableIsSet(environment))
|
||||||
|
return QStringList();
|
||||||
|
QString arguments = QString::fromLocal8Bit(qgetenv(environment));
|
||||||
|
return splitArgs(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QStringList extraClangStaticAnalyzerPrependOptions() {
|
||||||
|
constexpr char csaPrependOptions[] = "QTC_CLANG_CSA_CMD_PREPEND";
|
||||||
|
static const QStringList options = extraOptions(csaPrependOptions);
|
||||||
|
if (!options.isEmpty())
|
||||||
|
qWarning() << "ClangStaticAnalyzer options are prepended with " << options.toVector();
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QStringList extraClangStaticAnalyzerAppendOptions() {
|
||||||
|
constexpr char csaAppendOptions[] = "QTC_CLANG_CSA_CMD_APPEND";
|
||||||
|
static const QStringList options = extraOptions(csaAppendOptions);
|
||||||
|
if (!options.isEmpty())
|
||||||
|
qWarning() << "ClangStaticAnalyzer options are appended with " << options.toVector();
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ClangStaticAnalyzer {
|
namespace ClangStaticAnalyzer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -303,7 +338,9 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
|
|||||||
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
||||||
CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion,
|
CompilerOptionsBuilder optionsBuilder(*projectPart, clangVersion,
|
||||||
clangResourceDirectory);
|
clangResourceDirectory);
|
||||||
const QStringList arguments = optionsBuilder.build(file.kind, pchUsage);
|
QStringList arguments = extraClangStaticAnalyzerPrependOptions();
|
||||||
|
arguments.append(optionsBuilder.build(file.kind, pchUsage));
|
||||||
|
arguments.append(extraClangStaticAnalyzerAppendOptions());
|
||||||
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
|
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,30 +28,74 @@
|
|||||||
#include "clangfilepath.h"
|
#include "clangfilepath.h"
|
||||||
|
|
||||||
#include <utf8string.h>
|
#include <utf8string.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
static QList<QByteArray> splitArgs(QString &argsString)
|
||||||
|
{
|
||||||
|
QList<QByteArray> result;
|
||||||
|
Utils::QtcProcess::ArgIterator it(&argsString);
|
||||||
|
while (it.next())
|
||||||
|
result.append(it.value().toUtf8());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t Size>
|
||||||
|
static QList<QByteArray> extraOptions(const char(&environment)[Size])
|
||||||
|
{
|
||||||
|
if (!qEnvironmentVariableIsSet(environment))
|
||||||
|
return QList<QByteArray>();
|
||||||
|
QString arguments = QString::fromLocal8Bit(qgetenv(environment));
|
||||||
|
return splitArgs(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<QByteArray> extraClangCodeModelPrependOptions() {
|
||||||
|
constexpr char ccmPrependOptions[] = "QTC_CLANG_CCM_CMD_PREPEND";
|
||||||
|
static const QList<QByteArray> options = extraOptions(ccmPrependOptions);
|
||||||
|
if (!options.isEmpty())
|
||||||
|
qWarning() << "ClangCodeModel options are prepended with " << options;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<QByteArray> extraClangCodeModelAppendOptions() {
|
||||||
|
constexpr char ccmAppendOptions[] = "QTC_CLANG_CCM_CMD_APPEND";
|
||||||
|
static const QList<QByteArray> options = extraOptions(ccmAppendOptions);
|
||||||
|
if (!options.isEmpty())
|
||||||
|
qWarning() << "ClangCodeModel options are appended with " << options;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
CommandLineArguments::CommandLineArguments(const char *filePath,
|
CommandLineArguments::CommandLineArguments(const char *filePath,
|
||||||
const Utf8StringVector &projectPartArguments,
|
const Utf8StringVector &projectPartArguments,
|
||||||
const Utf8StringVector &fileArguments,
|
const Utf8StringVector &fileArguments,
|
||||||
bool addVerboseOption)
|
bool addVerboseOption)
|
||||||
|
: m_prependArgs(extraClangCodeModelPrependOptions()),
|
||||||
|
m_appendArgs(extraClangCodeModelAppendOptions())
|
||||||
{
|
{
|
||||||
const auto elementsToReserve = projectPartArguments.size()
|
const int elementsToReserve = m_prependArgs.size()
|
||||||
+ uint(fileArguments.size())
|
+ projectPartArguments.size()
|
||||||
+ (addVerboseOption ? 1 : 0);
|
+ fileArguments.size()
|
||||||
m_arguments.reserve(elementsToReserve);
|
+ (addVerboseOption ? 1 : 0)
|
||||||
|
+ m_appendArgs.size();
|
||||||
|
m_arguments.reserve(static_cast<size_t>(elementsToReserve));
|
||||||
|
|
||||||
|
for (const auto &argument : m_prependArgs)
|
||||||
|
m_arguments.push_back(argument.constData());
|
||||||
for (const auto &argument : projectPartArguments)
|
for (const auto &argument : projectPartArguments)
|
||||||
m_arguments.push_back(argument.constData());
|
m_arguments.push_back(argument.constData());
|
||||||
for (const auto &argument : fileArguments)
|
for (const auto &argument : fileArguments)
|
||||||
m_arguments.push_back(argument.constData());
|
m_arguments.push_back(argument.constData());
|
||||||
if (addVerboseOption)
|
if (addVerboseOption)
|
||||||
m_arguments.push_back("-v");
|
m_arguments.push_back("-v");
|
||||||
|
for (const auto &argument : m_appendArgs)
|
||||||
|
m_arguments.push_back(argument.constData());
|
||||||
m_nativeFilePath = FilePath::toNativeSeparators(Utf8String::fromUtf8(filePath));
|
m_nativeFilePath = FilePath::toNativeSeparators(Utf8String::fromUtf8(filePath));
|
||||||
m_arguments.push_back(m_nativeFilePath.constData());
|
m_arguments.push_back(m_nativeFilePath.constData());
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Utf8String m_nativeFilePath;
|
Utf8String m_nativeFilePath;
|
||||||
|
const QList<QByteArray> m_prependArgs;
|
||||||
|
const QList<QByteArray> m_appendArgs;
|
||||||
std::vector<const char *> m_arguments;
|
std::vector<const char *> m_arguments;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user