From 5662706937bd6a1449538539e3a503c6cbc45399 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 5 Jul 2018 17:50:34 +0200 Subject: Fix macOS build when building inside Homebrew environment A brew build environment sets up a clang shim (fake clang ruby script that sets up additional compiler flags), which passes all brew formula dependency include paths as system include paths (via -isystem). This also includes the Qt dependency. Because our clang parser currently ignores system headers (see Builder::visitLocation in clangbuilder.cpp) and because Qt include statements inside header files would resolve to the system header location, this would result in no Qt classes being recognized by the API extractor, and thus fail the build. Fix this by checking for an environment variable that brew sets inside its build environment, to filter out the unnecessary -isystem flags. This way the Qt include path would be passed as a non-system include path from CMake, and thus correctly complete the build. Task-number: PYSIDE-731 Change-Id: I9b543eddc85270f1e8a90d9f30194b2a862e80d7 Reviewed-by: Christian Tismer Reviewed-by: Alberto Sottile --- .../ApiExtractor/clangparser/compilersupport.cpp | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'sources/shiboken2/ApiExtractor') diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp index 820909713..0d98999b1 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 Date: Mon, 9 Jul 2018 11:38:01 +0200 Subject: shiboken: Provide g++ internal headers for CentOS, too Extend the check introduced by 4725008aeea407ae55cfd66de802dd9e06412efc to CentOS. Task-number: PYSIDE-733 Change-Id: Iaaf2b8af0fa03684d4a3cbd5c5e70e141d125139 Reviewed-by: Alexandru Croitor --- .../ApiExtractor/clangparser/compilersupport.cpp | 39 ++++++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'sources/shiboken2/ApiExtractor') diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp index 0d98999b1..74cad05ae 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp @@ -182,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 @@ -294,9 +318,10 @@ QByteArrayList emulatedCompilerOptions() #endif // NEED_CLANG_BUILTIN_INCLUDES // Append the c++ include paths since Clang is unable to find 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++")) -- cgit v1.2.3