ProjectExplorer: Allow users to override the gcc target triple

... for the clang code model. Otherwise, it won't work with GCC
compilers for architectures clang does not know about.

Fixes: QTCREATORBUG-26913
Change-Id: I90115f2f562eae9922b90c500630ccf988542ca3
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2022-01-20 16:53:55 +01:00
parent b85e2bc17b
commit 6cec0e2033
9 changed files with 91 additions and 3 deletions

View File

@@ -254,7 +254,7 @@ void CompilerOptionsBuilder::addWordWidth()
void CompilerOptionsBuilder::addTargetTriple()
{
const QString target = m_explicitTarget.isEmpty()
const QString target = m_explicitTarget.isEmpty() || m_projectPart.targetTripleIsAuthoritative
? m_projectPart.toolChainTargetTriple : m_explicitTarget;
// Only "--target=" style is accepted in both g++ and cl driver modes.

View File

@@ -153,6 +153,7 @@ ProjectPart::ProjectPart(const Utils::FilePath &topLevelProject,
toolchainType(tcInfo.type),
isMsvc2015Toolchain(tcInfo.isMsvc2015ToolChain),
toolChainTargetTriple(tcInfo.targetTriple),
targetTripleIsAuthoritative(tcInfo.targetTripleIsAuthoritative),
toolChainWordWidth(tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit
: ProjectPart::WordWidth32Bit),
toolChainInstallDir(tcInfo.installDir),

View File

@@ -114,6 +114,7 @@ public:
const Utils::Id toolchainType;
const bool isMsvc2015Toolchain = false;
const QString toolChainTargetTriple;
const bool targetTripleIsAuthoritative;
const ToolChainWordWidth toolChainWordWidth = WordWidth32Bit;
const Utils::FilePath toolChainInstallDir;
const Utils::FilePath compilerFilePath;

View File

@@ -42,11 +42,13 @@
#include <utils/qtcprocess.h>
#include <QBuffer>
#include <QCheckBox>
#include <QComboBox>
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QLoggingCategory>
#include <QRegularExpression>
@@ -1203,10 +1205,53 @@ Toolchains GccToolChainFactory::autoDetectToolChain(const ToolChainDescription &
// GccToolChainConfigWidget
// --------------------------------------------------------------------------
namespace Internal {
class TargetTripleWidget : public QWidget
{
Q_OBJECT
public:
TargetTripleWidget(const ToolChain *toolchain)
{
const auto layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
m_tripleLineEdit.setEnabled(false);
m_overrideCheckBox.setText(tr("Override for code model"));
m_overrideCheckBox.setToolTip(tr("Check this button in the rare case that the code model\n"
"fails because clang does not understand the target architecture."));
layout->addWidget(&m_tripleLineEdit);
layout->addWidget(&m_overrideCheckBox);
layout->addStretch(1);
connect(&m_tripleLineEdit, &QLineEdit::textEdited, this, &TargetTripleWidget::valueChanged);
connect(&m_overrideCheckBox, &QCheckBox::toggled,
&m_tripleLineEdit, &QLineEdit::setEnabled);
m_tripleLineEdit.setText(toolchain->effectiveCodeModelTargetTriple());
m_overrideCheckBox.setChecked(!toolchain->explicitCodeModelTargetTriple().isEmpty());
}
QString explicitCodeModelTargetTriple() const
{
if (m_overrideCheckBox.isChecked())
return m_tripleLineEdit.text();
return {};
}
signals:
void valueChanged();
private:
QLineEdit m_tripleLineEdit;
QCheckBox m_overrideCheckBox;
};
}
GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
ToolChainConfigWidget(tc),
m_abiWidget(new AbiWidget),
m_compilerCommand(new PathChooser)
m_compilerCommand(new PathChooser),
m_targetTripleWidget(new TargetTripleWidget(tc))
{
Q_ASSERT(tc);
@@ -1222,6 +1267,7 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
m_platformLinkerFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->platformLinkerFlags()));
m_mainLayout->addRow(tr("Platform linker flags:"), m_platformLinkerFlagsLineEdit);
m_mainLayout->addRow(tr("&ABI:"), m_abiWidget);
m_mainLayout->addRow(tr("Target triple:"), m_targetTripleWidget);
m_abiWidget->setEnabled(false);
addErrorLabel();
@@ -1235,6 +1281,8 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
connect(m_platformLinkerFlagsLineEdit, &QLineEdit::editingFinished,
this, &GccToolChainConfigWidget::handlePlatformLinkerFlagsChange);
connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty);
connect(m_targetTripleWidget, &TargetTripleWidget::valueChanged,
this, &ToolChainConfigWidget::dirty);
}
void GccToolChainConfigWidget::applyImpl()
@@ -1252,6 +1300,7 @@ void GccToolChainConfigWidget::applyImpl()
}
tc->setInstallDir(tc->detectInstallDir());
tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple);
tc->setExplicitCodeModelTargetTriple(m_targetTripleWidget->explicitCodeModelTargetTriple());
tc->setDisplayName(displayName); // reset display name
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->text()));
@@ -1290,6 +1339,8 @@ bool GccToolChainConfigWidget::isDirtyImpl() const
!= ProcessArgs::joinArgs(tc->platformCodeGenFlags())
|| m_platformLinkerFlagsLineEdit->text()
!= ProcessArgs::joinArgs(tc->platformLinkerFlags())
|| m_targetTripleWidget->explicitCodeModelTargetTriple()
!= tc->explicitCodeModelTargetTriple()
|| (m_abiWidget && m_abiWidget->currentAbi() != tc->targetAbi());
}
@@ -1300,6 +1351,7 @@ void GccToolChainConfigWidget::makeReadOnlyImpl()
m_abiWidget->setEnabled(false);
m_platformCodeGenFlagsLineEdit->setEnabled(false);
m_platformLinkerFlagsLineEdit->setEnabled(false);
m_targetTripleWidget->setEnabled(false);
m_isReadOnly = true;
}
@@ -2103,3 +2155,5 @@ void ProjectExplorerPlugin::testGccAbiGuessing()
} // namespace ProjectExplorer
#endif
#include <gcctoolchain.moc>

View File

@@ -71,6 +71,8 @@ protected:
// GccToolChainConfigWidget
// --------------------------------------------------------------------------
class TargetTripleWidget;
class GccToolChainConfigWidget : public ToolChainConfigWidget
{
Q_OBJECT
@@ -96,6 +98,7 @@ private:
Utils::PathChooser *m_compilerCommand;
QLineEdit *m_platformCodeGenFlagsLineEdit;
QLineEdit *m_platformLinkerFlagsLineEdit;
TargetTripleWidget * const m_targetTripleWidget;
bool m_isReadOnly = false;
ProjectExplorer::Macros m_macros;

View File

@@ -182,7 +182,8 @@ ToolChainInfo::ToolChainInfo(const ToolChain *toolChain,
type = toolChain->typeId();
isMsvc2015ToolChain = toolChain->targetAbi().osFlavor() == Abi::WindowsMsvc2015Flavor;
wordWidth = toolChain->targetAbi().wordWidth();
targetTriple = toolChain->originalTargetTriple();
targetTriple = toolChain->effectiveCodeModelTargetTriple();
targetTripleIsAuthoritative = !toolChain->explicitCodeModelTargetTriple().isEmpty();
extraCodeModelFlags = toolChain->extraCodeModelFlags();
installDir = toolChain->installDir();
compilerFilePath = toolChain->compilerCommand();

View File

@@ -154,6 +154,7 @@ public:
public:
Utils::Id type;
bool isMsvc2015ToolChain = false;
bool targetTripleIsAuthoritative = false;
unsigned wordWidth = 0;
QString targetTriple;
Utils::FilePath compilerFilePath;

View File

@@ -49,6 +49,7 @@ static const char AUTODETECT_KEY[] = "ProjectExplorer.ToolChain.Autodetect";
static const char DETECTION_SOURCE_KEY[] = "ProjectExplorer.ToolChain.DetectionSource";
static const char LANGUAGE_KEY_V1[] = "ProjectExplorer.ToolChain.Language"; // For QtCreator <= 4.2
static const char LANGUAGE_KEY_V2[] = "ProjectExplorer.ToolChain.LanguageV2"; // For QtCreator > 4.2
const char CODE_MODEL_TRIPLE_KEY[] = "ExplicitCodeModelTargetTriple";
namespace ProjectExplorer {
namespace Internal {
@@ -86,6 +87,7 @@ public:
Utils::Id m_language;
Detection m_detection = ToolChain::UninitializedDetection;
QString m_detectionSource;
QString m_explicitCodeModelTargetTriple;
ToolChain::MacrosCache m_predefinedMacrosCache;
ToolChain::HeaderPathsCache m_headerPathsCache;
@@ -262,6 +264,7 @@ QVariantMap ToolChain::toMap() const
result.insert(QLatin1String(DISPLAY_NAME_KEY), displayName());
result.insert(QLatin1String(AUTODETECT_KEY), isAutoDetected());
result.insert(QLatin1String(DETECTION_SOURCE_KEY), d->m_detectionSource);
result.insert(CODE_MODEL_TRIPLE_KEY, d->m_explicitCodeModelTargetTriple);
// <Compatibility with QtC 4.2>
int oldLanguageId = -1;
if (language() == ProjectExplorer::Constants::C_LANGUAGE_ID)
@@ -370,6 +373,8 @@ bool ToolChain::fromMap(const QVariantMap &data)
d->m_detection = autoDetect ? AutoDetection : ManualDetection;
d->m_detectionSource = data.value(DETECTION_SOURCE_KEY).toString();
d->m_explicitCodeModelTargetTriple = data.value(CODE_MODEL_TRIPLE_KEY).toString();
if (data.contains(LANGUAGE_KEY_V2)) {
// remove hack to trim language id in 4.4: This is to fix up broken language
// ids that happened in 4.3 master branch
@@ -503,6 +508,24 @@ QString ToolChain::sysRoot() const
return QString();
}
QString ToolChain::explicitCodeModelTargetTriple() const
{
return d->m_explicitCodeModelTargetTriple;
}
QString ToolChain::effectiveCodeModelTargetTriple() const
{
const QString overridden = explicitCodeModelTargetTriple();
if (!overridden.isEmpty())
return overridden;
return originalTargetTriple();
}
void ToolChain::setExplicitCodeModelTargetTriple(const QString &triple)
{
d->m_explicitCodeModelTargetTriple = triple;
}
/*!
\class ProjectExplorer::ToolChainFactory
\brief The ToolChainFactory class creates tool chains from settings or

View File

@@ -127,6 +127,10 @@ public:
virtual QStringList includedFiles(const QStringList &flags, const QString &directory) const;
virtual QString sysRoot() const;
QString explicitCodeModelTargetTriple() const;
QString effectiveCodeModelTargetTriple() const;
void setExplicitCodeModelTargetTriple(const QString &triple);
class MacroInspectionReport
{
public: