From ce0b671d0a88eeb18300cebf7dbe3ed461f21b2c Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Mon, 7 Jan 2019 12:15:40 +0100 Subject: [PATCH] ProjectExplorer: Fix Clang toolchain setup on Windows Clang toolchain in gcc mode requires mingw sysroot and target in order to be used properly on Windows. Requires Qt >= 5.12 to work properly (it has the required mkspec). Change-Id: I4e5a734c699ac98740c0d50560aa7b69751ae58c Reviewed-by: Christian Kandeler --- .../cmakebuildconfiguration.cpp | 13 + src/plugins/projectexplorer/gcctoolchain.cpp | 267 +++++++++++++++++- src/plugins/projectexplorer/gcctoolchain.h | 16 ++ .../projectexplorer/gcctoolchainfactories.h | 29 +- .../projectexplorer/kitinformation.cpp | 27 +- src/plugins/projectexplorer/toolchain.cpp | 5 + src/plugins/projectexplorer/toolchain.h | 1 + src/plugins/qmakeprojectmanager/qmakestep.cpp | 19 +- src/plugins/qmakeprojectmanager/qmakestep.h | 2 + 9 files changed, 358 insertions(+), 21 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index c286e63ea8c..66d3ba5fbeb 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -500,6 +501,18 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp if (!buildTypeItem.isNull()) info->configuration.append(buildTypeItem); + const QString sysRoot = SysRootKitInformation::sysRoot(k).toString(); + if (!sysRoot.isEmpty()) { + info->configuration.append(CMakeConfigItem("CMAKE_SYSROOT", sysRoot.toUtf8())); + ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain( + k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + if (tc) { + const QByteArray targetTriple = tc->originalTargetTriple().toUtf8(); + info->configuration.append(CMakeConfigItem("CMAKE_C_COMPILER_TARGET", targetTriple)); + info->configuration.append(CMakeConfigItem("CMAKE_CXX_COMPILER_TARGET ", targetTriple)); + } + } + return info; } diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 004b362a3c9..9eca6bfe3d5 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -74,6 +75,7 @@ static const char compilerPlatformLinkerFlagsKeyC[] = "ProjectExplorer.GccToolCh static const char targetAbiKeyC[] = "ProjectExplorer.GccToolChain.TargetAbi"; static const char originalTargetTripleKeyC[] = "ProjectExplorer.GccToolChain.OriginalTargetTriple"; static const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis"; +static const char parentToolChainIdKeyC[] = "ProjectExplorer.ClangToolChain.ParentToolChainId"; static const char binaryRegexp[] = "(?:^|-|\\b)(?:gcc|g\\+\\+|clang(?:\\+\\+)?)(?:-([\\d.]+))?$"; static QByteArray runGcc(const FileName &gcc, const QStringList &arguments, const QStringList &env) @@ -1042,8 +1044,8 @@ QList GccToolChainFactory::autoDetectToolChain(const FileName &comp GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) : ToolChainConfigWidget(tc), - m_compilerCommand(new PathChooser), - m_abiWidget(new AbiWidget) + m_abiWidget(new AbiWidget), + m_compilerCommand(new PathChooser) { Q_ASSERT(tc); @@ -1083,8 +1085,10 @@ void GccToolChainConfigWidget::applyImpl() Q_ASSERT(tc); QString displayName = tc->displayName(); tc->setCompilerCommand(m_compilerCommand->fileName()); - tc->setSupportedAbis(m_abiWidget->supportedAbis()); - tc->setTargetAbi(m_abiWidget->currentAbi()); + if (m_abiWidget) { + tc->setSupportedAbis(m_abiWidget->supportedAbis()); + tc->setTargetAbi(m_abiWidget->currentAbi()); + } tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple); tc->setDisplayName(displayName); // reset display name tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text())); @@ -1108,9 +1112,11 @@ void GccToolChainConfigWidget::setFromToolchain() m_compilerCommand->setFileName(tc->compilerCommand()); m_platformCodeGenFlagsLineEdit->setText(QtcProcess::joinArgs(tc->platformCodeGenFlags())); m_platformLinkerFlagsLineEdit->setText(QtcProcess::joinArgs(tc->platformLinkerFlags())); - m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi()); - if (!m_isReadOnly && !m_compilerCommand->path().isEmpty()) - m_abiWidget->setEnabled(true); + if (m_abiWidget) { + m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi()); + if (!m_isReadOnly && !m_compilerCommand->path().isEmpty()) + m_abiWidget->setEnabled(true); + } } bool GccToolChainConfigWidget::isDirtyImpl() const @@ -1118,15 +1124,18 @@ bool GccToolChainConfigWidget::isDirtyImpl() const auto tc = static_cast(toolChain()); Q_ASSERT(tc); return m_compilerCommand->fileName() != tc->compilerCommand() - || m_platformCodeGenFlagsLineEdit->text() != QtcProcess::joinArgs(tc->platformCodeGenFlags()) - || m_platformLinkerFlagsLineEdit->text() != QtcProcess::joinArgs(tc->platformLinkerFlags()) - || m_abiWidget->currentAbi() != tc->targetAbi(); + || m_platformCodeGenFlagsLineEdit->text() + != QtcProcess::joinArgs(tc->platformCodeGenFlags()) + || m_platformLinkerFlagsLineEdit->text() + != QtcProcess::joinArgs(tc->platformLinkerFlags()) + || (m_abiWidget && m_abiWidget->currentAbi() != tc->targetAbi()); } void GccToolChainConfigWidget::makeReadOnlyImpl() { m_compilerCommand->setReadOnly(true); - m_abiWidget->setEnabled(false); + if (m_abiWidget) + m_abiWidget->setEnabled(false); m_platformCodeGenFlagsLineEdit->setEnabled(false); m_platformLinkerFlagsLineEdit->setEnabled(false); m_isReadOnly = true; @@ -1150,6 +1159,9 @@ QStringList GccToolChainConfigWidget::splitString(const QString &s) void GccToolChainConfigWidget::handleCompilerCommandChange() { + if (!m_abiWidget) + return; + bool haveCompiler = false; Abi currentAbi = m_abiWidget->currentAbi(); bool customAbi = m_abiWidget->isCustomAbi() && m_abiWidget->isEnabled(); @@ -1207,13 +1219,76 @@ void GccToolChainConfigWidget::handlePlatformLinkerFlagsChange() // ClangToolChain // -------------------------------------------------------------------------- +static QList mingwToolChains() +{ + return ToolChainManager::toolChains([](const ToolChain *tc) -> bool { + return tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID; + }); +} + +static const MingwToolChain *mingwToolChainFromId(const QByteArray &id) +{ + if (id.isEmpty()) + return nullptr; + + for (const ToolChain *tc : mingwToolChains()) { + if (tc->id() == id) + return static_cast(tc); + } + + return nullptr; +} + +void ClangToolChain::syncAutodetectedWithParentToolchains() +{ + if (!HostOsInfo::isWindowsHost() || !isAutoDetected()) + return; + + QObject::disconnect(m_thisToolchainRemovedConnection); + QObject::disconnect(m_mingwToolchainAddedConnection); + + if (!mingwToolChainFromId(m_parentToolChainId)) { + const QList mingwTCs = mingwToolChains(); + m_parentToolChainId = mingwTCs.isEmpty() ? "" : mingwTCs.front()->id(); + } + + // Subscribe only autodetected toolchains. + ToolChainManager *tcManager = ToolChainManager::instance(); + m_mingwToolchainAddedConnection + = QObject::connect(tcManager, &ToolChainManager::toolChainAdded, [this](ToolChain *tc) { + if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID + && !mingwToolChainFromId(m_parentToolChainId)) { + m_parentToolChainId = tc->id(); + } + }); + m_thisToolchainRemovedConnection + = QObject::connect(tcManager, &ToolChainManager::toolChainRemoved, [this](ToolChain *tc) { + if (tc == this) { + QObject::disconnect(m_thisToolchainRemovedConnection); + QObject::disconnect(m_mingwToolchainAddedConnection); + } else if (m_parentToolChainId == tc->id()) { + const QList mingwTCs = mingwToolChains(); + m_parentToolChainId = mingwTCs.isEmpty() ? "" : mingwTCs.front()->id(); + } + }); +} + ClangToolChain::ClangToolChain(Detection d) : GccToolChain(Constants::CLANG_TOOLCHAIN_TYPEID, d) -{ } +{ + syncAutodetectedWithParentToolchains(); +} ClangToolChain::ClangToolChain(Core::Id typeId, ToolChain::Detection d) : GccToolChain(typeId, d) -{ } +{ + syncAutodetectedWithParentToolchains(); +} + +ClangToolChain::ClangToolChain(const ClangToolChain &other) + : GccToolChain(other) + , m_parentToolChainId(other.m_parentToolChainId) +{} QString ClangToolChain::typeDisplayName() const { @@ -1261,22 +1336,30 @@ WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const FileNameList ClangToolChain::suggestedMkspecList() const { Abi abi = targetAbi(); - if (abi.os() == Abi::DarwinOS) + if (abi.os() == Abi::DarwinOS) { return FileNameList() << FileName::fromLatin1("macx-clang") << FileName::fromLatin1("macx-clang-32") << FileName::fromLatin1("unsupported/macx-clang") << FileName::fromLatin1("macx-ios-clang"); - else if (abi.os() == Abi::LinuxOS) + } else if (abi.os() == Abi::LinuxOS) { return FileNameList() << FileName::fromLatin1("linux-clang") << FileName::fromLatin1("unsupported/linux-clang"); + } else if (abi.os() == Abi::WindowsOS) { + return FileNameList() << FileName::fromLatin1("win32-clang-g++"); + } return FileNameList(); // Note: Not supported by Qt yet, so default to the mkspec the Qt was build with } void ClangToolChain::addToEnvironment(Environment &env) const { GccToolChain::addToEnvironment(env); + + const QString sysroot = sysRoot(); + if (!sysroot.isEmpty()) + env.prependOrSetPath(sysroot + "/bin"); + // Clang takes PWD as basis for debug info, if set. // When running Qt Creator from a shell, PWD is initially set to an "arbitrary" value. // Since the tools are not called through a shell, PWD is never changed to the actual cwd, @@ -1284,6 +1367,47 @@ void ClangToolChain::addToEnvironment(Environment &env) const env.unset("PWD"); } +QString ClangToolChain::originalTargetTriple() const +{ + const MingwToolChain *parentTC = mingwToolChainFromId(m_parentToolChainId); + if (parentTC) + return parentTC->originalTargetTriple(); + + return GccToolChain::originalTargetTriple(); +} + +QString ClangToolChain::sysRoot() const +{ + const MingwToolChain *parentTC = mingwToolChainFromId(m_parentToolChainId); + if (!parentTC) + return QString(); + + const FileName mingwCompiler = parentTC->compilerCommand(); + return mingwCompiler.parentDir().parentDir().toString(); +} + +std::unique_ptr ClangToolChain::createConfigurationWidget() +{ + return std::make_unique(this); +} + +QVariantMap ClangToolChain::toMap() const +{ + QVariantMap data = GccToolChain::toMap(); + data.insert(parentToolChainIdKeyC, m_parentToolChainId); + return data; +} + +bool ClangToolChain::fromMap(const QVariantMap &data) +{ + if (!GccToolChain::fromMap(data)) + return false; + + m_parentToolChainId = data.value(parentToolChainIdKeyC).toByteArray(); + syncAutodetectedWithParentToolchains(); + return true; +} + LanguageExtensions ClangToolChain::defaultLanguageExtensions() const { return LanguageExtension::Gnu; @@ -1341,6 +1465,7 @@ QList ClangToolChainFactory::autoDetect(const QList &a hostAbi, Constants::C_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown)); } + return tcs; } @@ -1363,6 +1488,118 @@ GccToolChain *ClangToolChainFactory::createToolChain(bool autoDetect) return new ClangToolChain(autoDetect ? ToolChain::AutoDetection : ToolChain::ManualDetection); } +ClangToolChainConfigWidget::ClangToolChainConfigWidget(ClangToolChain *tc) : + GccToolChainConfigWidget(tc) +{ + if (!HostOsInfo::isWindowsHost()) + return; + + // Remove m_abiWidget row because the parent toolchain abi is going to be used. + m_mainLayout->removeRow(m_mainLayout->rowCount() - 2); + m_abiWidget = nullptr; + + m_parentToolchainCombo = new QComboBox(this); + m_mainLayout->insertRow(m_mainLayout->rowCount() - 1, + tr("Parent Toolchain:"), + m_parentToolchainCombo); + + ToolChainManager *tcManager = ToolChainManager::instance(); + m_parentToolChainConnections.append( + connect(tcManager, &ToolChainManager::toolChainUpdated, this, [this](ToolChain *tc) { + if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) + updateParentToolChainComboBox(); + })); + m_parentToolChainConnections.append( + connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](ToolChain *tc) { + if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) + updateParentToolChainComboBox(); + })); + m_parentToolChainConnections.append( + connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](ToolChain *tc) { + if (tc->id() == toolChain()->id()) { + for (QMetaObject::Connection &connection : m_parentToolChainConnections) + QObject::disconnect(connection); + return; + } + if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) + updateParentToolChainComboBox(); + })); + + setFromClangToolchain(); +} + +void ClangToolChainConfigWidget::updateParentToolChainComboBox() +{ + auto *tc = static_cast(toolChain()); + QByteArray parentId = m_parentToolchainCombo->currentData().toByteArray(); + if (tc->isAutoDetected() || m_parentToolchainCombo->count() == 0) + parentId = tc->m_parentToolChainId; + + const MingwToolChain *parentTC = mingwToolChainFromId(parentId); + + m_parentToolchainCombo->clear(); + m_parentToolchainCombo->addItem(parentTC ? parentTC->displayName() : "", + parentTC ? parentId : ""); + + if (tc->isAutoDetected()) + return; + + for (const ToolChain *mingwTC : mingwToolChains()) { + if (parentId != mingwTC->id()) + m_parentToolchainCombo->addItem(mingwTC->displayName(), mingwTC->id()); + } +} + +void ClangToolChainConfigWidget::setFromClangToolchain() +{ + GccToolChainConfigWidget::setFromToolchain(); + + if (m_parentToolchainCombo) + updateParentToolChainComboBox(); +} + +void ClangToolChainConfigWidget::applyImpl() +{ + GccToolChainConfigWidget::applyImpl(); + if (!m_parentToolchainCombo) + return; + + auto *tc = static_cast(toolChain()); + tc->m_parentToolChainId.clear(); + + const QByteArray parentId = m_parentToolchainCombo->currentData().toByteArray(); + if (!parentId.isEmpty()) { + for (const ToolChain *mingwTC : mingwToolChains()) { + if (parentId == mingwTC->id()) { + tc->m_parentToolChainId = mingwTC->id(); + break; + } + } + } +} + +bool ClangToolChainConfigWidget::isDirtyImpl() const +{ + if (GccToolChainConfigWidget::isDirtyImpl()) + return true; + + if (!m_parentToolchainCombo) + return false; + + auto tc = static_cast(toolChain()); + Q_ASSERT(tc); + const MingwToolChain *parentTC = mingwToolChainFromId(tc->m_parentToolChainId); + const QByteArray parentId = parentTC ? parentTC->id() : ""; + return parentId != m_parentToolchainCombo->currentData(); +} + +void ClangToolChainConfigWidget::makeReadOnlyImpl() +{ + GccToolChainConfigWidget::makeReadOnlyImpl(); + if (m_parentToolchainCombo) + m_parentToolchainCombo->setEnabled(false); +} + // -------------------------------------------------------------------------- // MingwToolChain // -------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 657aeae5bc3..b34614cde88 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -42,6 +42,7 @@ namespace ProjectExplorer { namespace Internal { class ClangToolChainFactory; +class ClangToolChainConfigWidget; class GccToolChainConfigWidget; class GccToolChainFactory; class MingwToolChainFactory; @@ -208,6 +209,7 @@ class PROJECTEXPLORER_EXPORT ClangToolChain : public GccToolChain public: explicit ClangToolChain(Detection d); ClangToolChain(Core::Id typeId, Detection d); + ClangToolChain(const ClangToolChain &other); QString typeDisplayName() const override; QString makeCommand(const Utils::Environment &environment) const override; @@ -221,11 +223,25 @@ public: Utils::FileNameList suggestedMkspecList() const override; void addToEnvironment(Utils::Environment &env) const override; + QString originalTargetTriple() const override; + QString sysRoot() const override; + + std::unique_ptr createConfigurationWidget() override; + + QVariantMap toMap() const override; + bool fromMap(const QVariantMap &data) override; + protected: Utils::LanguageExtensions defaultLanguageExtensions() const override; + void syncAutodetectedWithParentToolchains(); private: + QByteArray m_parentToolChainId; + QMetaObject::Connection m_mingwToolchainAddedConnection; + QMetaObject::Connection m_thisToolchainRemovedConnection; + friend class Internal::ClangToolChainFactory; + friend class Internal::ClangToolChainConfigWidget; friend class ToolChainFactory; }; diff --git a/src/plugins/projectexplorer/gcctoolchainfactories.h b/src/plugins/projectexplorer/gcctoolchainfactories.h index 54d4f417825..775e0db6750 100644 --- a/src/plugins/projectexplorer/gcctoolchainfactories.h +++ b/src/plugins/projectexplorer/gcctoolchainfactories.h @@ -40,6 +40,7 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; } namespace ProjectExplorer { +class ClangToolChain; class GccToolChain; namespace Internal { @@ -91,7 +92,7 @@ public: explicit GccToolChainConfigWidget(GccToolChain *tc); static QStringList splitString(const QString &s); -private: +protected: void handleCompilerCommandChange(); void handlePlatformCodeGenFlagsChange(); void handlePlatformLinkerFlagsChange(); @@ -103,15 +104,39 @@ private: void setFromToolchain(); + AbiWidget *m_abiWidget; + +private: Utils::PathChooser *m_compilerCommand; QLineEdit *m_platformCodeGenFlagsLineEdit; QLineEdit *m_platformLinkerFlagsLineEdit; - AbiWidget *m_abiWidget; bool m_isReadOnly = false; ProjectExplorer::Macros m_macros; }; +// -------------------------------------------------------------------------- +// ClangToolChainConfigWidget +// -------------------------------------------------------------------------- + +class ClangToolChainConfigWidget : public GccToolChainConfigWidget +{ + Q_OBJECT +public: + explicit ClangToolChainConfigWidget(ClangToolChain *tc); + +private: + void applyImpl() override; + void discardImpl() override { setFromClangToolchain(); } + bool isDirtyImpl() const override; + void makeReadOnlyImpl() override; + + void setFromClangToolchain(); + void updateParentToolChainComboBox(); + QList m_parentToolChainConnections; + QComboBox *m_parentToolchainCombo = nullptr; +}; + // -------------------------------------------------------------------------- // ClangToolChainFactory // -------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 16de69382e9..c093678645b 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -121,13 +121,34 @@ Utils::FileName SysRootKitInformation::sysRoot(const Kit *k) { if (!k) return Utils::FileName(); - return Utils::FileName::fromString(k->value(SysRootKitInformation::id()).toString()); + + if (!k->value(SysRootKitInformation::id()).toString().isEmpty()) + return Utils::FileName::fromString(k->value(SysRootKitInformation::id()).toString()); + + for (ToolChain *tc : ToolChainKitInformation::toolChains(k)) { + if (!tc->sysRoot().isEmpty()) + return Utils::FileName::fromString(tc->sysRoot()); + } + + return Utils::FileName(); } void SysRootKitInformation::setSysRoot(Kit *k, const Utils::FileName &v) { - if (k) - k->setValue(SysRootKitInformation::id(), v.toString()); + if (!k) + return; + + for (ToolChain *tc : ToolChainKitInformation::toolChains(k)) { + if (!tc->sysRoot().isEmpty()) { + // It's the sysroot from toolchain, don't set it. + if (tc->sysRoot() == v.toString()) + return; + + // We've changed the default toolchain sysroot, set it. + break; + } + } + k->setValue(SysRootKitInformation::id(), v.toString()); } // -------------------------------------------------------------------------- diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 4e42075eb5c..212427417a3 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -362,6 +362,11 @@ QList ToolChain::validateKit(const Kit *) const return QList(); } +QString ToolChain::sysRoot() const +{ + return QString(); +} + /*! \class ProjectExplorer::ToolChainFactory \brief The ToolChainFactory class creates tool chains from settings or diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 163f6098adf..8925b449a45 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -110,6 +110,7 @@ public: virtual Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const = 0; virtual WarningFlags warningFlags(const QStringList &cflags) const = 0; + virtual QString sysRoot() const; class MacroInspectionReport { diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 9eef5dd6d93..5dc875206fd 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -145,8 +145,14 @@ QMakeStepConfig QMakeStep::deducedArguments() const ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); ProjectExplorer::Abi targetAbi; - if (tc) + if (tc) { targetAbi = tc->targetAbi(); + if (HostOsInfo::isWindowsHost() + && tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) { + config.sysRoot = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); + config.targetTriple = tc->originalTargetTriple(); + } + } BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); @@ -902,5 +908,16 @@ QStringList QMakeStepConfig::toArguments() const if (separateDebugInfo) arguments << "CONFIG+=force_debug_info" << "CONFIG+=separate_debug_info"; + if (!sysRoot.isEmpty()) { + arguments << ("QMAKE_CFLAGS+=--sysroot=\"" + sysRoot + "\""); + arguments << ("QMAKE_CXXFLAGS+=--sysroot=\"" + sysRoot + "\""); + arguments << ("QMAKE_LFLAGS+=--sysroot=\"" + sysRoot + "\""); + if (!targetTriple.isEmpty()) { + arguments << ("QMAKE_CFLAGS+=--target=" + targetTriple); + arguments << ("QMAKE_CXXFLAGS+=--target=" + targetTriple); + arguments << ("QMAKE_LFLAGS+=--target=" + targetTriple); + } + } + return arguments; } diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index 0555bab437f..891cadc697b 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -76,6 +76,8 @@ public: QStringList toArguments() const; // Actual data + QString sysRoot; + QString targetTriple; TargetArchConfig archConfig = NoArch; OsType osType = NoOsType; bool linkQmlDebuggingQQ2 = false;