diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 9ae36b75517..bc1b8639a10 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -221,39 +221,43 @@ static QString clangIncludeDirectory(const QString &clangVersion, #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, bool isMacOs = false) +static QStringList insertResourceDirectory(const QStringList &options, + const QString &resourceDir, + bool isMacOs = false) { // include/c++, include/g++, libc++\include and libc++abi\include static const QString cppIncludes = R"((.*[\/\\]include[\/\\].*(g\+\+|c\+\+).*))" R"(|(.*libc\+\+[\/\\]include))" R"(|(.*libc\+\+abi[\/\\]include))"; - static const QRegularExpression includeRegExp("\\A(" + cppIncludes + ")\\z"); - // The same as includeRegExp but also matches /usr/local/include - static const QRegularExpression includeRegExpMac( - "\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\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 + includeRegExp = QRegularExpression( + "\\A(" + cppIncludes + R"(|([\/\\]usr[\/\\]local[\/\\]include))" + ")\\z"); + } - const int cppIncludeIndex = lastIncludeIndex(options, isMacOs - ? includeRegExpMac - : includeRegExp); + for (const QString &option : options) { + if (option == "-isystem") + continue; - if (cppIncludeIndex > 0) - return cppIncludeIndex + 1; + if (includeRegExp.match(option).hasMatch()) { + 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() @@ -325,16 +329,11 @@ void CompilerOptionsBuilder::addHeaderPathOptions() const QString clangIncludePath = clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory); - int includeIndexForResourceDir = includeIndexForResourceDirectory( - builtInIncludes, m_projectPart.toolChainTargetTriple.contains("darwin")); - if (includeIndexForResourceDir >= 0) { - builtInIncludes.insert(includeIndexForResourceDir, clangIncludePath); - builtInIncludes.insert(includeIndexForResourceDir, "-isystem"); - } else { - builtInIncludes.prepend(clangIncludePath); - builtInIncludes.prepend("-isystem"); - } + builtInIncludes = insertResourceDirectory(builtInIncludes, + clangIncludePath, + m_projectPart.toolChainTargetTriple.contains( + "darwin")); } m_options.append(builtInIncludes); diff --git a/tests/unit/unittest/compileroptionsbuilder-test.cpp b/tests/unit/unittest/compileroptionsbuilder-test.cpp index 097efd58032..b7a4ace9e60 100644 --- a/tests/unit/unittest/compileroptionsbuilder-test.cpp +++ b/tests/unit/unittest/compileroptionsbuilder-test.cpp @@ -231,50 +231,16 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderLinux) } 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 = { - 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", + 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 = "i686-linux-android"; + projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu"; CppTools::CompilerOptionsBuilder compilerOptionsBuilder(projectPart, CppTools::UseSystemHeader::No, CppTools::SkipBuiltIn::No, @@ -290,22 +256,68 @@ TEST_F(CompilerOptionsBuilder, ClangHeadersAndCppIncludesPathsOrderAndroidClang) "-nostdinc", "-nostdlibinc", "-isystem", - QDir::toNativeSeparators( - "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include\\i686-linux-android"), + QDir::toNativeSeparators("C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++"), "-isystem", 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", 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\\sources\\cxx-stl\\llvm-libc++abi\\include"), + "C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/c++/backward"), "-isystem", QDir::toNativeSeparators(CLANG_RESOURCE_DIR ""), "-isystem", - QDir::toNativeSeparators( - "C:\\Users\\test\\AppData\\Local\\Android\\sdk\\ndk-bundle\\sysroot\\usr\\include"))); + QDir::toNativeSeparators("C:/Qt/Tools/mingw530_32/i686-w64-mingw32/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)