aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp73
1 files changed, 66 insertions, 7 deletions
diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
index 820909713..74cad05ae 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
@@ -95,6 +95,36 @@ static bool runProcess(const QString &program, const QStringList &arguments,
static QByteArray frameworkPath() { return QByteArrayLiteral(" (framework directory)"); }
+#if defined(Q_OS_MACOS)
+static void filterHomebrewHeaderPaths(HeaderPaths &headerPaths)
+{
+ QByteArray homebrewPrefix = qgetenv("HOMEBREW_OPT");
+
+ // If HOMEBREW_OPT is found we assume that the build is happening
+ // inside a brew environment, which means we need to filter out
+ // the -isystem flags added by the brew clang shim. This is needed
+ // because brew passes the Qt include paths as system include paths
+ // and because our parser ignores system headers, Qt classes won't
+ // be found and thus compilation errors will occur.
+ if (homebrewPrefix.isEmpty())
+ return;
+
+ qCInfo(lcShiboken) << "Found HOMEBREW_OPT with value:" << homebrewPrefix
+ << "Assuming homebrew build environment.";
+
+ HeaderPaths::iterator it = headerPaths.begin();
+ while (it != headerPaths.end()) {
+ if (it->path.startsWith(homebrewPrefix)) {
+ qCInfo(lcShiboken) << "Filtering out homebrew include path: "
+ << it->path;
+ it = headerPaths.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+#endif
+
// Determine g++'s internal include paths from the output of
// g++ -E -x c++ - -v </dev/null
// Output looks like:
@@ -130,6 +160,10 @@ static HeaderPaths gppInternalIncludePaths(const QString &compiler)
isIncludeDir = true;
}
}
+
+#if defined(Q_OS_MACOS)
+ filterHomebrewHeaderPaths(result);
+#endif
return result;
}
#endif // Q_CC_MSVC
@@ -148,12 +182,36 @@ static void detectVulkan(HeaderPaths *headerPaths)
}
#if defined(Q_CC_GNU)
-static inline bool isRedHat74()
+enum class LinuxDistribution { RedHat, CentOs, Other };
+
+static LinuxDistribution linuxDistribution()
+{
+ const QString &productType = QSysInfo::productType();
+ if (productType == QLatin1String("rhel"))
+ return LinuxDistribution::RedHat;
+ if (productType == QLatin1String("centos"))
+ return LinuxDistribution::CentOs;
+ return LinuxDistribution::Other;
+}
+
+static bool checkProductVersion(const QVersionNumber &minimum,
+ const QVersionNumber &excludedMaximum)
{
- if (QSysInfo::productType() != QLatin1String("rhel"))
- return false;
const QVersionNumber osVersion = QVersionNumber::fromString(QSysInfo::productVersion());
- return osVersion.isNull() || osVersion >= QVersionNumber(7, 4);
+ return osVersion.isNull() || (osVersion >= minimum && osVersion < excludedMaximum);
+}
+
+static inline bool needsGppInternalHeaders()
+{
+ const LinuxDistribution distro = linuxDistribution();
+ switch (distro) {
+ case LinuxDistribution::RedHat:
+ case LinuxDistribution::CentOs:
+ return checkProductVersion(QVersionNumber(7), QVersionNumber(8));
+ case LinuxDistribution::Other:
+ break;
+ }
+ return false;
}
#endif // Q_CC_GNU
@@ -260,9 +318,10 @@ QByteArrayList emulatedCompilerOptions()
#endif // NEED_CLANG_BUILTIN_INCLUDES
// Append the c++ include paths since Clang is unable to find <list> etc
- // on RHEL 7.4 with g++ 6.3. A fix for this has been added to Clang 5.0,
- // so, the code can be removed once Clang 5.0 is the minimum version.
- if (isRedHat74()) {
+ // on RHEL 7 with g++ 6.3 or CentOS 7.2.
+ // A fix for this has been added to Clang 5.0, so, the code can be removed
+ // once Clang 5.0 is the minimum version.
+ if (needsGppInternalHeaders()) {
const HeaderPaths gppPaths = gppInternalIncludePaths(QStringLiteral("g++"));
for (const HeaderPath &h : gppPaths) {
if (h.path.contains("c++"))