forked from qt-creator/qt-creator
Clang: Always force the built-in includes order
C++ includes must always come first, then clang resource directory and then everything else. This prevents both c++ standard headers and intrinsics issues. Change-Id: Ia21bfa2fe99884c9adf58f7ef6beba1bede1724b Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
@@ -221,39 +221,43 @@ static QString clangIncludeDirectory(const QString &clangVersion,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lastIncludeIndex(const QStringList &options, const QRegularExpression &includePathRegEx)
|
static QStringList insertResourceDirectory(const QStringList &options,
|
||||||
{
|
const QString &resourceDir,
|
||||||
int index = options.lastIndexOf(includePathRegEx);
|
bool isMacOs = false)
|
||||||
|
|
||||||
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, bool isMacOs = false)
|
|
||||||
{
|
{
|
||||||
// include/c++, include/g++, libc++\include and libc++abi\include
|
// include/c++, include/g++, libc++\include and libc++abi\include
|
||||||
static const QString cppIncludes = R"((.*[\/\\]include[\/\\].*(g\+\+|c\+\+).*))"
|
static const QString cppIncludes = R"((.*[\/\\]include[\/\\].*(g\+\+|c\+\+).*))"
|
||||||
R"(|(.*libc\+\+[\/\\]include))"
|
R"(|(.*libc\+\+[\/\\]include))"
|
||||||
R"(|(.*libc\+\+abi[\/\\]include))";
|
R"(|(.*libc\+\+abi[\/\\]include))";
|
||||||
static const QRegularExpression includeRegExp("\\A(" + cppIncludes + ")\\z");
|
|
||||||
|
|
||||||
|
QStringList optionsBeforeResourceDirectory;
|
||||||
|
QStringList optionsAfterResourceDirectory;
|
||||||
|
QRegularExpression includeRegExp;
|
||||||
|
if (!isMacOs) {
|
||||||
|
includeRegExp = QRegularExpression("\\A(" + cppIncludes + ")\\z");
|
||||||
|
} else {
|
||||||
// The same as includeRegExp but also matches /usr/local/include
|
// The same as includeRegExp but also matches /usr/local/include
|
||||||
static const QRegularExpression includeRegExpMac(
|
includeRegExp = QRegularExpression(
|
||||||
"\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\z");
|
"\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\z");
|
||||||
|
}
|
||||||
|
|
||||||
const int cppIncludeIndex = lastIncludeIndex(options, isMacOs
|
for (const QString &option : options) {
|
||||||
? includeRegExpMac
|
if (option == "-isystem")
|
||||||
: includeRegExp);
|
continue;
|
||||||
|
|
||||||
if (cppIncludeIndex > 0)
|
if (includeRegExp.match(option).hasMatch()) {
|
||||||
return cppIncludeIndex + 1;
|
optionsBeforeResourceDirectory.push_back("-isystem");
|
||||||
|
optionsBeforeResourceDirectory.push_back(option);
|
||||||
|
} else {
|
||||||
|
optionsAfterResourceDirectory.push_back("-isystem");
|
||||||
|
optionsAfterResourceDirectory.push_back(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
optionsBeforeResourceDirectory.push_back("-isystem");
|
||||||
|
optionsBeforeResourceDirectory.push_back(resourceDir);
|
||||||
|
|
||||||
|
return optionsBeforeResourceDirectory + optionsAfterResourceDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilder::insertWrappedQtHeaders()
|
void CompilerOptionsBuilder::insertWrappedQtHeaders()
|
||||||
@@ -325,16 +329,11 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
|
|||||||
|
|
||||||
const QString clangIncludePath
|
const QString clangIncludePath
|
||||||
= clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory);
|
= clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory);
|
||||||
int includeIndexForResourceDir = includeIndexForResourceDirectory(
|
|
||||||
builtInIncludes, m_projectPart.toolChainTargetTriple.contains("darwin"));
|
|
||||||
|
|
||||||
if (includeIndexForResourceDir >= 0) {
|
builtInIncludes = insertResourceDirectory(builtInIncludes,
|
||||||
builtInIncludes.insert(includeIndexForResourceDir, clangIncludePath);
|
clangIncludePath,
|
||||||
builtInIncludes.insert(includeIndexForResourceDir, "-isystem");
|
m_projectPart.toolChainTargetTriple.contains(
|
||||||
} else {
|
"darwin"));
|
||||||
builtInIncludes.prepend(clangIncludePath);
|
|
||||||
builtInIncludes.prepend("-isystem");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_options.append(builtInIncludes);
|
m_options.append(builtInIncludes);
|
||||||
|
@@ -231,50 +231,16 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderLinux)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderNoVersion)
|
TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderNoVersion)
|
||||||
{
|
|
||||||
projectPart.headerPaths = {HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include", HeaderPathType::BuiltIn},
|
|
||||||
HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++", HeaderPathType::BuiltIn},
|
|
||||||
HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32", HeaderPathType::BuiltIn},
|
|
||||||
HeaderPath{"C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\backward", HeaderPathType::BuiltIn}
|
|
||||||
};
|
|
||||||
projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu";
|
|
||||||
CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
|
|
||||||
CppTools::UseSystemHeader::No,
|
|
||||||
CppTools::SkipBuiltIn::No,
|
|
||||||
CppTools::SkipLanguageDefines::Yes,
|
|
||||||
"7.0.0",
|
|
||||||
"");
|
|
||||||
|
|
||||||
compilerOptionsBuilder.addHeaderPathOptions();
|
|
||||||
|
|
||||||
ASSERT_THAT(compilerOptionsBuilder.options(),
|
|
||||||
ElementsAre("-nostdinc",
|
|
||||||
"-nostdlibinc",
|
|
||||||
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include"),
|
|
||||||
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++"),
|
|
||||||
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32"),
|
|
||||||
"-isystem", QDir::toNativeSeparators("C:\\Qt\\Tools\\mingw530_32\\i686-w64-mingw32\\include\\c++\\backward"),
|
|
||||||
"-isystem", QDir::toNativeSeparators(CLANG_RESOURCE_DIR "")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang)
|
|
||||||
{
|
{
|
||||||
projectPart.headerPaths = {
|
projectPart.headerPaths = {
|
||||||
HeaderPath{
|
HeaderPath{"C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include", HeaderPathType::BuiltIn},
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android",
|
HeaderPath{"C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++",
|
||||||
HeaderPathType::BuiltIn},
|
HeaderPathType::BuiltIn},
|
||||||
HeaderPath{
|
HeaderPath{"C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++/i686-w64-mingw32",
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++\\include",
|
|
||||||
HeaderPathType::BuiltIn},
|
HeaderPathType::BuiltIn},
|
||||||
HeaderPath{
|
HeaderPath{"C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++/backward",
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\android\\support\\include",
|
|
||||||
HeaderPathType::BuiltIn},
|
|
||||||
HeaderPath{
|
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++abi\\include",
|
|
||||||
HeaderPathType::BuiltIn},
|
|
||||||
HeaderPath{"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include",
|
|
||||||
HeaderPathType::BuiltIn}};
|
HeaderPathType::BuiltIn}};
|
||||||
projectPart.toolChainTargetTriple = "i686-linux-android";
|
projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu";
|
||||||
CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
|
CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
|
||||||
CppTools::UseSystemHeader::No,
|
CppTools::UseSystemHeader::No,
|
||||||
CppTools::SkipBuiltIn::No,
|
CppTools::SkipBuiltIn::No,
|
||||||
@@ -290,22 +256,68 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang)
|
|||||||
"-nostdinc",
|
"-nostdinc",
|
||||||
"-nostdlibinc",
|
"-nostdlibinc",
|
||||||
"-isystem",
|
"-isystem",
|
||||||
QDir::toNativeSeparators(
|
QDir::toNativeSeparators("C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++"),
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android"),
|
|
||||||
"-isystem",
|
"-isystem",
|
||||||
QDir::toNativeSeparators(
|
QDir::toNativeSeparators(
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++\\include"),
|
"C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++/i686-w64-mingw32"),
|
||||||
"-isystem",
|
"-isystem",
|
||||||
QDir::toNativeSeparators(
|
QDir::toNativeSeparators(
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\android\\support\\include"),
|
"C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++/backward"),
|
||||||
"-isystem",
|
|
||||||
QDir::toNativeSeparators(
|
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sources\\cxx-stl\\llvm-libc++abi\\include"),
|
|
||||||
"-isystem",
|
"-isystem",
|
||||||
QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""),
|
QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""),
|
||||||
"-isystem",
|
"-isystem",
|
||||||
QDir::toNativeSeparators(
|
QDir::toNativeSeparators("C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include")));
|
||||||
"C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include")));
|
}
|
||||||
|
|
||||||
|
TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang)
|
||||||
|
{
|
||||||
|
projectPart.headerPaths
|
||||||
|
= {HeaderPath{"C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sysroot/usr/include/i686-linux-android",
|
||||||
|
HeaderPathType::BuiltIn},
|
||||||
|
HeaderPath{"C:/Users/test/AppData/Local/Android/sdk/ndk-bundle/sources/cxx-"
|
||||||
|
"stl/llvm-libc++/include",
|
||||||
|
HeaderPathType::BuiltIn},
|
||||||
|
HeaderPath{"C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sources/android/support/include",
|
||||||
|
HeaderPathType::BuiltIn},
|
||||||
|
HeaderPath{"C:/Users/test/AppData/Local/Android/sdk/ndk-bundle/sources/cxx-"
|
||||||
|
"stl/llvm-libc++abi/include",
|
||||||
|
HeaderPathType::BuiltIn},
|
||||||
|
HeaderPath{
|
||||||
|
"C:/Users/test/AppData/Local/Android/sdk/ndk-bundle/sysroot/usr/include",
|
||||||
|
HeaderPathType::BuiltIn}};
|
||||||
|
projectPart.toolChainTargetTriple = "i686-linux-android";
|
||||||
|
CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart,
|
||||||
|
CppTools::UseSystemHeader::No,
|
||||||
|
CppTools::SkipBuiltIn::No,
|
||||||
|
CppTools::SkipLanguageDefines::Yes,
|
||||||
|
"7.0.0",
|
||||||
|
"");
|
||||||
|
|
||||||
|
compilerOptionsBuilder.addHeaderPathOptions();
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
compilerOptionsBuilder.options(),
|
||||||
|
ElementsAre("-nostdinc",
|
||||||
|
"-nostdlibinc",
|
||||||
|
"-isystem",
|
||||||
|
QDir::toNativeSeparators("C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sources/cxx-stl/llvm-libc++/include"),
|
||||||
|
"-isystem",
|
||||||
|
QDir::toNativeSeparators("C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sources/cxx-stl/llvm-libc++abi/include"),
|
||||||
|
"-isystem",
|
||||||
|
QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""),
|
||||||
|
"-isystem",
|
||||||
|
QDir::toNativeSeparators("C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sysroot/usr/include/i686-linux-android"),
|
||||||
|
"-isystem",
|
||||||
|
QDir::toNativeSeparators("C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sources/android/support/include"),
|
||||||
|
"-isystem",
|
||||||
|
QDir::toNativeSeparators("C:/Users/test/AppData/Local/Android/sdk/ndk-"
|
||||||
|
"bundle/sysroot/usr/include")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader)
|
TEST_F(CompilerOptionsBuilder, NoPrecompiledHeader)
|
||||||
|
Reference in New Issue
Block a user