forked from qt-creator/qt-creator
Clang: Fix include paths order
C++ include paths should come before Clang include folder. Therefore parse all options for include/c++/v1, include/c++/{version}, include/g++ and /usr/local/include. Task-number: QTCREATORBUG-20231 Change-Id: I22c41f07d241e1e564069bb192d4fe637ff05e87 Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
@@ -83,44 +83,17 @@ QStringList createClangOptions(const ProjectPart::Ptr &pPart, const QString &fil
|
|||||||
return createClangOptions(pPart, fileKind);
|
return createClangOptions(pPart, fileKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString creatorResourcePath()
|
|
||||||
{
|
|
||||||
#ifndef UNIT_TESTS
|
|
||||||
return Core::ICore::resourcePath();
|
|
||||||
#else
|
|
||||||
return QString();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString clangIncludeDirectory(const QString &clangVersion,
|
|
||||||
const QString &clangResourceDirectory)
|
|
||||||
{
|
|
||||||
#ifndef UNIT_TESTS
|
|
||||||
return Core::ICore::clangIncludeDirectory(clangVersion, clangResourceDirectory);
|
|
||||||
#else
|
|
||||||
return QString();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
class LibClangOptionsBuilder final : public CompilerOptionsBuilder
|
class LibClangOptionsBuilder final : public CompilerOptionsBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LibClangOptionsBuilder(const ProjectPart &projectPart)
|
LibClangOptionsBuilder(const ProjectPart &projectPart)
|
||||||
: CompilerOptionsBuilder(projectPart)
|
: CompilerOptionsBuilder(projectPart,
|
||||||
, m_clangVersion(CLANG_VERSION)
|
UseSystemHeader::No,
|
||||||
, m_clangResourceDirectory(CLANG_RESOURCE_DIR)
|
QString(CLANG_VERSION),
|
||||||
|
QString(CLANG_RESOURCE_DIR))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPredefinedHeaderPathsOptions() final
|
|
||||||
{
|
|
||||||
CompilerOptionsBuilder::addPredefinedHeaderPathsOptions();
|
|
||||||
add("-nostdinc");
|
|
||||||
add("-nostdlibinc");
|
|
||||||
addClangIncludeFolder();
|
|
||||||
addWrappedQtHeadersIncludePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToolchainAndProjectMacros() final
|
void addToolchainAndProjectMacros() final
|
||||||
{
|
{
|
||||||
addMacros({ProjectExplorer::Macro("Q_CREATOR_RUN", "1")});
|
addMacros({ProjectExplorer::Macro("Q_CREATOR_RUN", "1")});
|
||||||
@@ -138,28 +111,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addClangIncludeFolder()
|
|
||||||
{
|
|
||||||
QTC_CHECK(!m_clangVersion.isEmpty());
|
|
||||||
add("-I");
|
|
||||||
add(clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory));
|
|
||||||
}
|
|
||||||
|
|
||||||
void addWrappedQtHeadersIncludePath()
|
|
||||||
{
|
|
||||||
static const QString resourcePath = creatorResourcePath();
|
|
||||||
static QString wrappedQtHeadersPath = resourcePath + "/cplusplus/wrappedQtHeaders";
|
|
||||||
QTC_ASSERT(QDir(wrappedQtHeadersPath).exists(), return;);
|
|
||||||
|
|
||||||
if (m_projectPart.qtVersion != CppTools::ProjectPart::NoQt) {
|
|
||||||
const QString wrappedQtCoreHeaderPath = wrappedQtHeadersPath + "/QtCore";
|
|
||||||
add(includeDirOptionForPath(wrappedQtHeadersPath));
|
|
||||||
add(QDir::toNativeSeparators(wrappedQtHeadersPath));
|
|
||||||
add(includeDirOptionForPath(wrappedQtHeadersPath));
|
|
||||||
add(QDir::toNativeSeparators(wrappedQtCoreHeaderPath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addDummyUiHeaderOnDiskIncludePath()
|
void addDummyUiHeaderOnDiskIncludePath()
|
||||||
{
|
{
|
||||||
const QString path = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskDirPath();
|
const QString path = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskDirPath();
|
||||||
@@ -168,9 +119,6 @@ private:
|
|||||||
add(QDir::toNativeSeparators(path));
|
add(QDir::toNativeSeparators(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString m_clangVersion;
|
|
||||||
QString m_clangResourceDirectory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -191,7 +191,10 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
|
|||||||
AnalyzeUnits unitsToAnalyze;
|
AnalyzeUnits unitsToAnalyze;
|
||||||
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
|
||||||
for (const FileInfo &fileInfo : fileInfos) {
|
for (const FileInfo &fileInfo : fileInfos) {
|
||||||
CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart);
|
CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart,
|
||||||
|
CppTools::UseSystemHeader::No,
|
||||||
|
QString(CLANG_VERSION),
|
||||||
|
QString(CLANG_RESOURCE_DIR));
|
||||||
QStringList arguments = extraClangToolsPrependOptions();
|
QStringList arguments = extraClangToolsPrependOptions();
|
||||||
arguments.append(optionsBuilder.build(fileInfo.kind, pchUsage));
|
arguments.append(optionsBuilder.build(fileInfo.kind, pchUsage));
|
||||||
arguments.append(extraClangToolsAppendOptions());
|
arguments.append(extraClangToolsAppendOptions());
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "compileroptionsbuilder.h"
|
#include "compileroptionsbuilder.h"
|
||||||
|
|
||||||
|
#include "cppmodelmanager.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/vcsmanager.h>
|
#include <coreplugin/vcsmanager.h>
|
||||||
|
|
||||||
@@ -40,9 +42,13 @@
|
|||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
||||||
UseSystemHeader useSystemHeader)
|
UseSystemHeader useSystemHeader,
|
||||||
: m_projectPart(projectPart),
|
QString clangVersion,
|
||||||
m_useSystemHeader(useSystemHeader)
|
QString clangResourceDirectory)
|
||||||
|
: m_projectPart(projectPart)
|
||||||
|
, m_useSystemHeader(useSystemHeader)
|
||||||
|
, m_clangVersion(clangVersion)
|
||||||
|
, m_clangResourceDirectory(clangResourceDirectory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +75,7 @@ QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind,
|
|||||||
undefineCppLanguageFeatureMacrosForMsvc2015();
|
undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||||
addDefineFunctionMacrosMsvc();
|
addDefineFunctionMacrosMsvc();
|
||||||
|
|
||||||
addPredefinedHeaderPathsOptions();
|
addGlobalUndef();
|
||||||
addPrecompiledHeaderOptions(pchUsage);
|
addPrecompiledHeaderOptions(pchUsage);
|
||||||
addHeaderPathOptions();
|
addHeaderPathOptions();
|
||||||
addProjectConfigFileInclude();
|
addProjectConfigFileInclude();
|
||||||
@@ -78,6 +84,8 @@ QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind,
|
|||||||
|
|
||||||
addExtraOptions();
|
addExtraOptions();
|
||||||
|
|
||||||
|
insertPredefinedHeaderPathsOptions();
|
||||||
|
|
||||||
return options();
|
return options();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,7 +517,107 @@ bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const
|
|||||||
return clangIncludeDir.match(headerPath).hasMatch();
|
return clangIncludeDir.match(headerPath).hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
|
static QString creatorResourcePath()
|
||||||
|
{
|
||||||
|
#ifndef UNIT_TESTS
|
||||||
|
return Core::ICore::resourcePath();
|
||||||
|
#else
|
||||||
|
return QString();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString clangIncludeDirectory(const QString &clangVersion,
|
||||||
|
const QString &clangResourceDirectory)
|
||||||
|
{
|
||||||
|
#ifndef UNIT_TESTS
|
||||||
|
return Core::ICore::clangIncludeDirectory(clangVersion, clangResourceDirectory);
|
||||||
|
#else
|
||||||
|
return QString();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lastIncludeIndex(const QStringList &options, const QRegularExpression &includePathRegEx)
|
||||||
|
{
|
||||||
|
int index = options.lastIndexOf(includePathRegEx);
|
||||||
|
|
||||||
|
while (index > 0 && options[index - 1] != "-I" && options[index - 1] != "-isystem")
|
||||||
|
index = options.lastIndexOf(includePathRegEx, index - 1);
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
index = -1;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int includeIndexForResourceDirectory(const QStringList &options)
|
||||||
|
{
|
||||||
|
// include/c++/{version}, include/c++/v1 and include/g++
|
||||||
|
const int cppIncludeIndex = lastIncludeIndex(
|
||||||
|
options,
|
||||||
|
QRegularExpression("\\A.*[\\/\\\\]include[\\/\\\\].*(g\\+\\+.*\\z|c\\+\\+[\\/\\\\](v1\\z|\\d+.*\\z))"));
|
||||||
|
|
||||||
|
if (cppIncludeIndex > 0)
|
||||||
|
return cppIncludeIndex + 1;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerOptionsBuilder::insertPredefinedHeaderPathsOptions()
|
||||||
|
{
|
||||||
|
if (m_clangVersion.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringList wrappedQtHeaders;
|
||||||
|
addWrappedQtHeadersIncludePath(wrappedQtHeaders);
|
||||||
|
|
||||||
|
QStringList predefinedOptions;
|
||||||
|
predefinedOptions.append("-nostdinc");
|
||||||
|
predefinedOptions.append("-nostdlibinc");
|
||||||
|
addClangIncludeFolder(predefinedOptions);
|
||||||
|
|
||||||
|
const int index = m_options.indexOf(QRegularExpression("\\A-I.*\\z"));
|
||||||
|
if (index < 0) {
|
||||||
|
m_options.append(wrappedQtHeaders);
|
||||||
|
m_options.append(predefinedOptions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int includeIndexForResourceDir = includeIndexForResourceDirectory(m_options);
|
||||||
|
if (includeIndexForResourceDir < index)
|
||||||
|
includeIndexForResourceDir = index;
|
||||||
|
|
||||||
|
m_options = m_options.mid(0, index)
|
||||||
|
+ wrappedQtHeaders
|
||||||
|
+ m_options.mid(index, includeIndexForResourceDir - index)
|
||||||
|
+ predefinedOptions
|
||||||
|
+ m_options.mid(includeIndexForResourceDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerOptionsBuilder::addClangIncludeFolder(QStringList &list)
|
||||||
|
{
|
||||||
|
QTC_CHECK(!m_clangVersion.isEmpty());
|
||||||
|
const QString clangIncludeDir = clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory);
|
||||||
|
|
||||||
|
list.append(includeDirOptionForPath(clangIncludeDir));
|
||||||
|
list.append(clangIncludeDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerOptionsBuilder::addWrappedQtHeadersIncludePath(QStringList &list)
|
||||||
|
{
|
||||||
|
static const QString resourcePath = creatorResourcePath();
|
||||||
|
static QString wrappedQtHeadersPath = resourcePath + "/cplusplus/wrappedQtHeaders";
|
||||||
|
QTC_ASSERT(QDir(wrappedQtHeadersPath).exists(), return;);
|
||||||
|
|
||||||
|
if (m_projectPart.qtVersion != CppTools::ProjectPart::NoQt) {
|
||||||
|
const QString wrappedQtCoreHeaderPath = wrappedQtHeadersPath + "/QtCore";
|
||||||
|
list.append(includeDirOptionForPath(wrappedQtHeadersPath));
|
||||||
|
list.append(QDir::toNativeSeparators(wrappedQtHeadersPath));
|
||||||
|
list.append(includeDirOptionForPath(wrappedQtHeadersPath));
|
||||||
|
list.append(QDir::toNativeSeparators(wrappedQtCoreHeaderPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerOptionsBuilder::addGlobalUndef()
|
||||||
{
|
{
|
||||||
// In case of MSVC we need builtin clang defines to correctly handle clang includes
|
// In case of MSVC we need builtin clang defines to correctly handle clang includes
|
||||||
if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||||
|
@@ -46,13 +46,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CompilerOptionsBuilder(const ProjectPart &projectPart,
|
CompilerOptionsBuilder(const ProjectPart &projectPart,
|
||||||
UseSystemHeader useSystemHeader = UseSystemHeader::No);
|
UseSystemHeader useSystemHeader = UseSystemHeader::No,
|
||||||
|
QString clangVersion = QString(),
|
||||||
|
QString clangResourceDirectory = QString());
|
||||||
virtual ~CompilerOptionsBuilder() {}
|
virtual ~CompilerOptionsBuilder() {}
|
||||||
|
|
||||||
virtual void addTargetTriple();
|
virtual void addTargetTriple();
|
||||||
virtual void addExtraCodeModelFlags();
|
virtual void addExtraCodeModelFlags();
|
||||||
virtual void enableExceptions();
|
virtual void enableExceptions();
|
||||||
virtual void addPredefinedHeaderPathsOptions();
|
virtual void insertPredefinedHeaderPathsOptions();
|
||||||
virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true);
|
virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true);
|
||||||
virtual void updateLanguageOption(ProjectFile::Kind fileKind);
|
virtual void updateLanguageOption(ProjectFile::Kind fileKind);
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ public:
|
|||||||
|
|
||||||
// Add options based on project part
|
// Add options based on project part
|
||||||
void addWordWidth();
|
void addWordWidth();
|
||||||
|
void addGlobalUndef();
|
||||||
void addHeaderPathOptions();
|
void addHeaderPathOptions();
|
||||||
void addPrecompiledHeaderOptions(PchUsage pchUsage);
|
void addPrecompiledHeaderOptions(PchUsage pchUsage);
|
||||||
virtual void addToolchainAndProjectMacros();
|
virtual void addToolchainAndProjectMacros();
|
||||||
@@ -95,8 +98,14 @@ private:
|
|||||||
QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const;
|
QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const;
|
||||||
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
|
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
|
||||||
|
|
||||||
|
void addClangIncludeFolder(QStringList &list);
|
||||||
|
void addWrappedQtHeadersIncludePath(QStringList &list);
|
||||||
|
|
||||||
QStringList m_options;
|
QStringList m_options;
|
||||||
UseSystemHeader m_useSystemHeader;
|
UseSystemHeader m_useSystemHeader;
|
||||||
|
|
||||||
|
QString m_clangVersion;
|
||||||
|
QString m_clangResourceDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
Reference in New Issue
Block a user