diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2025-06-17 13:52:03 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2025-06-27 15:23:00 +0200 |
| commit | a9479bf46e876f67a15d04e49db0e012acbc4e6c (patch) | |
| tree | 515c0a1dc0e108313f2df29658d5c03fcefba138 | |
| parent | 7e1a388425d6fdb2b4256106036241c5b049e532 (diff) | |
shiboken6: Add heuristics for cross compiling
If --target is present in the clang options and the relevant
-platform/-arch options are not set, use the target to determine the
platform. Also determine the compiler type from the path passed in.
[ChangeLog][shiboken6] The support for cross compiling (using the
correct target for clang-based parsing) has been improved.
Task-number: PYSIDE-3105
Change-Id: If7c81b5317e0002edced1e8629318a8e66e7e1f5
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
3 files changed, 56 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index 26a813427..c6b51991d 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -453,6 +453,7 @@ FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments, unsigned clangFlags) { clang::Builder builder; + clang::setHeuristicOptions(arguments); builder.setForceProcessSystemIncludes(TypeDatabase::instance()->forceProcessSystemIncludes()); if (addCompilerSupportArguments) { if (level == LanguageLevel::Default) diff --git a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp index 14f27bc60..f4c221cb9 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp +++ b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp @@ -29,6 +29,20 @@ using namespace Qt::StringLiterals; namespace clang { +// The command line options set +enum OptionSetFlag : unsigned +{ + CompilerOption = 0x1, + CompilerPathOption = 0x2, + PlatformOption = 0x4, + ArchitectureOption = 0x8 +}; + +Q_DECLARE_FLAGS(OptionsSet, OptionSetFlag) +Q_DECLARE_OPERATORS_FOR_FLAGS(OptionsSet) + +static OptionsSet setOptions; + QVersionNumber libClangVersion() { return QVersionNumber(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR); @@ -67,6 +81,7 @@ bool parseCompiler(QStringView name, Compiler *c) bool setCompiler(const QString &name) { + setOptions.setFlag(CompilerOption); return parseCompiler(name, &_compiler); } @@ -83,6 +98,7 @@ const QString &compilerPath() void setCompilerPath(const QString &name) { + setOptions.setFlag(CompilerPathOption); _compilerPath = name; } @@ -134,6 +150,7 @@ static bool parsePlatform(QStringView name, Platform *p) bool setPlatform(const QString &name) { + setOptions.setFlag(PlatformOption); return parsePlatform(name, &_platform); } @@ -189,6 +206,7 @@ Architecture architecture() bool setArchitecture(const QString &name) { + setOptions.setFlag(ArchitectureOption); auto newArchitecture = parseArchitecture(name); const bool result = newArchitecture != Architecture::Other; if (result) @@ -702,4 +720,37 @@ bool hasTargetOption(const QByteArrayList &clangOptions) isTargetArchOption); } +void setHeuristicOptions(const QByteArrayList &clangOptions) +{ + // Figure out compiler type from the binary set + if (!setOptions.testFlag(CompilerOption) && setOptions.testFlag(CompilerPathOption)) { + const QString name = QFileInfo(_compilerPath).baseName().toLower(); + if (name.contains("clang"_L1)) + _compiler = Compiler::Clang; + else if (name.contains("cl"_L1)) + _compiler = Compiler::Msvc; + else if (name.contains("gcc"_L1) || name.contains("g++"_L1)) + _compiler = Compiler::Gpp; + } + + // Figure out platform/arch from "--target" triplet + if (!setOptions.testFlag(PlatformOption) && !setOptions.testFlag(ArchitectureOption)) { + auto it = std::find_if(clangOptions.cbegin(), clangOptions.cend(), isTargetOption); + if (it != clangOptions.cend()) { + const QString triplet = QLatin1StringView(it->sliced(qstrlen(targetOptionC))); + Architecture arch{}; + Platform platform{}; + Compiler comp{}; + if (parseTriplet(triplet, &arch, &platform, &comp)) { + if (!setOptions.testFlag(ArchitectureOption)) + _architecture = arch; + if (!setOptions.testFlag(PlatformOption)) + _platform = platform; + } else { + qCWarning(lcShiboken, "Unable to parse triplet \"%s\".", qPrintable(triplet)); + } + } + } +} + } // namespace clang diff --git a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h index e497f2df8..f2518edd7 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h +++ b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h @@ -80,6 +80,10 @@ bool isCrossCompilation(); // Are there any options specifying a target bool hasTargetOption(const QByteArrayList &clangOptions); +// Unless the platform/architecture/compiler options were set, try to find +// values based on a --target option in clangOptions and the compiler path. +void setHeuristicOptions(const QByteArrayList &clangOptions); + // Parse a triplet "x86_64-unknown-linux-gnu" (for testing). Note the // compiler might not be present and defaults to host bool parseTriplet(QStringView name, Architecture *a, Platform *p, Compiler *c); |
