2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2017 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2011-02-01 18:36:00 +01:00
|
|
|
|
|
|
|
|
#include "gcctoolchain.h"
|
2022-01-21 10:44:53 +01:00
|
|
|
|
|
|
|
|
#include "abiwidget.h"
|
2011-05-18 18:38:58 +02:00
|
|
|
#include "clangparser.h"
|
2022-04-12 21:01:45 +02:00
|
|
|
#include "devicesupport/idevice.h"
|
2011-02-01 18:36:00 +01:00
|
|
|
#include "gccparser.h"
|
|
|
|
|
#include "linuxiccparser.h"
|
2023-01-13 12:38:22 +01:00
|
|
|
#include "projectexplorertr.h"
|
2017-02-07 15:00:38 +01:00
|
|
|
#include "projectmacro.h"
|
2022-01-21 10:44:53 +01:00
|
|
|
#include "toolchainconfigwidget.h"
|
2011-03-31 10:13:35 +02:00
|
|
|
#include "toolchainmanager.h"
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2018-08-06 12:30:32 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2019-09-26 18:27:46 +02:00
|
|
|
#include <coreplugin/messagemanager.h>
|
2018-08-06 12:30:32 +02:00
|
|
|
|
2014-07-07 19:02:26 +02:00
|
|
|
#include <utils/algorithm.h>
|
2011-02-01 18:36:00 +01:00
|
|
|
#include <utils/environment.h>
|
2012-08-23 15:53:58 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
2011-02-28 16:50:14 +01:00
|
|
|
#include <utils/pathchooser.h>
|
2023-05-03 17:05:35 +02:00
|
|
|
#include <utils/process.h>
|
2013-07-25 15:18:23 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QBuffer>
|
2022-01-20 16:53:55 +01:00
|
|
|
#include <QCheckBox>
|
2019-01-07 12:15:40 +01:00
|
|
|
#include <QComboBox>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QCoreApplication>
|
2017-07-14 15:47:03 +03:00
|
|
|
#include <QDir>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QFileInfo>
|
|
|
|
|
#include <QFormLayout>
|
2022-01-20 16:53:55 +01:00
|
|
|
#include <QHBoxLayout>
|
2017-07-17 22:35:06 +03:00
|
|
|
#include <QLineEdit>
|
2017-10-27 16:02:06 +02:00
|
|
|
#include <QLoggingCategory>
|
2017-07-17 22:35:06 +03:00
|
|
|
#include <QRegularExpression>
|
2020-01-08 11:18:43 +01:00
|
|
|
#include <QTimer>
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2017-02-07 13:05:12 +01:00
|
|
|
#include <memory>
|
|
|
|
|
|
2017-10-27 16:02:06 +02:00
|
|
|
namespace {
|
2020-01-15 14:39:23 +01:00
|
|
|
static Q_LOGGING_CATEGORY(gccLog, "qtc.projectexplorer.toolchain.gcc", QtWarningMsg);
|
2017-10-27 16:02:06 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
2012-08-21 13:29:16 +02:00
|
|
|
using namespace Utils;
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
namespace ProjectExplorer {
|
2022-01-21 10:44:53 +01:00
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
class TargetTripleWidget;
|
|
|
|
|
class GccToolChainConfigWidget : public ToolChainConfigWidget
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit GccToolChainConfigWidget(GccToolChain *tc);
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void handleCompilerCommandChange();
|
|
|
|
|
void handlePlatformCodeGenFlagsChange();
|
|
|
|
|
void handlePlatformLinkerFlagsChange();
|
|
|
|
|
|
|
|
|
|
void applyImpl() override;
|
|
|
|
|
void discardImpl() override { setFromToolchain(); }
|
|
|
|
|
bool isDirtyImpl() const override;
|
|
|
|
|
void makeReadOnlyImpl() override;
|
|
|
|
|
|
|
|
|
|
void setFromToolchain();
|
|
|
|
|
|
|
|
|
|
AbiWidget *m_abiWidget;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Utils::PathChooser *m_compilerCommand;
|
|
|
|
|
QLineEdit *m_platformCodeGenFlagsLineEdit;
|
|
|
|
|
QLineEdit *m_platformLinkerFlagsLineEdit;
|
|
|
|
|
TargetTripleWidget * const m_targetTripleWidget;
|
|
|
|
|
|
|
|
|
|
bool m_isReadOnly = false;
|
|
|
|
|
ProjectExplorer::Macros m_macros;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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<QMetaObject::Connection> m_parentToolChainConnections;
|
|
|
|
|
QComboBox *m_parentToolchainCombo = nullptr;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
using namespace Internal;
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// Helpers:
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2022-07-01 09:42:53 +02:00
|
|
|
const char compilerPlatformCodeGenFlagsKeyC[] = "ProjectExplorer.GccToolChain.PlatformCodeGenFlags";
|
|
|
|
|
const char compilerPlatformLinkerFlagsKeyC[] = "ProjectExplorer.GccToolChain.PlatformLinkerFlags";
|
|
|
|
|
const char targetAbiKeyC[] = "ProjectExplorer.GccToolChain.TargetAbi";
|
|
|
|
|
const char originalTargetTripleKeyC[] = "ProjectExplorer.GccToolChain.OriginalTargetTriple";
|
|
|
|
|
const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis";
|
|
|
|
|
const char parentToolChainIdKeyC[] = "ProjectExplorer.ClangToolChain.ParentToolChainId";
|
2022-08-17 11:14:11 +02:00
|
|
|
const char priorityKeyC[] = "ProjectExplorer.ClangToolChain.Priority";
|
2022-07-01 09:42:53 +02:00
|
|
|
const char binaryRegexp[] = "(?:^|-|\\b)(?:gcc|g\\+\\+|clang(?:\\+\\+)?)(?:-([\\d.]+))?$";
|
|
|
|
|
|
|
|
|
|
static QString runGcc(const FilePath &gcc, const QStringList &arguments, const Environment &env)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2021-04-29 13:12:24 +02:00
|
|
|
if (!gcc.isExecutableFile())
|
2022-07-01 09:42:53 +02:00
|
|
|
return {};
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2023-05-03 16:00:22 +02:00
|
|
|
Process cpp;
|
2021-04-30 17:50:30 +02:00
|
|
|
Environment environment(env);
|
2021-05-20 11:57:21 +02:00
|
|
|
environment.setupEnglishOutput();
|
2011-07-29 08:53:00 +00:00
|
|
|
|
|
|
|
|
cpp.setEnvironment(environment);
|
2016-04-29 16:52:58 +02:00
|
|
|
cpp.setTimeoutS(10);
|
2021-05-17 12:02:42 +02:00
|
|
|
cpp.setCommand({gcc, arguments});
|
|
|
|
|
cpp.runBlocking();
|
2022-03-02 04:12:25 +01:00
|
|
|
if (cpp.result() != ProcessResult::FinishedWithSuccess || cpp.exitCode() != 0) {
|
2020-12-01 15:01:12 +01:00
|
|
|
Core::MessageManager::writeFlashing({"Compiler feature detection failure!",
|
2021-05-14 13:12:46 +02:00
|
|
|
cpp.exitMessage(),
|
2022-07-01 09:42:53 +02:00
|
|
|
cpp.allOutput()});
|
|
|
|
|
return {};
|
2013-09-02 17:23:59 +02:00
|
|
|
}
|
|
|
|
|
|
2022-07-01 09:42:53 +02:00
|
|
|
return cpp.allOutput();
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
static ProjectExplorer::Macros gccPredefinedMacros(const FilePath &gcc,
|
2017-02-07 15:00:38 +01:00
|
|
|
const QStringList &args,
|
2021-05-14 06:13:03 +02:00
|
|
|
const Environment &env)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2013-09-09 15:47:46 +02:00
|
|
|
QStringList arguments = args;
|
2016-11-24 14:57:07 +01:00
|
|
|
arguments << "-";
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2022-07-01 09:42:53 +02:00
|
|
|
ProjectExplorer::Macros predefinedMacros = Macro::toMacros(runGcc(gcc, arguments, env).toUtf8());
|
2013-07-25 15:18:23 +02:00
|
|
|
// Sanity check in case we get an error message instead of real output:
|
2017-02-07 15:00:38 +01:00
|
|
|
QTC_CHECK(predefinedMacros.isEmpty()
|
|
|
|
|
|| predefinedMacros.front().type == ProjectExplorer::MacroType::Define);
|
2015-02-03 23:59:04 +02:00
|
|
|
if (HostOsInfo::isMacHost()) {
|
2012-08-23 15:53:58 +02:00
|
|
|
// Turn off flag indicating Apple's blocks support
|
2017-02-07 15:00:38 +01:00
|
|
|
const ProjectExplorer::Macro blocksDefine("__BLOCKS__", "1");
|
|
|
|
|
const ProjectExplorer::Macro blocksUndefine("__BLOCKS__", ProjectExplorer::MacroType::Undefine);
|
2012-08-23 15:53:58 +02:00
|
|
|
const int idx = predefinedMacros.indexOf(blocksDefine);
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (idx != -1)
|
2017-02-07 15:00:38 +01:00
|
|
|
predefinedMacros[idx] = blocksUndefine;
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2012-08-23 15:53:58 +02:00
|
|
|
// Define __strong and __weak (used for Apple's GC extension of C) to be empty
|
2017-02-07 15:00:38 +01:00
|
|
|
predefinedMacros.append({"__strong"});
|
|
|
|
|
predefinedMacros.append({"__weak"});
|
2012-08-23 15:53:58 +02:00
|
|
|
}
|
2011-02-01 18:36:00 +01:00
|
|
|
return predefinedMacros;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-14 06:13:03 +02:00
|
|
|
HeaderPaths GccToolChain::gccHeaderPaths(const FilePath &gcc,
|
|
|
|
|
const QStringList &arguments,
|
|
|
|
|
const Environment &env)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2018-09-17 11:29:32 +02:00
|
|
|
HeaderPaths builtInHeaderPaths;
|
2011-02-01 18:36:00 +01:00
|
|
|
QByteArray line;
|
2022-07-01 09:42:53 +02:00
|
|
|
QByteArray data = runGcc(gcc, arguments, env).toUtf8();
|
2011-02-01 18:36:00 +01:00
|
|
|
QBuffer cpp(&data);
|
2011-03-01 13:23:49 +01:00
|
|
|
cpp.open(QIODevice::ReadOnly);
|
2011-02-01 18:36:00 +01:00
|
|
|
while (cpp.canReadLine()) {
|
|
|
|
|
line = cpp.readLine();
|
|
|
|
|
if (line.startsWith("#include"))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!line.isEmpty() && line.startsWith("#include")) {
|
2018-09-13 11:44:43 +02:00
|
|
|
auto kind = HeaderPathType::User;
|
2011-02-01 18:36:00 +01:00
|
|
|
while (cpp.canReadLine()) {
|
|
|
|
|
line = cpp.readLine();
|
|
|
|
|
if (line.startsWith("#include")) {
|
2018-09-17 11:29:32 +02:00
|
|
|
kind = HeaderPathType::BuiltIn;
|
2016-11-24 14:57:07 +01:00
|
|
|
} else if (! line.isEmpty() && QChar(line.at(0)).isSpace()) {
|
2018-09-13 11:44:43 +02:00
|
|
|
HeaderPathType thisHeaderKind = kind;
|
2011-02-01 18:36:00 +01:00
|
|
|
|
|
|
|
|
line = line.trimmed();
|
|
|
|
|
|
|
|
|
|
const int index = line.indexOf(" (framework directory)");
|
|
|
|
|
if (index != -1) {
|
|
|
|
|
line.truncate(index);
|
2018-09-13 11:44:43 +02:00
|
|
|
thisHeaderKind = HeaderPathType::Framework;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 08:25:12 +01:00
|
|
|
const FilePath headerPath
|
2023-03-29 13:45:42 +02:00
|
|
|
= gcc.withNewPath(QString::fromUtf8(line)).canonicalPath();
|
2022-12-02 08:25:12 +01:00
|
|
|
|
|
|
|
|
if (!headerPath.isEmpty())
|
|
|
|
|
builtInHeaderPaths.append({headerPath, thisHeaderKind});
|
2011-02-01 18:36:00 +01:00
|
|
|
} else if (line.startsWith("End of search list.")) {
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
2012-01-09 16:30:33 +01:00
|
|
|
qWarning("%s: Ignoring line: %s", __FUNCTION__, line.constData());
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-17 11:29:32 +02:00
|
|
|
return builtInHeaderPaths;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 11:04:18 +02:00
|
|
|
static Abis guessGccAbi(const QString &m, const ProjectExplorer::Macros ¯os)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2019-05-27 11:04:18 +02:00
|
|
|
Abis abiList;
|
2011-03-10 14:44:49 +01:00
|
|
|
|
2013-08-23 11:45:39 +02:00
|
|
|
Abi guessed = Abi::abiFromTargetTriplet(m);
|
|
|
|
|
if (guessed.isNull())
|
2011-03-10 14:44:49 +01:00
|
|
|
return abiList;
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2013-08-23 11:45:39 +02:00
|
|
|
Abi::Architecture arch = guessed.architecture();
|
|
|
|
|
Abi::OS os = guessed.os();
|
|
|
|
|
Abi::OSFlavor flavor = guessed.osFlavor();
|
|
|
|
|
Abi::BinaryFormat format = guessed.binaryFormat();
|
|
|
|
|
int width = guessed.wordWidth();
|
2017-02-07 15:00:38 +01:00
|
|
|
|
|
|
|
|
const Macro sizeOfMacro = Utils::findOrDefault(macros, [](const Macro &m) { return m.key == "__SIZEOF_SIZE_T__"; });
|
|
|
|
|
if (sizeOfMacro.isValid() && sizeOfMacro.type == MacroType::Define)
|
|
|
|
|
width = sizeOfMacro.value.toInt() * 8;
|
|
|
|
|
const Macro &mscVerMacro = Utils::findOrDefault(macros, [](const Macro &m) { return m.key == "_MSC_VER"; });
|
|
|
|
|
if (mscVerMacro.type == MacroType::Define) {
|
|
|
|
|
const int msvcVersion = mscVerMacro.value.toInt();
|
2017-04-06 16:25:16 +03:00
|
|
|
flavor = Abi::flavorForMsvcVersion(msvcVersion);
|
|
|
|
|
}
|
2013-11-04 13:07:20 +01:00
|
|
|
|
2016-07-25 18:39:16 -07:00
|
|
|
if (os == Abi::DarwinOS) {
|
2011-03-10 14:44:49 +01:00
|
|
|
// Apple does PPC and x86!
|
2012-08-21 13:29:16 +02:00
|
|
|
abiList << Abi(arch, os, flavor, format, width);
|
|
|
|
|
abiList << Abi(arch, os, flavor, format, width == 64 ? 32 : 64);
|
2013-03-15 16:36:48 +01:00
|
|
|
} else if (arch == Abi::X86Architecture && (width == 0 || width == 64)) {
|
2013-11-04 13:07:20 +01:00
|
|
|
abiList << Abi(arch, os, flavor, format, 64);
|
2019-04-08 15:13:26 +02:00
|
|
|
if (width != 64 || (!m.contains("mingw")
|
|
|
|
|
&& ToolChainManager::detectionSettings().detectX64AsX32)) {
|
2019-04-02 13:49:34 +02:00
|
|
|
abiList << Abi(arch, os, flavor, format, 32);
|
2019-04-08 15:13:26 +02:00
|
|
|
}
|
2011-03-10 14:44:49 +01:00
|
|
|
} else {
|
2012-08-21 13:29:16 +02:00
|
|
|
abiList << Abi(arch, os, flavor, format, width);
|
2011-03-10 14:44:49 +01:00
|
|
|
}
|
|
|
|
|
return abiList;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-04 15:33:16 +01:00
|
|
|
|
2021-05-14 06:13:03 +02:00
|
|
|
static GccToolChain::DetectedAbisResult guessGccAbi(const FilePath &path,
|
|
|
|
|
const Environment &env,
|
|
|
|
|
const Macros ¯os,
|
|
|
|
|
const QStringList &extraArgs = {})
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2012-02-09 13:45:08 +01:00
|
|
|
if (path.isEmpty())
|
2016-03-04 15:33:16 +01:00
|
|
|
return GccToolChain::DetectedAbisResult();
|
2012-02-09 13:45:08 +01:00
|
|
|
|
2013-04-22 23:03:45 +02:00
|
|
|
QStringList arguments = extraArgs;
|
2016-11-24 14:57:07 +01:00
|
|
|
arguments << "-dumpmachine";
|
2022-07-01 09:42:53 +02:00
|
|
|
QString machine = runGcc(path, arguments, env).trimmed().section('\n', 0, 0, QString::SectionSkipEmpty);
|
2019-10-24 11:24:30 +02:00
|
|
|
if (machine.isEmpty()) {
|
|
|
|
|
// ICC does not implement the -dumpmachine option on macOS.
|
|
|
|
|
if (HostOsInfo::isMacHost() && (path.fileName() == "icc" || path.fileName() == "icpc"))
|
|
|
|
|
return GccToolChain::DetectedAbisResult({Abi::hostAbi()});
|
2016-03-04 15:33:16 +01:00
|
|
|
return GccToolChain::DetectedAbisResult(); // no need to continue if running failed once...
|
2019-10-24 11:24:30 +02:00
|
|
|
}
|
2016-03-04 15:33:16 +01:00
|
|
|
return GccToolChain::DetectedAbisResult(guessGccAbi(machine, macros), machine);
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2021-05-14 06:13:03 +02:00
|
|
|
static QString gccVersion(const FilePath &path,
|
|
|
|
|
const Environment &env,
|
2020-01-20 10:47:55 +01:00
|
|
|
const QStringList &extraArgs)
|
2011-09-06 15:19:05 +00:00
|
|
|
{
|
2020-01-20 10:47:55 +01:00
|
|
|
QStringList arguments = extraArgs;
|
|
|
|
|
arguments << "-dumpversion";
|
2022-07-01 09:42:53 +02:00
|
|
|
return runGcc(path, arguments, env).trimmed();
|
2011-09-06 15:19:05 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-14 13:01:28 +02:00
|
|
|
static FilePath gccInstallDir(const FilePath &compiler,
|
2021-05-14 06:13:03 +02:00
|
|
|
const Environment &env,
|
|
|
|
|
const QStringList &extraArgs = {})
|
2019-10-10 11:04:01 +02:00
|
|
|
{
|
2020-01-20 10:47:55 +01:00
|
|
|
QStringList arguments = extraArgs;
|
|
|
|
|
arguments << "-print-search-dirs";
|
2022-07-01 09:42:53 +02:00
|
|
|
QString output = runGcc(compiler, arguments, env).trimmed();
|
2019-10-10 11:04:01 +02:00
|
|
|
// Expected output looks like this:
|
|
|
|
|
// install: /usr/lib/gcc/x86_64-linux-gnu/7/
|
|
|
|
|
// ...
|
|
|
|
|
// Note that clang also supports "-print-search-dirs". However, the
|
|
|
|
|
// install dir is not part of the output (tested with clang-8/clang-9).
|
|
|
|
|
|
|
|
|
|
const QString prefix = "install: ";
|
|
|
|
|
const QString line = QTextStream(&output).readLine();
|
|
|
|
|
if (!line.startsWith(prefix))
|
|
|
|
|
return {};
|
2021-07-14 13:01:28 +02:00
|
|
|
return compiler.withNewPath(QDir::cleanPath(line.mid(prefix.size())));
|
2019-10-10 11:04:01 +02:00
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// GccToolChain
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2020-06-26 13:59:38 +02:00
|
|
|
GccToolChain::GccToolChain(Utils::Id typeId) :
|
2019-05-08 19:03:15 +02:00
|
|
|
ToolChain(typeId)
|
2019-06-19 17:28:20 +02:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setTypeDisplayName(Tr::tr("GCC"));
|
2020-11-10 14:05:58 +01:00
|
|
|
setTargetAbiKey(targetAbiKeyC);
|
2020-11-13 09:39:32 +01:00
|
|
|
setCompilerCommandKey("ProjectExplorer.GccToolChain.Path");
|
2014-07-21 14:23:09 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 11:04:18 +02:00
|
|
|
void GccToolChain::setSupportedAbis(const Abis &abis)
|
2014-07-21 14:23:09 +02:00
|
|
|
{
|
2019-05-27 11:04:18 +02:00
|
|
|
if (m_supportedAbis == abis)
|
2016-07-06 14:13:25 +02:00
|
|
|
return;
|
|
|
|
|
|
2019-05-27 11:04:18 +02:00
|
|
|
m_supportedAbis = abis;
|
2016-07-06 14:13:25 +02:00
|
|
|
toolChainUpdated();
|
2014-07-21 14:23:09 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-04 15:33:16 +01:00
|
|
|
void GccToolChain::setOriginalTargetTriple(const QString &targetTriple)
|
|
|
|
|
{
|
2016-07-06 14:13:25 +02:00
|
|
|
if (m_originalTargetTriple == targetTriple)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-03-04 15:33:16 +01:00
|
|
|
m_originalTargetTriple = targetTriple;
|
2016-07-06 14:13:25 +02:00
|
|
|
toolChainUpdated();
|
2016-03-04 15:33:16 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-10 11:04:01 +02:00
|
|
|
void GccToolChain::setInstallDir(const Utils::FilePath &installDir)
|
|
|
|
|
{
|
|
|
|
|
if (m_installDir == installDir)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_installDir = installDir;
|
|
|
|
|
toolChainUpdated();
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
QString GccToolChain::defaultDisplayName() const
|
|
|
|
|
{
|
2017-07-17 22:35:06 +03:00
|
|
|
QString type = typeDisplayName();
|
|
|
|
|
const QRegularExpression regexp(binaryRegexp);
|
2020-11-13 09:39:32 +01:00
|
|
|
const QRegularExpressionMatch match = regexp.match(compilerCommand().fileName());
|
2017-07-25 23:47:16 +03:00
|
|
|
if (match.lastCapturedIndex() >= 1)
|
2017-07-17 22:35:06 +03:00
|
|
|
type += ' ' + match.captured(1);
|
2020-11-10 14:05:58 +01:00
|
|
|
const Abi abi = targetAbi();
|
|
|
|
|
if (abi.architecture() == Abi::UnknownArchitecture || abi.wordWidth() == 0)
|
2017-07-17 22:35:06 +03:00
|
|
|
return type;
|
2023-01-13 12:38:22 +01:00
|
|
|
return Tr::tr("%1 (%2, %3 %4 at %5)").arg(type,
|
2020-11-10 14:05:58 +01:00
|
|
|
ToolChainManager::displayNameOfLanguageId(language()),
|
|
|
|
|
Abi::toString(abi.architecture()),
|
|
|
|
|
Abi::toString(abi.wordWidth()),
|
2021-04-29 13:16:02 +02:00
|
|
|
compilerCommand().toUserOutput());
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions GccToolChain::defaultLanguageExtensions() const
|
2013-04-28 13:11:48 +04:00
|
|
|
{
|
2018-10-08 09:49:02 +02:00
|
|
|
return LanguageExtension::Gnu;
|
2013-04-28 13:11:48 +04:00
|
|
|
}
|
|
|
|
|
|
2016-03-04 15:33:16 +01:00
|
|
|
QString GccToolChain::originalTargetTriple() const
|
|
|
|
|
{
|
2016-03-31 08:48:59 +02:00
|
|
|
if (m_originalTargetTriple.isEmpty())
|
|
|
|
|
m_originalTargetTriple = detectSupportedAbis().originalTargetTriple;
|
2016-03-04 15:33:16 +01:00
|
|
|
return m_originalTargetTriple;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-06 15:19:05 +00:00
|
|
|
QString GccToolChain::version() const
|
|
|
|
|
{
|
|
|
|
|
if (m_version.isEmpty())
|
|
|
|
|
m_version = detectVersion();
|
|
|
|
|
return m_version;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-10 11:04:01 +02:00
|
|
|
FilePath GccToolChain::installDir() const
|
|
|
|
|
{
|
|
|
|
|
if (m_installDir.isEmpty())
|
|
|
|
|
m_installDir = detectInstallDir();
|
|
|
|
|
return m_installDir;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-27 11:04:18 +02:00
|
|
|
Abis GccToolChain::supportedAbis() const
|
2011-03-10 14:44:49 +01:00
|
|
|
{
|
|
|
|
|
return m_supportedAbis;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-22 13:35:04 +01:00
|
|
|
static bool isNetworkCompiler(const QString &dirPath)
|
|
|
|
|
{
|
|
|
|
|
return dirPath.contains("icecc") || dirPath.contains("distcc");
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
static Utils::FilePath findLocalCompiler(const Utils::FilePath &compilerPath,
|
2017-02-13 10:56:38 +01:00
|
|
|
const Environment &env)
|
|
|
|
|
{
|
2017-09-15 17:33:16 +02:00
|
|
|
// Find the "real" compiler if icecc, distcc or similar are in use. Ignore ccache, since that
|
|
|
|
|
// is local already.
|
|
|
|
|
|
2018-10-22 16:34:31 +02:00
|
|
|
// Get the path to the compiler, ignoring direct calls to icecc and distcc as we cannot
|
2017-09-15 17:33:16 +02:00
|
|
|
// do anything about those.
|
2019-02-22 13:35:04 +01:00
|
|
|
if (!isNetworkCompiler(compilerPath.parentDir().toString()))
|
2017-09-15 17:33:16 +02:00
|
|
|
return compilerPath;
|
|
|
|
|
|
2019-02-22 13:35:04 +01:00
|
|
|
// Filter out network compilers
|
2019-12-17 14:07:53 +01:00
|
|
|
const FilePaths pathComponents = Utils::filtered(env.path(), [] (const FilePath &dirPath) {
|
2019-02-22 13:35:04 +01:00
|
|
|
return !isNetworkCompiler(dirPath.toString());
|
2017-02-13 10:56:38 +01:00
|
|
|
});
|
2017-09-15 17:33:16 +02:00
|
|
|
|
|
|
|
|
// This effectively searches the PATH twice, once via pathComponents and once via PATH itself:
|
|
|
|
|
// searchInPath filters duplicates, so that will not hurt.
|
2019-05-28 13:49:26 +02:00
|
|
|
const Utils::FilePath path = env.searchInPath(compilerPath.fileName(), pathComponents);
|
2017-02-13 10:56:38 +01:00
|
|
|
|
2017-09-15 17:33:16 +02:00
|
|
|
return path.isEmpty() ? compilerPath : path;
|
2017-02-13 10:56:38 +01:00
|
|
|
}
|
|
|
|
|
|
2020-01-17 15:28:49 +01:00
|
|
|
// For querying operations such as -dM
|
|
|
|
|
static QStringList filteredFlags(const QStringList &allFlags, bool considerSysroot)
|
|
|
|
|
{
|
|
|
|
|
QStringList filtered;
|
|
|
|
|
for (int i = 0; i < allFlags.size(); ++i) {
|
|
|
|
|
const QString &a = allFlags.at(i);
|
|
|
|
|
if (a.startsWith("--gcc-toolchain=")) {
|
|
|
|
|
filtered << a;
|
|
|
|
|
} else if (a == "-arch") {
|
|
|
|
|
if (++i < allFlags.length() && !filtered.contains(a))
|
|
|
|
|
filtered << a << allFlags.at(i);
|
2022-06-17 15:40:30 +02:00
|
|
|
} else if (a == "-Xclang") {
|
|
|
|
|
filtered << a;
|
2020-01-17 15:28:49 +01:00
|
|
|
} else if ((considerSysroot && (a == "--sysroot" || a == "-isysroot"))
|
|
|
|
|
|| a == "-D" || a == "-U"
|
|
|
|
|
|| a == "-gcc-toolchain" || a == "-target" || a == "-mllvm" || a == "-isystem") {
|
|
|
|
|
if (++i < allFlags.length())
|
|
|
|
|
filtered << a << allFlags.at(i);
|
2022-07-14 12:06:50 +02:00
|
|
|
} else if (a.startsWith("-m") || a.startsWith("-f") || a.startsWith("-O")
|
|
|
|
|
|| a.startsWith("-std=") || a.startsWith("-stdlib=")
|
2020-01-17 15:28:49 +01:00
|
|
|
|| a.startsWith("-specs=") || a == "-ansi" || a == "-undef"
|
2022-07-14 12:06:50 +02:00
|
|
|
|| a.startsWith("-D") || a.startsWith("-U")
|
|
|
|
|
|| a.startsWith("-stdlib=") || a.startsWith("-B")
|
2020-01-17 15:28:49 +01:00
|
|
|
|| a.startsWith("--target=")
|
|
|
|
|
|| (a.startsWith("-isystem") && a.length() > 8)
|
2022-07-14 12:06:50 +02:00
|
|
|
|| a == "-Wno-deprecated"
|
2020-01-17 15:28:49 +01:00
|
|
|
|| a == "-nostdinc" || a == "-nostdinc++") {
|
|
|
|
|
filtered << a;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return filtered;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-27 10:18:44 +02:00
|
|
|
ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const
|
2017-02-06 16:59:53 +01:00
|
|
|
{
|
|
|
|
|
// Using a clean environment breaks ccache/distcc/etc.
|
2022-10-18 17:00:36 +02:00
|
|
|
Environment env = compilerCommand().deviceEnvironment();
|
2017-02-06 16:59:53 +01:00
|
|
|
addToEnvironment(env);
|
|
|
|
|
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
|
|
|
|
|
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
|
|
|
|
|
QTC_CHECK(reinterpretOptions);
|
2019-05-09 11:24:54 +02:00
|
|
|
MacrosCache macroCache = predefinedMacrosCache();
|
2020-06-26 13:59:38 +02:00
|
|
|
Utils::Id lang = language();
|
2017-02-06 16:59:53 +01:00
|
|
|
|
2020-11-27 11:46:58 +01:00
|
|
|
/*
|
|
|
|
|
* Asks compiler for set of predefined macros
|
|
|
|
|
* flags are the compiler flags collected from project settings
|
|
|
|
|
* returns the list of defines, one per line, e.g. "#define __GXX_WEAK__ 1"
|
|
|
|
|
* Note: changing compiler flags sometimes changes macros set, e.g. -fopenmp
|
|
|
|
|
* adds _OPENMP macro, for full list of macro search by word "when" on this page:
|
|
|
|
|
* http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
|
|
|
|
|
*
|
|
|
|
|
* This runner must be thread-safe!
|
|
|
|
|
*/
|
2020-11-13 09:39:32 +01:00
|
|
|
return [env, compilerCommand = compilerCommand(),
|
|
|
|
|
platformCodeGenFlags, reinterpretOptions, macroCache, lang]
|
2017-10-24 14:36:11 +02:00
|
|
|
(const QStringList &flags) {
|
|
|
|
|
QStringList allFlags = platformCodeGenFlags + flags; // add only cxxflags is empty?
|
2020-01-17 15:28:49 +01:00
|
|
|
QStringList arguments = gccPredefinedMacrosOptions(lang) + filteredFlags(allFlags, true);
|
2017-02-06 16:59:53 +01:00
|
|
|
arguments = reinterpretOptions(arguments);
|
2022-08-26 10:30:00 +02:00
|
|
|
const std::optional<MacroInspectionReport> cachedMacros = macroCache->check(arguments);
|
2017-10-24 14:36:11 +02:00
|
|
|
if (cachedMacros)
|
|
|
|
|
return cachedMacros.value();
|
|
|
|
|
|
2018-09-27 10:18:44 +02:00
|
|
|
const Macros macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
|
|
|
|
|
arguments,
|
2021-05-14 06:13:03 +02:00
|
|
|
env);
|
2017-02-06 16:59:53 +01:00
|
|
|
|
2018-10-09 14:26:47 +02:00
|
|
|
const auto report = MacroInspectionReport{macros, languageVersion(lang, macros)};
|
2018-09-27 10:18:44 +02:00
|
|
|
macroCache->insert(arguments, report);
|
|
|
|
|
|
|
|
|
|
qCDebug(gccLog) << "MacroInspectionReport for code model:";
|
2018-10-08 09:49:02 +02:00
|
|
|
qCDebug(gccLog) << "Language version:" << static_cast<int>(report.languageVersion);
|
2018-10-09 14:26:47 +02:00
|
|
|
for (const Macro &m : macros) {
|
2017-10-27 16:02:06 +02:00
|
|
|
qCDebug(gccLog) << compilerCommand.toUserOutput()
|
|
|
|
|
<< (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
|
|
|
|
|
<< arguments.join(", ") << "]"
|
|
|
|
|
<< QString::fromUtf8(m.toByteArray());
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-27 10:18:44 +02:00
|
|
|
return report;
|
2017-02-06 16:59:53 +01:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-28 13:11:48 +04:00
|
|
|
/**
|
2018-10-08 09:49:02 +02:00
|
|
|
* @brief Parses gcc flags -std=*, -fopenmp, -fms-extensions.
|
2013-04-28 13:11:48 +04:00
|
|
|
* @see http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
|
|
|
|
|
*/
|
2019-01-09 18:31:20 +01:00
|
|
|
Utils::LanguageExtensions GccToolChain::languageExtensions(const QStringList &cxxflags) const
|
2012-02-16 15:09:56 +01:00
|
|
|
{
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions extensions = defaultLanguageExtensions();
|
2013-04-28 13:11:48 +04:00
|
|
|
|
|
|
|
|
const QStringList allCxxflags = m_platformCodeGenFlags + cxxflags; // add only cxxflags is empty?
|
2022-05-03 15:40:40 +02:00
|
|
|
for (const QString &flag : allCxxflags) {
|
2016-11-24 14:57:07 +01:00
|
|
|
if (flag.startsWith("-std=")) {
|
2014-08-28 17:33:47 +02:00
|
|
|
const QByteArray std = flag.mid(5).toLatin1();
|
2018-09-27 10:18:44 +02:00
|
|
|
if (std.startsWith("gnu"))
|
2018-10-08 09:49:02 +02:00
|
|
|
extensions |= LanguageExtension::Gnu;
|
2018-09-27 10:18:44 +02:00
|
|
|
else
|
2018-10-08 09:49:02 +02:00
|
|
|
extensions &= ~LanguageExtensions(LanguageExtension::Gnu);
|
2016-11-24 14:57:07 +01:00
|
|
|
} else if (flag == "-fopenmp") {
|
2018-10-16 09:21:33 +02:00
|
|
|
extensions |= LanguageExtension::OpenMP;
|
2016-11-24 14:57:07 +01:00
|
|
|
} else if (flag == "-fms-extensions") {
|
2018-10-08 09:49:02 +02:00
|
|
|
extensions |= LanguageExtension::Microsoft;
|
2013-04-28 13:11:48 +04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-08 09:49:02 +02:00
|
|
|
return extensions;
|
2012-02-16 15:09:56 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-18 11:56:54 +01:00
|
|
|
WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const
|
2013-03-03 21:53:38 +04:00
|
|
|
{
|
|
|
|
|
// based on 'LC_ALL="en" gcc -Q --help=warnings | grep enabled'
|
2020-01-07 14:57:57 +01:00
|
|
|
WarningFlags flags(WarningFlags::Deprecated | WarningFlags::IgnoredQualifiers
|
2016-01-18 11:56:54 +01:00
|
|
|
| WarningFlags::SignedComparison | WarningFlags::UninitializedVars);
|
|
|
|
|
WarningFlags groupWall(WarningFlags::All | WarningFlags::UnknownPragma | WarningFlags::UnusedFunctions
|
|
|
|
|
| WarningFlags::UnusedLocals | WarningFlags::UnusedResult | WarningFlags::UnusedValue
|
|
|
|
|
| WarningFlags::SignedComparison | WarningFlags::UninitializedVars);
|
2020-01-07 14:57:57 +01:00
|
|
|
WarningFlags groupWextra(WarningFlags::Extra | WarningFlags::IgnoredQualifiers | WarningFlags::UnusedParams);
|
2013-03-03 21:53:38 +04:00
|
|
|
|
2022-05-03 15:40:40 +02:00
|
|
|
for (int end = cflags.size(), i = 0; i != end; ++i) {
|
|
|
|
|
const QString &flag = cflags[i];
|
2016-11-24 14:57:07 +01:00
|
|
|
if (flag == "--all-warnings")
|
2013-03-03 21:53:38 +04:00
|
|
|
flags |= groupWall;
|
2016-11-24 14:57:07 +01:00
|
|
|
else if (flag == "--extra-warnings")
|
2013-03-03 21:53:38 +04:00
|
|
|
flags |= groupWextra;
|
|
|
|
|
|
|
|
|
|
WarningFlagAdder add(flag, flags);
|
|
|
|
|
if (add.triggered())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// supported by clang too
|
2016-01-18 11:56:54 +01:00
|
|
|
add("error", WarningFlags::AsErrors);
|
2013-03-03 21:53:38 +04:00
|
|
|
add("all", groupWall);
|
|
|
|
|
add("extra", groupWextra);
|
2016-01-18 11:56:54 +01:00
|
|
|
add("deprecated", WarningFlags::Deprecated);
|
|
|
|
|
add("effc++", WarningFlags::EffectiveCxx);
|
2020-01-07 14:57:57 +01:00
|
|
|
add("ignored-qualifiers", WarningFlags::IgnoredQualifiers);
|
2016-01-18 11:56:54 +01:00
|
|
|
add("non-virtual-dtor", WarningFlags::NonVirtualDestructor);
|
|
|
|
|
add("overloaded-virtual", WarningFlags::OverloadedVirtual);
|
|
|
|
|
add("shadow", WarningFlags::HiddenLocals);
|
|
|
|
|
add("sign-compare", WarningFlags::SignedComparison);
|
|
|
|
|
add("unknown-pragmas", WarningFlags::UnknownPragma);
|
|
|
|
|
add("unused", WarningFlags::UnusedFunctions | WarningFlags::UnusedLocals | WarningFlags::UnusedParams
|
|
|
|
|
| WarningFlags::UnusedResult | WarningFlags::UnusedValue);
|
|
|
|
|
add("unused-function", WarningFlags::UnusedFunctions);
|
|
|
|
|
add("unused-variable", WarningFlags::UnusedLocals);
|
|
|
|
|
add("unused-parameter", WarningFlags::UnusedParams);
|
|
|
|
|
add("unused-result", WarningFlags::UnusedResult);
|
|
|
|
|
add("unused-value", WarningFlags::UnusedValue);
|
|
|
|
|
add("uninitialized", WarningFlags::UninitializedVars);
|
2013-03-03 21:53:38 +04:00
|
|
|
}
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-25 14:06:47 +01:00
|
|
|
FilePaths GccToolChain::includedFiles(const QStringList &flags, const FilePath &directoryPath) const
|
2018-06-11 12:52:04 +02:00
|
|
|
{
|
2022-10-11 09:24:46 +03:00
|
|
|
return ToolChain::includedFiles("-include", flags, directoryPath, PossiblyConcatenatedFlag::No);
|
2018-06-11 12:52:04 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-06 16:00:25 +01:00
|
|
|
QStringList GccToolChain::gccPrepareArguments(const QStringList &flags,
|
2022-06-30 09:08:47 +02:00
|
|
|
const FilePath &sysRoot,
|
2017-11-06 16:00:25 +01:00
|
|
|
const QStringList &platformCodeGenFlags,
|
2022-06-30 09:08:47 +02:00
|
|
|
Id languageId,
|
2017-11-06 16:00:25 +01:00
|
|
|
OptionsReinterpreter reinterpretOptions)
|
|
|
|
|
{
|
|
|
|
|
QStringList arguments;
|
|
|
|
|
const bool hasKitSysroot = !sysRoot.isEmpty();
|
|
|
|
|
if (hasKitSysroot)
|
2022-06-30 09:08:47 +02:00
|
|
|
arguments.append(QString("--sysroot=%1").arg(sysRoot.nativePath()));
|
2017-11-06 16:00:25 +01:00
|
|
|
|
|
|
|
|
QStringList allFlags;
|
|
|
|
|
allFlags << platformCodeGenFlags << flags;
|
2020-01-17 15:28:49 +01:00
|
|
|
arguments += filteredFlags(allFlags, !hasKitSysroot);
|
2017-11-06 16:00:25 +01:00
|
|
|
arguments << languageOption(languageId) << "-E" << "-v" << "-";
|
|
|
|
|
arguments = reinterpretOptions(arguments);
|
|
|
|
|
|
|
|
|
|
return arguments;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTE: extraHeaderPathsFunction must NOT capture this or it's members!!!
|
|
|
|
|
void GccToolChain::initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extraHeaderPathsFunction) const
|
|
|
|
|
{
|
|
|
|
|
m_extraHeaderPathsFunction = std::move(extraHeaderPathsFunction);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-25 16:06:39 +02:00
|
|
|
HeaderPaths GccToolChain::builtInHeaderPaths(const Utils::Environment &env,
|
2019-05-28 13:49:26 +02:00
|
|
|
const Utils::FilePath &compilerCommand,
|
2019-04-25 16:06:39 +02:00
|
|
|
const QStringList &platformCodeGenFlags,
|
|
|
|
|
OptionsReinterpreter reinterpretOptions,
|
2019-05-09 11:24:54 +02:00
|
|
|
HeaderPathsCache headerCache,
|
2020-06-26 13:59:38 +02:00
|
|
|
Utils::Id languageId,
|
2019-04-25 16:06:39 +02:00
|
|
|
ExtraHeaderPathsFunction extraHeaderPathsFunction,
|
|
|
|
|
const QStringList &flags,
|
2022-06-30 09:08:47 +02:00
|
|
|
const Utils::FilePath &sysRoot,
|
2019-04-25 16:06:39 +02:00
|
|
|
const QString &originalTargetTriple)
|
|
|
|
|
{
|
|
|
|
|
QStringList arguments = gccPrepareArguments(flags,
|
|
|
|
|
sysRoot,
|
|
|
|
|
platformCodeGenFlags,
|
|
|
|
|
languageId,
|
|
|
|
|
reinterpretOptions);
|
|
|
|
|
|
|
|
|
|
// Must be clang case only.
|
|
|
|
|
if (!originalTargetTriple.isEmpty())
|
|
|
|
|
arguments << "-target" << originalTargetTriple;
|
|
|
|
|
|
2022-09-30 15:57:27 +02:00
|
|
|
const std::optional<HeaderPaths> cachedPaths = headerCache->check({env, arguments});
|
2019-04-25 16:06:39 +02:00
|
|
|
if (cachedPaths)
|
|
|
|
|
return cachedPaths.value();
|
|
|
|
|
|
|
|
|
|
HeaderPaths paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env),
|
|
|
|
|
arguments,
|
2021-05-14 06:13:03 +02:00
|
|
|
env);
|
2019-04-25 16:06:39 +02:00
|
|
|
extraHeaderPathsFunction(paths);
|
2022-09-30 15:57:27 +02:00
|
|
|
headerCache->insert({env, arguments}, paths);
|
2019-04-25 16:06:39 +02:00
|
|
|
|
|
|
|
|
qCDebug(gccLog) << "Reporting header paths to code model:";
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const HeaderPath &hp : std::as_const(paths)) {
|
2019-04-25 16:06:39 +02:00
|
|
|
qCDebug(gccLog) << compilerCommand.toUserOutput()
|
|
|
|
|
<< (languageId == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
|
|
|
|
|
<< arguments.join(", ") << "]" << hp.path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return paths;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-05 16:58:07 +02:00
|
|
|
ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner(
|
|
|
|
|
const Environment &env) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2017-02-06 16:59:53 +01:00
|
|
|
// Using a clean environment breaks ccache/distcc/etc.
|
2019-07-05 16:58:07 +02:00
|
|
|
Environment fullEnv = env;
|
|
|
|
|
addToEnvironment(fullEnv);
|
2017-02-06 16:59:53 +01:00
|
|
|
|
|
|
|
|
// This runner must be thread-safe!
|
2020-12-14 10:50:40 +01:00
|
|
|
return [fullEnv,
|
2020-11-13 09:39:32 +01:00
|
|
|
compilerCommand = compilerCommand(),
|
2019-04-25 16:06:39 +02:00
|
|
|
platformCodeGenFlags = m_platformCodeGenFlags,
|
|
|
|
|
reinterpretOptions = m_optionsReinterpreter,
|
2019-05-09 11:24:54 +02:00
|
|
|
headerCache = headerPathsCache(),
|
2019-04-25 16:06:39 +02:00
|
|
|
languageId = language(),
|
|
|
|
|
extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags,
|
2022-06-30 09:08:47 +02:00
|
|
|
const FilePath &sysRoot,
|
2019-04-25 16:06:39 +02:00
|
|
|
const QString &) {
|
2019-07-05 16:58:07 +02:00
|
|
|
return builtInHeaderPaths(fullEnv,
|
2019-04-25 16:06:39 +02:00
|
|
|
compilerCommand,
|
|
|
|
|
platformCodeGenFlags,
|
|
|
|
|
reinterpretOptions,
|
|
|
|
|
headerCache,
|
|
|
|
|
languageId,
|
|
|
|
|
extraHeaderPathsFunction,
|
|
|
|
|
flags,
|
|
|
|
|
sysRoot,
|
2019-10-31 14:31:59 +01:00
|
|
|
/*originalTargetTriple=*/""); // Must be empty for gcc.
|
2017-02-06 16:59:53 +01:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
void GccToolChain::addCommandPathToEnvironment(const FilePath &command, Environment &env)
|
2013-09-02 17:19:57 +02:00
|
|
|
{
|
2021-11-09 18:20:14 +01:00
|
|
|
env.prependOrSetPath(command.parentDir());
|
2013-09-02 17:19:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-08-21 13:29:16 +02:00
|
|
|
void GccToolChain::addToEnvironment(Environment &env) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2017-10-22 11:26:17 +03:00
|
|
|
// On Windows gcc invokes cc1plus which is in libexec directory.
|
|
|
|
|
// cc1plus depends on libwinpthread-1.dll which is in bin, so bin must be in the PATH.
|
2022-02-23 12:33:23 +01:00
|
|
|
if (compilerCommand().osType() == OsTypeWindows)
|
2020-11-13 09:39:32 +01:00
|
|
|
addCommandPathToEnvironment(compilerCommand(), env);
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 14:22:15 +02:00
|
|
|
QStringList GccToolChain::suggestedMkspecList() const
|
2011-04-07 13:12:55 +02:00
|
|
|
{
|
2019-05-27 14:22:15 +02:00
|
|
|
const Abi abi = targetAbi();
|
|
|
|
|
const Abi host = Abi::hostAbi();
|
2012-02-02 11:56:09 +01:00
|
|
|
|
|
|
|
|
// Cross compile: Leave the mkspec alone!
|
|
|
|
|
if (abi.architecture() != host.architecture()
|
|
|
|
|
|| abi.os() != host.os()
|
|
|
|
|
|| abi.osFlavor() != host.osFlavor()) // Note: This can fail:-(
|
2019-05-27 14:22:15 +02:00
|
|
|
return {};
|
2012-02-02 11:56:09 +01:00
|
|
|
|
2016-07-25 18:39:16 -07:00
|
|
|
if (abi.os() == Abi::DarwinOS) {
|
2011-09-06 15:19:05 +00:00
|
|
|
QString v = version();
|
2016-07-25 18:39:16 -07:00
|
|
|
// prefer versioned g++ on macOS. This is required to enable building for older macOS versions
|
2020-11-13 09:39:32 +01:00
|
|
|
if (v.startsWith("4.0") && compilerCommand().endsWith("-4.0"))
|
2019-05-27 14:22:15 +02:00
|
|
|
return {"macx-g++40"};
|
2020-11-13 09:39:32 +01:00
|
|
|
if (v.startsWith("4.2") && compilerCommand().endsWith("-4.2"))
|
2019-05-27 14:22:15 +02:00
|
|
|
return {"macx-g++42"};
|
|
|
|
|
return {"macx-g++"};
|
2011-09-06 15:19:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (abi.os() == Abi::LinuxOS) {
|
2018-06-14 16:13:46 +02:00
|
|
|
if (abi.osFlavor() != Abi::GenericFlavor)
|
2019-05-27 14:22:15 +02:00
|
|
|
return {}; // most likely not a desktop, so leave the mkspec alone.
|
2012-08-08 14:19:29 +02:00
|
|
|
if (abi.wordWidth() == host.wordWidth()) {
|
|
|
|
|
// no need to explicitly set the word width, but provide that mkspec anyway to make sure
|
|
|
|
|
// that the correct compiler is picked if a mkspec with a wordwidth is given.
|
2020-11-10 14:05:58 +01:00
|
|
|
return {"linux-g++", "linux-g++-" + QString::number(targetAbi().wordWidth())};
|
2012-08-08 14:19:29 +02:00
|
|
|
}
|
2020-11-10 14:05:58 +01:00
|
|
|
return {"linux-g++-" + QString::number(targetAbi().wordWidth())};
|
2011-09-06 15:19:05 +00:00
|
|
|
}
|
2012-02-02 11:56:09 +01:00
|
|
|
|
2011-05-31 10:06:32 +00:00
|
|
|
if (abi.os() == Abi::BsdOS && abi.osFlavor() == Abi::FreeBsdFlavor)
|
2019-05-27 14:22:15 +02:00
|
|
|
return {"freebsd-g++"};
|
2012-02-02 11:56:09 +01:00
|
|
|
|
2019-05-27 14:22:15 +02:00
|
|
|
return {};
|
2011-04-07 13:12:55 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
FilePath GccToolChain::makeCommand(const Environment &environment) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2019-05-28 13:49:26 +02:00
|
|
|
const FilePath tmp = environment.searchInPath("make");
|
2021-08-10 16:19:02 +02:00
|
|
|
return tmp.isEmpty() ? "make" : tmp;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2020-04-16 13:53:05 +02:00
|
|
|
QList<OutputLineParser *> GccToolChain::createOutputParsers() const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2020-04-08 17:45:39 +02:00
|
|
|
return GccParser::gccParserSuite();
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
void GccToolChain::resetToolChain(const FilePath &path)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2016-09-12 12:06:50 +02:00
|
|
|
bool resetDisplayName = (displayName() == defaultDisplayName());
|
2011-04-14 14:51:28 +02:00
|
|
|
|
2014-07-21 14:23:09 +02:00
|
|
|
setCompilerCommand(path);
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2020-11-10 14:05:58 +01:00
|
|
|
const Abi currentAbi = targetAbi();
|
2016-03-04 15:33:16 +01:00
|
|
|
const DetectedAbisResult detectedAbis = detectSupportedAbis();
|
|
|
|
|
m_supportedAbis = detectedAbis.supportedAbis;
|
|
|
|
|
m_originalTargetTriple = detectedAbis.originalTargetTriple;
|
2019-10-10 11:04:01 +02:00
|
|
|
m_installDir = installDir();
|
2011-04-14 14:51:28 +02:00
|
|
|
|
2020-11-10 14:05:58 +01:00
|
|
|
if (m_supportedAbis.isEmpty())
|
|
|
|
|
setTargetAbiNoSignal(Abi());
|
|
|
|
|
else if (!m_supportedAbis.contains(currentAbi))
|
|
|
|
|
setTargetAbiNoSignal(m_supportedAbis.at(0));
|
2012-01-30 18:07:24 +01:00
|
|
|
|
|
|
|
|
if (resetDisplayName)
|
|
|
|
|
setDisplayName(defaultDisplayName()); // calls toolChainUpdated()!
|
|
|
|
|
else
|
|
|
|
|
toolChainUpdated();
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-22 23:03:45 +02:00
|
|
|
void GccToolChain::setPlatformCodeGenFlags(const QStringList &flags)
|
|
|
|
|
{
|
|
|
|
|
if (flags != m_platformCodeGenFlags) {
|
|
|
|
|
m_platformCodeGenFlags = flags;
|
|
|
|
|
toolChainUpdated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-15 15:28:13 +01:00
|
|
|
QStringList GccToolChain::extraCodeModelFlags() const
|
|
|
|
|
{
|
|
|
|
|
return platformCodeGenFlags();
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-22 23:03:45 +02:00
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Code gen flags that have to be passed to the compiler.
|
2013-04-22 23:03:45 +02:00
|
|
|
*/
|
|
|
|
|
QStringList GccToolChain::platformCodeGenFlags() const
|
|
|
|
|
{
|
|
|
|
|
return m_platformCodeGenFlags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GccToolChain::setPlatformLinkerFlags(const QStringList &flags)
|
|
|
|
|
{
|
|
|
|
|
if (flags != m_platformLinkerFlags) {
|
|
|
|
|
m_platformLinkerFlags = flags;
|
|
|
|
|
toolChainUpdated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2013-09-10 17:16:10 +02:00
|
|
|
Flags that have to be passed to the linker.
|
2013-04-22 23:03:45 +02:00
|
|
|
|
2013-09-10 17:16:10 +02:00
|
|
|
For example: \c{-arch armv7}
|
2013-04-22 23:03:45 +02:00
|
|
|
*/
|
|
|
|
|
QStringList GccToolChain::platformLinkerFlags() const
|
|
|
|
|
{
|
|
|
|
|
return m_platformLinkerFlags;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-23 16:53:06 +02:00
|
|
|
void GccToolChain::toMap(Store &data) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-07-20 16:41:45 +02:00
|
|
|
ToolChain::toMap(data);
|
2016-11-24 14:57:07 +01:00
|
|
|
data.insert(compilerPlatformCodeGenFlagsKeyC, m_platformCodeGenFlags);
|
|
|
|
|
data.insert(compilerPlatformLinkerFlagsKeyC, m_platformLinkerFlags);
|
|
|
|
|
data.insert(originalTargetTripleKeyC, m_originalTargetTriple);
|
2019-05-27 12:12:16 +02:00
|
|
|
data.insert(supportedAbisKeyC, Utils::transform<QStringList>(m_supportedAbis, &Abi::toString));
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-23 16:53:06 +02:00
|
|
|
void GccToolChain::fromMap(const Store &data)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-07-21 19:15:02 +02:00
|
|
|
ToolChain::fromMap(data);
|
|
|
|
|
if (hasError())
|
|
|
|
|
return;
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2016-11-24 14:57:07 +01:00
|
|
|
m_platformCodeGenFlags = data.value(compilerPlatformCodeGenFlagsKeyC).toStringList();
|
|
|
|
|
m_platformLinkerFlags = data.value(compilerPlatformLinkerFlagsKeyC).toStringList();
|
|
|
|
|
m_originalTargetTriple = data.value(originalTargetTripleKeyC).toString();
|
|
|
|
|
const QStringList abiList = data.value(supportedAbisKeyC).toStringList();
|
2011-06-21 13:26:22 +02:00
|
|
|
m_supportedAbis.clear();
|
2019-08-01 17:04:32 +02:00
|
|
|
for (const QString &a : abiList)
|
|
|
|
|
m_supportedAbis.append(Abi::fromString(a));
|
2016-09-12 12:06:50 +02:00
|
|
|
|
2020-11-10 14:05:58 +01:00
|
|
|
const QString targetAbiString = data.value(targetAbiKeyC).toString();
|
2019-01-16 16:24:02 +01:00
|
|
|
if (targetAbiString.isEmpty())
|
2020-11-13 09:39:32 +01:00
|
|
|
resetToolChain(compilerCommand());
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GccToolChain::operator ==(const ToolChain &other) const
|
|
|
|
|
{
|
|
|
|
|
if (!ToolChain::operator ==(other))
|
|
|
|
|
return false;
|
|
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
auto gccTc = static_cast<const GccToolChain *>(&other);
|
2020-11-13 09:39:32 +01:00
|
|
|
return compilerCommand() == gccTc->compilerCommand() && targetAbi() == gccTc->targetAbi()
|
2013-04-22 23:03:45 +02:00
|
|
|
&& m_platformCodeGenFlags == gccTc->m_platformCodeGenFlags
|
|
|
|
|
&& m_platformLinkerFlags == gccTc->m_platformLinkerFlags;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2018-07-11 08:25:07 +02:00
|
|
|
std::unique_ptr<ToolChainConfigWidget> GccToolChain::createConfigurationWidget()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2018-07-11 08:25:07 +02:00
|
|
|
return std::make_unique<GccToolChainConfigWidget>(this);
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2011-03-10 14:44:49 +01:00
|
|
|
void GccToolChain::updateSupportedAbis() const
|
|
|
|
|
{
|
2016-03-04 15:33:16 +01:00
|
|
|
if (m_supportedAbis.isEmpty()) {
|
|
|
|
|
const DetectedAbisResult detected = detectSupportedAbis();
|
|
|
|
|
m_supportedAbis = detected.supportedAbis;
|
|
|
|
|
m_originalTargetTriple = detected.originalTargetTriple;
|
|
|
|
|
}
|
2011-05-17 16:02:05 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-06 16:59:53 +01:00
|
|
|
void GccToolChain::setOptionsReinterpreter(const OptionsReinterpreter &optionsReinterpreter)
|
|
|
|
|
{
|
|
|
|
|
m_optionsReinterpreter = optionsReinterpreter;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 15:33:16 +01:00
|
|
|
GccToolChain::DetectedAbisResult GccToolChain::detectSupportedAbis() const
|
2011-05-17 16:02:05 +02:00
|
|
|
{
|
2022-10-18 17:00:36 +02:00
|
|
|
Environment env = compilerCommand().deviceEnvironment();
|
2011-05-17 16:02:05 +02:00
|
|
|
addToEnvironment(env);
|
2020-11-27 11:46:58 +01:00
|
|
|
ProjectExplorer::Macros macros = createMacroInspectionRunner()({}).macros;
|
2020-11-13 09:39:32 +01:00
|
|
|
return guessGccAbi(findLocalCompiler(compilerCommand(), env),
|
2021-05-14 06:13:03 +02:00
|
|
|
env,
|
2017-02-13 10:56:38 +01:00
|
|
|
macros,
|
|
|
|
|
platformCodeGenFlags());
|
2011-03-10 14:44:49 +01:00
|
|
|
}
|
|
|
|
|
|
2011-09-06 15:19:05 +00:00
|
|
|
QString GccToolChain::detectVersion() const
|
|
|
|
|
{
|
2022-10-18 17:00:36 +02:00
|
|
|
Environment env = compilerCommand().deviceEnvironment();
|
2011-09-06 15:19:05 +00:00
|
|
|
addToEnvironment(env);
|
2021-05-14 06:13:03 +02:00
|
|
|
return gccVersion(findLocalCompiler(compilerCommand(), env), env,
|
2020-01-20 10:47:55 +01:00
|
|
|
filteredFlags(platformCodeGenFlags(), true));
|
2011-09-06 15:19:05 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-10 11:04:01 +02:00
|
|
|
Utils::FilePath GccToolChain::detectInstallDir() const
|
|
|
|
|
{
|
2022-10-18 17:00:36 +02:00
|
|
|
Environment env = compilerCommand().deviceEnvironment();
|
2019-10-10 11:04:01 +02:00
|
|
|
addToEnvironment(env);
|
2021-05-14 06:13:03 +02:00
|
|
|
return gccInstallDir(findLocalCompiler(compilerCommand(), env), env,
|
2020-01-20 10:47:55 +01:00
|
|
|
filteredFlags(platformCodeGenFlags(), true));
|
2019-10-10 11:04:01 +02:00
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// GccToolChainFactory
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
static Utils::FilePaths gnuSearchPathsFromRegistry()
|
2019-07-09 19:09:45 +03:00
|
|
|
{
|
|
|
|
|
if (!HostOsInfo::isWindowsHost())
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
// Registry token for the "GNU Tools for ARM Embedded Processors".
|
|
|
|
|
static const char kRegistryToken[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \
|
|
|
|
|
"Windows\\CurrentVersion\\Uninstall\\";
|
|
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
Utils::FilePaths searchPaths;
|
2019-07-09 19:09:45 +03:00
|
|
|
|
|
|
|
|
QSettings registry(kRegistryToken, QSettings::NativeFormat);
|
|
|
|
|
const auto productGroups = registry.childGroups();
|
|
|
|
|
for (const QString &productKey : productGroups) {
|
|
|
|
|
if (!productKey.startsWith("GNU Tools for ARM Embedded Processors"))
|
|
|
|
|
continue;
|
|
|
|
|
registry.beginGroup(productKey);
|
|
|
|
|
QString uninstallFilePath = registry.value("UninstallString").toString();
|
|
|
|
|
if (uninstallFilePath.startsWith(QLatin1Char('"')))
|
|
|
|
|
uninstallFilePath.remove(0, 1);
|
|
|
|
|
if (uninstallFilePath.endsWith(QLatin1Char('"')))
|
|
|
|
|
uninstallFilePath.remove(uninstallFilePath.size() - 1, 1);
|
|
|
|
|
registry.endGroup();
|
|
|
|
|
|
|
|
|
|
const QString toolkitRootPath = QFileInfo(uninstallFilePath).path();
|
|
|
|
|
const QString toolchainPath = toolkitRootPath + QLatin1String("/bin");
|
|
|
|
|
searchPaths.push_back(FilePath::fromString(toolchainPath));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return searchPaths;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
static Utils::FilePaths atmelSearchPathsFromRegistry()
|
2019-07-11 16:16:20 +03:00
|
|
|
{
|
|
|
|
|
if (!HostOsInfo::isWindowsHost())
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
// Registry token for the "Atmel" toolchains, e.g. provided by installed
|
|
|
|
|
// "Atmel Studio" IDE.
|
|
|
|
|
static const char kRegistryToken[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Atmel\\";
|
|
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
Utils::FilePaths searchPaths;
|
2019-07-11 16:16:20 +03:00
|
|
|
QSettings registry(kRegistryToken, QSettings::NativeFormat);
|
2019-07-15 17:43:48 +03:00
|
|
|
|
|
|
|
|
// This code enumerate the installed toolchains provided
|
|
|
|
|
// by the Atmel Studio v6.x.
|
2019-07-11 16:16:20 +03:00
|
|
|
const auto toolchainGroups = registry.childGroups();
|
|
|
|
|
for (const QString &toolchainKey : toolchainGroups) {
|
|
|
|
|
if (!toolchainKey.endsWith("GCC"))
|
|
|
|
|
continue;
|
|
|
|
|
registry.beginGroup(toolchainKey);
|
|
|
|
|
const auto entries = registry.childGroups();
|
|
|
|
|
for (const auto &entryKey : entries) {
|
|
|
|
|
registry.beginGroup(entryKey);
|
|
|
|
|
const QString installDir = registry.value("Native/InstallDir").toString();
|
|
|
|
|
const QString version = registry.value("Native/Version").toString();
|
|
|
|
|
registry.endGroup();
|
|
|
|
|
|
|
|
|
|
QString toolchainPath = installDir
|
|
|
|
|
+ QLatin1String("/Atmel Toolchain/")
|
|
|
|
|
+ toolchainKey + QLatin1String("/Native/")
|
|
|
|
|
+ version;
|
|
|
|
|
if (toolchainKey.startsWith("ARM"))
|
|
|
|
|
toolchainPath += QLatin1String("/arm-gnu-toolchain");
|
|
|
|
|
else if (toolchainKey.startsWith("AVR32"))
|
|
|
|
|
toolchainPath += QLatin1String("/avr32-gnu-toolchain");
|
|
|
|
|
else if (toolchainKey.startsWith("AVR8"))
|
|
|
|
|
toolchainPath += QLatin1String("/avr8-gnu-toolchain");
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
toolchainPath += QLatin1String("/bin");
|
|
|
|
|
|
|
|
|
|
const FilePath path = FilePath::fromString(toolchainPath);
|
|
|
|
|
if (path.exists()) {
|
|
|
|
|
searchPaths.push_back(FilePath::fromString(toolchainPath));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
registry.endGroup();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-15 17:43:48 +03:00
|
|
|
// This code enumerate the installed toolchains provided
|
|
|
|
|
// by the Atmel Studio v7.
|
|
|
|
|
registry.beginGroup("AtmelStudio");
|
|
|
|
|
const auto productVersions = registry.childGroups();
|
|
|
|
|
for (const auto &productVersionKey : productVersions) {
|
|
|
|
|
registry.beginGroup(productVersionKey);
|
|
|
|
|
const QString installDir = registry.value("InstallDir").toString();
|
|
|
|
|
registry.endGroup();
|
|
|
|
|
|
|
|
|
|
const QStringList knownToolchainSubdirs = {
|
|
|
|
|
"/toolchain/arm/arm-gnu-toolchain/bin/",
|
|
|
|
|
"/toolchain/avr8/avr8-gnu-toolchain/bin/",
|
|
|
|
|
"/toolchain/avr32/avr32-gnu-toolchain/bin/",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const auto &subdir : knownToolchainSubdirs) {
|
|
|
|
|
const QString toolchainPath = installDir + subdir;
|
|
|
|
|
const FilePath path = FilePath::fromString(toolchainPath);
|
|
|
|
|
if (!path.exists())
|
|
|
|
|
continue;
|
|
|
|
|
searchPaths.push_back(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
registry.endGroup();
|
|
|
|
|
|
2019-07-11 16:16:20 +03:00
|
|
|
return searchPaths;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
static Utils::FilePaths renesasRl78SearchPathsFromRegistry()
|
2019-11-04 23:02:08 +03:00
|
|
|
{
|
|
|
|
|
if (!HostOsInfo::isWindowsHost())
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
// Registry token for the "Renesas RL78" toolchain.
|
|
|
|
|
static const char kRegistryToken[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \
|
|
|
|
|
"Windows\\CurrentVersion\\Uninstall";
|
|
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
Utils::FilePaths searchPaths;
|
2019-11-04 23:02:08 +03:00
|
|
|
|
|
|
|
|
QSettings registry(QLatin1String(kRegistryToken), QSettings::NativeFormat);
|
|
|
|
|
const auto productGroups = registry.childGroups();
|
|
|
|
|
for (const QString &productKey : productGroups) {
|
|
|
|
|
if (!productKey.startsWith("GCC for Renesas RL78"))
|
|
|
|
|
continue;
|
|
|
|
|
registry.beginGroup(productKey);
|
|
|
|
|
const QString installLocation = registry.value("InstallLocation").toString();
|
|
|
|
|
registry.endGroup();
|
|
|
|
|
if (installLocation.isEmpty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const FilePath toolchainPath = FilePath::fromUserInput(installLocation)
|
|
|
|
|
.pathAppended("rl78-elf/rl78-elf/bin");
|
|
|
|
|
if (!toolchainPath.exists())
|
|
|
|
|
continue;
|
|
|
|
|
searchPaths.push_back(toolchainPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return searchPaths;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
GccToolChainFactory::GccToolChainFactory()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("GCC"));
|
2019-05-08 14:56:26 +02:00
|
|
|
setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID);
|
2019-05-08 15:36:57 +02:00
|
|
|
setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID});
|
2019-06-19 17:28:20 +02:00
|
|
|
setToolchainConstructor([] { return new GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID); });
|
2019-05-10 18:22:58 +02:00
|
|
|
setUserCreatable(true);
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2019-08-22 13:04:04 +02:00
|
|
|
// GCC is almost never what you want on macOS, but it is by default found in /usr/bin
|
2023-04-17 10:12:53 +02:00
|
|
|
if (HostOsInfo::isMacHost() && detector.device->type() == Constants::DESKTOP_DEVICE_TYPE)
|
2019-08-22 13:04:04 +02:00
|
|
|
return {};
|
2023-04-17 10:12:53 +02:00
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains tcs;
|
2019-04-05 11:05:06 +02:00
|
|
|
static const auto tcChecker = [](const ToolChain *tc) {
|
|
|
|
|
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor
|
|
|
|
|
&& tc->compilerCommand().fileName() != "c89-gcc"
|
|
|
|
|
&& tc->compilerCommand().fileName() != "c99-gcc";
|
|
|
|
|
};
|
|
|
|
|
tcs.append(autoDetectToolchains("g++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::GCC_TOOLCHAIN_TYPEID, detector, tcChecker));
|
2019-04-05 11:05:06 +02:00
|
|
|
tcs.append(autoDetectToolchains("gcc", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::GCC_TOOLCHAIN_TYPEID, detector, tcChecker));
|
2011-10-31 09:52:18 +00:00
|
|
|
return tcs;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
2017-02-07 14:18:32 +01:00
|
|
|
{
|
2021-06-04 07:59:00 +02:00
|
|
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
2022-05-13 13:17:02 +02:00
|
|
|
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
|
|
|
|
|
|
|
|
|
|
const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
|
|
|
|
|
&& (fileName.startsWith("gcc")
|
|
|
|
|
|| fileName.endsWith("gcc")
|
|
|
|
|
|| (fileName == "cc" && !resolvedSymlinksFileName.contains("clang")));
|
|
|
|
|
|
|
|
|
|
const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
|
|
|
|
|
&& (fileName.startsWith("g++")
|
|
|
|
|
|| fileName.endsWith("g++")
|
|
|
|
|
|| (fileName == "c++" && !resolvedSymlinksFileName.contains("clang")));
|
|
|
|
|
|
|
|
|
|
if (isCCompiler || isCxxCompiler) {
|
2019-07-02 11:31:12 +02:00
|
|
|
return autoDetectToolChain(tcd, [](const ToolChain *tc) {
|
2019-04-05 11:05:06 +02:00
|
|
|
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor;
|
|
|
|
|
});
|
2022-01-18 15:42:02 +01:00
|
|
|
}
|
2022-01-14 17:29:02 +01:00
|
|
|
return {};
|
2017-02-07 14:18:32 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-14 16:37:57 +01:00
|
|
|
static FilePaths findCompilerCandidates(const ToolchainDetector &detector,
|
2021-06-17 16:56:14 +02:00
|
|
|
const QString &compilerName,
|
|
|
|
|
bool detectVariants)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2022-03-14 16:37:57 +01:00
|
|
|
const IDevice::ConstPtr device = detector.device;
|
2021-06-17 16:56:14 +02:00
|
|
|
const QFileInfo fi(compilerName);
|
2023-04-17 10:12:53 +02:00
|
|
|
if (device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE && fi.isAbsolute() && fi.isFile())
|
2021-06-17 16:56:14 +02:00
|
|
|
return {FilePath::fromString(compilerName)};
|
|
|
|
|
|
|
|
|
|
QStringList nameFilters(compilerName);
|
|
|
|
|
if (detectVariants) {
|
|
|
|
|
nameFilters
|
|
|
|
|
<< compilerName + "-[1-9]*" // "clang-8", "gcc-5"
|
|
|
|
|
<< ("*-" + compilerName) // "avr-gcc", "avr32-gcc"
|
|
|
|
|
<< ("*-" + compilerName + "-[1-9]*")// "avr-gcc-4.8.1", "avr32-gcc-4.4.7"
|
|
|
|
|
<< ("*-*-*-" + compilerName) // "arm-none-eabi-gcc"
|
|
|
|
|
<< ("*-*-*-" + compilerName + "-[1-9]*") // "arm-none-eabi-gcc-9.1.0"
|
|
|
|
|
<< ("*-*-*-*-" + compilerName) // "x86_64-pc-linux-gnu-gcc"
|
|
|
|
|
<< ("*-*-*-*-" + compilerName
|
|
|
|
|
+ "-[1-9]*"); // "x86_64-pc-linux-gnu-gcc-7.4.1"
|
|
|
|
|
}
|
2022-02-14 16:41:57 +01:00
|
|
|
nameFilters = transform(nameFilters,
|
|
|
|
|
[os = device ? device->osType() : HostOsInfo::hostOs()](const QString &baseName) {
|
|
|
|
|
return OsSpecificAspects::withExecutableSuffix(os, baseName);
|
|
|
|
|
});
|
2021-04-27 16:06:50 +02:00
|
|
|
|
2019-12-17 14:07:53 +01:00
|
|
|
FilePaths compilerPaths;
|
2021-06-17 16:56:14 +02:00
|
|
|
|
2023-06-22 12:36:29 +02:00
|
|
|
if (device && device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
|
2021-06-17 16:56:14 +02:00
|
|
|
// FIXME: Merge with block below
|
2022-03-14 16:37:57 +01:00
|
|
|
FilePaths searchPaths = detector.searchPaths;
|
|
|
|
|
if (searchPaths.isEmpty())
|
|
|
|
|
searchPaths = device->systemEnvironment().path();
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const FilePath &deviceDir : std::as_const(searchPaths)) {
|
2021-06-17 16:56:14 +02:00
|
|
|
static const QRegularExpression regexp(binaryRegexp);
|
2021-12-14 12:15:40 +01:00
|
|
|
const auto callBack = [&compilerPaths, compilerName](const FilePath &candidate) {
|
|
|
|
|
if (candidate.fileName() == compilerName)
|
|
|
|
|
compilerPaths << candidate;
|
|
|
|
|
else if (regexp.match(candidate.path()).hasMatch())
|
|
|
|
|
compilerPaths << candidate;
|
2023-01-24 11:23:47 +01:00
|
|
|
return IterationPolicy::Continue;
|
2021-12-14 12:15:40 +01:00
|
|
|
};
|
2022-12-14 17:26:30 +01:00
|
|
|
const FilePath globalDir = device->filePath(deviceDir.path());
|
2022-10-10 17:32:56 +02:00
|
|
|
globalDir.iterateDirectory(callBack, {nameFilters, QDir::Files | QDir::Executable});
|
2021-06-17 16:56:14 +02:00
|
|
|
}
|
2019-04-05 11:05:06 +02:00
|
|
|
} else {
|
2021-06-17 16:56:14 +02:00
|
|
|
// The normal, local host case.
|
2022-03-14 16:37:57 +01:00
|
|
|
FilePaths searchPaths = detector.searchPaths;
|
|
|
|
|
if (searchPaths.isEmpty()) {
|
|
|
|
|
searchPaths = Environment::systemEnvironment().path();
|
|
|
|
|
searchPaths << gnuSearchPathsFromRegistry();
|
|
|
|
|
searchPaths << atmelSearchPathsFromRegistry();
|
|
|
|
|
searchPaths << renesasRl78SearchPathsFromRegistry();
|
2022-08-30 15:25:52 +02:00
|
|
|
if (HostOsInfo::isMacHost()) {
|
|
|
|
|
searchPaths << "/opt/homebrew/opt/ccache/libexec" // homebrew arm
|
|
|
|
|
<< "/usr/local/opt/ccache/libexec" // homebrew intel
|
|
|
|
|
<< "/opt/local/libexec/ccache"; // macports, no links are created automatically though
|
|
|
|
|
}
|
2022-03-14 16:37:57 +01:00
|
|
|
if (HostOsInfo::isAnyUnixHost()) {
|
|
|
|
|
FilePath ccachePath = "/usr/lib/ccache/bin";
|
|
|
|
|
if (!ccachePath.exists())
|
|
|
|
|
ccachePath = "/usr/lib/ccache";
|
|
|
|
|
if (ccachePath.exists() && !searchPaths.contains(ccachePath))
|
|
|
|
|
searchPaths << ccachePath;
|
|
|
|
|
}
|
2020-01-29 13:33:28 +01:00
|
|
|
}
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const FilePath &dir : std::as_const(searchPaths)) {
|
2019-04-05 11:05:06 +02:00
|
|
|
static const QRegularExpression regexp(binaryRegexp);
|
|
|
|
|
QDir binDir(dir.toString());
|
|
|
|
|
const QStringList fileNames = binDir.entryList(nameFilters,
|
|
|
|
|
QDir::Files | QDir::Executable);
|
|
|
|
|
for (const QString &fileName : fileNames) {
|
|
|
|
|
if (fileName != compilerName &&
|
|
|
|
|
!regexp.match(QFileInfo(fileName).completeBaseName()).hasMatch()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-05-28 13:49:26 +02:00
|
|
|
compilerPaths << FilePath::fromString(binDir.filePath(fileName));
|
2019-04-05 11:05:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-03-10 14:44:49 +01:00
|
|
|
|
2021-06-17 16:56:14 +02:00
|
|
|
return compilerPaths;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains GccToolChainFactory::autoDetectToolchains(
|
2021-06-17 16:56:14 +02:00
|
|
|
const QString &compilerName,
|
|
|
|
|
DetectVariants detectVariants,
|
|
|
|
|
const Id language,
|
|
|
|
|
const Id requiredTypeId,
|
2022-01-14 17:29:02 +01:00
|
|
|
const ToolchainDetector &detector,
|
|
|
|
|
const ToolchainChecker &checker) const
|
2021-06-17 16:56:14 +02:00
|
|
|
{
|
|
|
|
|
const FilePaths compilerPaths =
|
2022-03-14 16:37:57 +01:00
|
|
|
findCompilerCandidates(detector, compilerName, detectVariants == DetectVariants::Yes);
|
2022-01-18 13:48:08 +01:00
|
|
|
Toolchains existingCandidates = filtered(detector.alreadyKnown,
|
|
|
|
|
[language](const ToolChain *tc) { return tc->language() == language; });
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains result;
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const FilePath &compilerPath : std::as_const(compilerPaths)) {
|
2019-04-05 11:05:06 +02:00
|
|
|
bool alreadyExists = false;
|
|
|
|
|
for (ToolChain * const existingTc : existingCandidates) {
|
|
|
|
|
// We have a match if the existing toolchain ultimately refers to the same file
|
|
|
|
|
// as the candidate path, either directly or via a hard or soft link.
|
|
|
|
|
// Exceptions:
|
|
|
|
|
// - clang++ is often a soft link to clang, but behaves differently.
|
|
|
|
|
// - ccache and icecc also create soft links that must not be followed here.
|
|
|
|
|
bool existingTcMatches = false;
|
2019-05-28 13:49:26 +02:00
|
|
|
const FilePath existingCommand = existingTc->compilerCommand();
|
2019-04-05 11:05:06 +02:00
|
|
|
if ((requiredTypeId == Constants::CLANG_TOOLCHAIN_TYPEID
|
2022-01-24 10:23:20 +01:00
|
|
|
&& ((language == Constants::CXX_LANGUAGE_ID && !existingCommand.fileName().contains("clang++"))
|
|
|
|
|
|| (language == Constants::C_LANGUAGE_ID && !existingCommand.baseName().endsWith("clang"))))
|
2019-04-05 11:05:06 +02:00
|
|
|
|| compilerPath.toString().contains("icecc")
|
|
|
|
|
|| compilerPath.toString().contains("ccache")) {
|
|
|
|
|
existingTcMatches = existingCommand == compilerPath;
|
|
|
|
|
} else {
|
2022-11-21 12:29:17 +01:00
|
|
|
existingTcMatches = existingCommand.isSameExecutable(compilerPath);
|
2022-02-23 08:43:58 +01:00
|
|
|
if (!existingTcMatches
|
|
|
|
|
&& HostOsInfo::isWindowsHost()
|
|
|
|
|
&& !existingCommand.needsDevice()
|
|
|
|
|
&& !compilerPath.needsDevice()) {
|
2022-10-14 09:54:39 +02:00
|
|
|
existingTcMatches = existingCommand.fileSize()
|
|
|
|
|
== compilerPath.fileSize();
|
2022-02-23 08:43:58 +01:00
|
|
|
}
|
2019-04-05 11:05:06 +02:00
|
|
|
}
|
|
|
|
|
if (existingTcMatches) {
|
2022-01-18 13:48:08 +01:00
|
|
|
if (existingTc->typeId() == requiredTypeId && (!checker || checker(existingTc))
|
|
|
|
|
&& !result.contains(existingTc)) {
|
2019-04-05 11:05:06 +02:00
|
|
|
result << existingTc;
|
2022-01-18 13:48:08 +01:00
|
|
|
}
|
2019-04-05 11:05:06 +02:00
|
|
|
alreadyExists = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!alreadyExists) {
|
2021-04-27 16:06:50 +02:00
|
|
|
const QList<ToolChain *> newToolchains
|
|
|
|
|
= autoDetectToolChain({compilerPath, language}, checker);
|
2019-04-05 11:05:06 +02:00
|
|
|
result << newToolchains;
|
|
|
|
|
existingCandidates << newToolchains;
|
2017-05-26 16:53:09 +03:00
|
|
|
}
|
|
|
|
|
}
|
2015-07-19 10:59:06 +03:00
|
|
|
|
2017-02-07 13:05:12 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains GccToolChainFactory::autoDetectToolChain(const ToolChainDescription &tcd,
|
|
|
|
|
const ToolchainChecker &checker) const
|
2017-02-07 13:05:12 +01:00
|
|
|
{
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains result;
|
2017-02-07 13:05:12 +01:00
|
|
|
|
2022-02-23 12:33:23 +01:00
|
|
|
Environment systemEnvironment = tcd.compilerPath.deviceEnvironment();
|
2019-07-02 11:31:12 +02:00
|
|
|
GccToolChain::addCommandPathToEnvironment(tcd.compilerPath, systemEnvironment);
|
|
|
|
|
const FilePath localCompilerPath = findLocalCompiler(tcd.compilerPath, systemEnvironment);
|
2022-01-18 15:42:02 +01:00
|
|
|
if (ToolChainManager::isBadToolchain(localCompilerPath))
|
|
|
|
|
return result;
|
2017-02-07 15:00:38 +01:00
|
|
|
Macros macros
|
2019-07-02 11:31:12 +02:00
|
|
|
= gccPredefinedMacros(localCompilerPath, gccPredefinedMacrosOptions(tcd.language),
|
2021-05-14 06:13:03 +02:00
|
|
|
systemEnvironment);
|
2022-01-18 15:42:02 +01:00
|
|
|
if (macros.isEmpty()) {
|
|
|
|
|
ToolChainManager::addBadToolchain(localCompilerPath);
|
2019-12-17 17:12:57 +01:00
|
|
|
return result;
|
2022-01-18 15:42:02 +01:00
|
|
|
}
|
2017-02-13 10:56:38 +01:00
|
|
|
const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath,
|
2021-05-14 06:13:03 +02:00
|
|
|
systemEnvironment,
|
2016-03-04 15:33:16 +01:00
|
|
|
macros);
|
2019-04-05 11:05:06 +02:00
|
|
|
for (const Abi &abi : detectedAbis.supportedAbis) {
|
2019-05-10 17:35:04 +02:00
|
|
|
std::unique_ptr<GccToolChain> tc(dynamic_cast<GccToolChain *>(create()));
|
2017-02-07 13:05:12 +01:00
|
|
|
if (!tc)
|
2011-03-10 14:44:49 +01:00
|
|
|
return result;
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2019-07-02 11:31:12 +02:00
|
|
|
tc->setLanguage(tcd.language);
|
2019-05-08 19:03:15 +02:00
|
|
|
tc->setDetection(ToolChain::AutoDetection);
|
2019-05-09 11:24:54 +02:00
|
|
|
tc->predefinedMacrosCache()
|
2018-09-27 10:18:44 +02:00
|
|
|
->insert(QStringList(),
|
|
|
|
|
ToolChain::MacroInspectionReport{macros,
|
2019-07-02 11:31:12 +02:00
|
|
|
ToolChain::languageVersion(tcd.language, macros)});
|
|
|
|
|
tc->setCompilerCommand(tcd.compilerPath);
|
2017-02-07 13:05:12 +01:00
|
|
|
tc->setSupportedAbis(detectedAbis.supportedAbis);
|
2011-03-10 14:44:49 +01:00
|
|
|
tc->setTargetAbi(abi);
|
2016-03-04 15:33:16 +01:00
|
|
|
tc->setOriginalTargetTriple(detectedAbis.originalTargetTriple);
|
2011-03-14 11:00:38 +01:00
|
|
|
tc->setDisplayName(tc->defaultDisplayName()); // reset displayname
|
2019-04-05 11:05:06 +02:00
|
|
|
if (!checker || checker(tc.get()))
|
|
|
|
|
result.append(tc.release());
|
2011-03-10 14:44:49 +01:00
|
|
|
}
|
2011-02-01 18:36:00 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// GccToolChainConfigWidget
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2022-01-20 16:53:55 +01:00
|
|
|
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);
|
2023-01-13 12:38:22 +01:00
|
|
|
m_overrideCheckBox.setText(Tr::tr("Override for code model"));
|
|
|
|
|
m_overrideCheckBox.setToolTip(Tr::tr("Enable in the rare case that the code model\n"
|
2022-06-28 15:22:38 +02:00
|
|
|
"fails because Clang does not understand the target architecture."));
|
2022-02-01 19:42:24 +01:00
|
|
|
layout->addWidget(&m_tripleLineEdit, 1);
|
2022-01-20 16:53:55 +01:00
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
|
2011-02-22 12:25:19 +01:00
|
|
|
ToolChainConfigWidget(tc),
|
2019-01-07 12:15:40 +01:00
|
|
|
m_abiWidget(new AbiWidget),
|
2022-01-20 16:53:55 +01:00
|
|
|
m_compilerCommand(new PathChooser),
|
|
|
|
|
m_targetTripleWidget(new TargetTripleWidget(tc))
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
|
|
|
|
Q_ASSERT(tc);
|
|
|
|
|
|
2016-11-24 14:57:07 +01:00
|
|
|
const QStringList gnuVersionArgs = QStringList("--version");
|
2012-08-21 13:29:16 +02:00
|
|
|
m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand);
|
2012-02-01 14:39:11 +01:00
|
|
|
m_compilerCommand->setCommandVersionArguments(gnuVersionArgs);
|
2016-11-24 14:57:07 +01:00
|
|
|
m_compilerCommand->setHistoryCompleter("PE.Gcc.Command.History");
|
2022-05-31 11:16:44 +02:00
|
|
|
m_compilerCommand->setAllowPathFromDevice(true);
|
2023-01-13 12:38:22 +01:00
|
|
|
m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand);
|
2013-04-22 23:03:45 +02:00
|
|
|
m_platformCodeGenFlagsLineEdit = new QLineEdit(this);
|
2021-05-06 13:07:36 +02:00
|
|
|
m_platformCodeGenFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->platformCodeGenFlags()));
|
2023-01-13 12:38:22 +01:00
|
|
|
m_mainLayout->addRow(Tr::tr("Platform codegen flags:"), m_platformCodeGenFlagsLineEdit);
|
2013-04-22 23:03:45 +02:00
|
|
|
m_platformLinkerFlagsLineEdit = new QLineEdit(this);
|
2021-05-06 13:07:36 +02:00
|
|
|
m_platformLinkerFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->platformLinkerFlags()));
|
2023-01-13 12:38:22 +01:00
|
|
|
m_mainLayout->addRow(Tr::tr("Platform linker flags:"), m_platformLinkerFlagsLineEdit);
|
|
|
|
|
m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget);
|
|
|
|
|
m_mainLayout->addRow(Tr::tr("Target triple:"), m_targetTripleWidget);
|
2013-04-22 23:03:45 +02:00
|
|
|
|
2011-06-08 15:39:14 +00:00
|
|
|
m_abiWidget->setEnabled(false);
|
2012-08-16 15:59:10 +02:00
|
|
|
addErrorLabel();
|
2011-04-13 15:50:14 +02:00
|
|
|
|
2011-02-23 11:36:59 +01:00
|
|
|
setFromToolchain();
|
2011-06-21 13:26:22 +02:00
|
|
|
|
2016-01-29 16:38:37 +02:00
|
|
|
connect(m_compilerCommand, &PathChooser::rawPathChanged,
|
|
|
|
|
this, &GccToolChainConfigWidget::handleCompilerCommandChange);
|
|
|
|
|
connect(m_platformCodeGenFlagsLineEdit, &QLineEdit::editingFinished,
|
|
|
|
|
this, &GccToolChainConfigWidget::handlePlatformCodeGenFlagsChange);
|
|
|
|
|
connect(m_platformLinkerFlagsLineEdit, &QLineEdit::editingFinished,
|
|
|
|
|
this, &GccToolChainConfigWidget::handlePlatformLinkerFlagsChange);
|
|
|
|
|
connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty);
|
2022-01-20 16:53:55 +01:00
|
|
|
connect(m_targetTripleWidget, &TargetTripleWidget::valueChanged,
|
|
|
|
|
this, &ToolChainConfigWidget::dirty);
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
void GccToolChainConfigWidget::applyImpl()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
|
|
|
|
if (toolChain()->isAutoDetected())
|
|
|
|
|
return;
|
|
|
|
|
|
2016-04-13 15:52:14 +02:00
|
|
|
auto tc = static_cast<GccToolChain *>(toolChain());
|
2011-02-01 18:36:00 +01:00
|
|
|
Q_ASSERT(tc);
|
|
|
|
|
QString displayName = tc->displayName();
|
2020-04-09 11:05:50 +02:00
|
|
|
tc->setCompilerCommand(m_compilerCommand->filePath());
|
2019-01-07 12:15:40 +01:00
|
|
|
if (m_abiWidget) {
|
|
|
|
|
tc->setSupportedAbis(m_abiWidget->supportedAbis());
|
|
|
|
|
tc->setTargetAbi(m_abiWidget->currentAbi());
|
|
|
|
|
}
|
2019-10-10 11:04:01 +02:00
|
|
|
tc->setInstallDir(tc->detectInstallDir());
|
2016-03-04 15:33:16 +01:00
|
|
|
tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple);
|
2022-01-20 16:53:55 +01:00
|
|
|
tc->setExplicitCodeModelTargetTriple(m_targetTripleWidget->explicitCodeModelTargetTriple());
|
2011-02-01 18:36:00 +01:00
|
|
|
tc->setDisplayName(displayName); // reset display name
|
2013-04-22 23:03:45 +02:00
|
|
|
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
|
|
|
|
|
tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->text()));
|
2018-12-04 10:46:42 +01:00
|
|
|
|
|
|
|
|
if (m_macros.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
2019-05-09 11:24:54 +02:00
|
|
|
tc->predefinedMacrosCache()
|
2018-09-27 10:18:44 +02:00
|
|
|
->insert(tc->platformCodeGenFlags(),
|
|
|
|
|
ToolChain::MacroInspectionReport{m_macros,
|
|
|
|
|
ToolChain::languageVersion(tc->language(),
|
|
|
|
|
m_macros)});
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
void GccToolChainConfigWidget::setFromToolchain()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2011-06-21 13:26:22 +02:00
|
|
|
// subwidgets are not yet connected!
|
2017-09-30 07:12:57 +02:00
|
|
|
QSignalBlocker blocker(this);
|
2016-04-13 15:52:14 +02:00
|
|
|
auto tc = static_cast<GccToolChain *>(toolChain());
|
2020-04-09 11:05:50 +02:00
|
|
|
m_compilerCommand->setFilePath(tc->compilerCommand());
|
2023-02-07 16:46:47 +01:00
|
|
|
m_platformCodeGenFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->platformCodeGenFlags(),
|
|
|
|
|
HostOsInfo::hostOs()));
|
|
|
|
|
m_platformLinkerFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->platformLinkerFlags(),
|
|
|
|
|
HostOsInfo::hostOs()));
|
2019-01-07 12:15:40 +01:00
|
|
|
if (m_abiWidget) {
|
|
|
|
|
m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
|
2020-04-09 11:35:12 +02:00
|
|
|
if (!m_isReadOnly && !m_compilerCommand->filePath().toString().isEmpty())
|
2019-01-07 12:15:40 +01:00
|
|
|
m_abiWidget->setEnabled(true);
|
|
|
|
|
}
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
bool GccToolChainConfigWidget::isDirtyImpl() const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2016-04-13 15:52:14 +02:00
|
|
|
auto tc = static_cast<GccToolChain *>(toolChain());
|
2011-02-01 18:36:00 +01:00
|
|
|
Q_ASSERT(tc);
|
2020-04-09 11:05:50 +02:00
|
|
|
return m_compilerCommand->filePath() != tc->compilerCommand()
|
2019-01-07 12:15:40 +01:00
|
|
|
|| m_platformCodeGenFlagsLineEdit->text()
|
2021-05-06 13:07:36 +02:00
|
|
|
!= ProcessArgs::joinArgs(tc->platformCodeGenFlags())
|
2019-01-07 12:15:40 +01:00
|
|
|
|| m_platformLinkerFlagsLineEdit->text()
|
2021-05-06 13:07:36 +02:00
|
|
|
!= ProcessArgs::joinArgs(tc->platformLinkerFlags())
|
2022-01-20 16:53:55 +01:00
|
|
|
|| m_targetTripleWidget->explicitCodeModelTargetTriple()
|
|
|
|
|
!= tc->explicitCodeModelTargetTriple()
|
2019-01-07 12:15:40 +01:00
|
|
|
|| (m_abiWidget && m_abiWidget->currentAbi() != tc->targetAbi());
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
void GccToolChainConfigWidget::makeReadOnlyImpl()
|
2011-03-29 17:51:40 +02:00
|
|
|
{
|
2014-07-03 08:39:01 +03:00
|
|
|
m_compilerCommand->setReadOnly(true);
|
2019-01-07 12:15:40 +01:00
|
|
|
if (m_abiWidget)
|
|
|
|
|
m_abiWidget->setEnabled(false);
|
2013-07-15 16:31:27 +02:00
|
|
|
m_platformCodeGenFlagsLineEdit->setEnabled(false);
|
|
|
|
|
m_platformLinkerFlagsLineEdit->setEnabled(false);
|
2022-01-20 16:53:55 +01:00
|
|
|
m_targetTripleWidget->setEnabled(false);
|
2011-06-27 17:24:54 +02:00
|
|
|
m_isReadOnly = true;
|
2011-03-29 17:51:40 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
void GccToolChainConfigWidget::handleCompilerCommandChange()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2019-01-07 12:15:40 +01:00
|
|
|
if (!m_abiWidget)
|
|
|
|
|
return;
|
|
|
|
|
|
2013-11-04 14:46:45 +01:00
|
|
|
bool haveCompiler = false;
|
|
|
|
|
Abi currentAbi = m_abiWidget->currentAbi();
|
2018-03-08 10:10:36 +01:00
|
|
|
bool customAbi = m_abiWidget->isCustomAbi() && m_abiWidget->isEnabled();
|
2020-04-09 11:05:50 +02:00
|
|
|
FilePath path = m_compilerCommand->filePath();
|
2019-05-27 11:04:18 +02:00
|
|
|
Abis abiList;
|
2013-11-04 14:46:45 +01:00
|
|
|
|
2011-06-08 15:39:14 +00:00
|
|
|
if (!path.isEmpty()) {
|
2022-06-30 11:03:34 +02:00
|
|
|
haveCompiler = path.isExecutableFile();
|
2011-06-08 15:39:14 +00:00
|
|
|
}
|
2013-09-02 17:19:57 +02:00
|
|
|
if (haveCompiler) {
|
2022-02-23 12:33:23 +01:00
|
|
|
Environment env = path.deviceEnvironment();
|
2013-09-02 17:19:57 +02:00
|
|
|
GccToolChain::addCommandPathToEnvironment(path, env);
|
2017-07-14 15:46:09 +03:00
|
|
|
QStringList args = gccPredefinedMacrosOptions(Constants::CXX_LANGUAGE_ID)
|
|
|
|
|
+ splitString(m_platformCodeGenFlagsLineEdit->text());
|
2019-05-28 13:49:26 +02:00
|
|
|
const FilePath localCompilerPath = findLocalCompiler(path, env);
|
2021-05-14 06:13:03 +02:00
|
|
|
m_macros = gccPredefinedMacros(localCompilerPath, args, env);
|
|
|
|
|
abiList = guessGccAbi(localCompilerPath, env, m_macros,
|
2016-03-04 15:33:16 +01:00
|
|
|
splitString(m_platformCodeGenFlagsLineEdit->text())).supportedAbis;
|
2013-09-02 17:19:57 +02:00
|
|
|
}
|
2011-06-08 15:39:14 +00:00
|
|
|
m_abiWidget->setEnabled(haveCompiler);
|
2013-11-04 14:46:45 +01:00
|
|
|
|
|
|
|
|
// Find a good ABI for the new compiler:
|
|
|
|
|
Abi newAbi;
|
2019-10-31 16:29:42 +01:00
|
|
|
if (customAbi || abiList.contains(currentAbi))
|
2013-11-04 14:46:45 +01:00
|
|
|
newAbi = currentAbi;
|
|
|
|
|
|
|
|
|
|
m_abiWidget->setAbis(abiList, newAbi);
|
2012-02-21 12:00:45 +01:00
|
|
|
emit dirty();
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
void GccToolChainConfigWidget::handlePlatformCodeGenFlagsChange()
|
2013-04-22 23:03:45 +02:00
|
|
|
{
|
|
|
|
|
QString str1 = m_platformCodeGenFlagsLineEdit->text();
|
2021-05-06 13:07:36 +02:00
|
|
|
QString str2 = ProcessArgs::joinArgs(splitString(str1));
|
2013-04-22 23:03:45 +02:00
|
|
|
if (str1 != str2)
|
|
|
|
|
m_platformCodeGenFlagsLineEdit->setText(str2);
|
|
|
|
|
else
|
|
|
|
|
handleCompilerCommandChange();
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
void GccToolChainConfigWidget::handlePlatformLinkerFlagsChange()
|
2013-04-22 23:03:45 +02:00
|
|
|
{
|
|
|
|
|
QString str1 = m_platformLinkerFlagsLineEdit->text();
|
2021-05-06 13:07:36 +02:00
|
|
|
QString str2 = ProcessArgs::joinArgs(splitString(str1));
|
2013-04-22 23:03:45 +02:00
|
|
|
if (str1 != str2)
|
|
|
|
|
m_platformLinkerFlagsLineEdit->setText(str2);
|
|
|
|
|
else
|
|
|
|
|
emit dirty();
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-13 11:48:34 +02:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// ClangToolChain
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2022-01-18 18:40:41 +01:00
|
|
|
static const Toolchains mingwToolChains()
|
2019-01-07 12:15:40 +01:00
|
|
|
{
|
2022-01-18 18:40:41 +01:00
|
|
|
return ToolChainManager::toolchains([](const ToolChain *tc) -> bool {
|
2019-01-07 12:15:40 +01:00
|
|
|
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<const MingwToolChain *>(tc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClangToolChain::syncAutodetectedWithParentToolchains()
|
|
|
|
|
{
|
2019-01-21 15:07:04 +01:00
|
|
|
if (!HostOsInfo::isWindowsHost() || typeId() != Constants::CLANG_TOOLCHAIN_TYPEID
|
|
|
|
|
|| !isAutoDetected()) {
|
2019-01-07 12:15:40 +01:00
|
|
|
return;
|
2019-01-21 15:07:04 +01:00
|
|
|
}
|
2019-01-07 12:15:40 +01:00
|
|
|
|
|
|
|
|
QObject::disconnect(m_thisToolchainRemovedConnection);
|
|
|
|
|
QObject::disconnect(m_mingwToolchainAddedConnection);
|
|
|
|
|
|
2020-09-08 16:50:50 +02:00
|
|
|
if (!ToolChainManager::isLoaded()) {
|
2023-08-01 20:31:02 +02:00
|
|
|
connect(ToolChainManager::instance(), &ToolChainManager::toolChainsLoaded, this,
|
|
|
|
|
[id = id()] {
|
2020-09-08 16:50:50 +02:00
|
|
|
if (ToolChain * const tc = ToolChainManager::findToolChain(id)) {
|
|
|
|
|
if (tc->typeId() == Constants::CLANG_TOOLCHAIN_TYPEID)
|
|
|
|
|
static_cast<ClangToolChain *>(tc)->syncAutodetectedWithParentToolchains();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 12:15:40 +01:00
|
|
|
if (!mingwToolChainFromId(m_parentToolChainId)) {
|
|
|
|
|
const QList<ToolChain *> mingwTCs = mingwToolChains();
|
2020-06-30 15:11:15 +02:00
|
|
|
m_parentToolChainId = mingwTCs.isEmpty() ? QByteArray() : mingwTCs.front()->id();
|
2019-01-07 12:15:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Subscribe only autodetected toolchains.
|
|
|
|
|
ToolChainManager *tcManager = ToolChainManager::instance();
|
|
|
|
|
m_mingwToolchainAddedConnection
|
2023-08-01 20:31:02 +02:00
|
|
|
= connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](ToolChain *tc) {
|
2019-01-07 12:15:40 +01:00
|
|
|
if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID
|
|
|
|
|
&& !mingwToolChainFromId(m_parentToolChainId)) {
|
|
|
|
|
m_parentToolChainId = tc->id();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
m_thisToolchainRemovedConnection
|
2023-08-01 20:31:02 +02:00
|
|
|
= connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](ToolChain *tc) {
|
2019-01-07 12:15:40 +01:00
|
|
|
if (tc == this) {
|
|
|
|
|
QObject::disconnect(m_thisToolchainRemovedConnection);
|
|
|
|
|
QObject::disconnect(m_mingwToolchainAddedConnection);
|
|
|
|
|
} else if (m_parentToolChainId == tc->id()) {
|
|
|
|
|
const QList<ToolChain *> mingwTCs = mingwToolChains();
|
2020-06-30 15:11:15 +02:00
|
|
|
m_parentToolChainId = mingwTCs.isEmpty() ? QByteArray() : mingwTCs.front()->id();
|
2019-01-07 12:15:40 +01:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-08 19:03:15 +02:00
|
|
|
ClangToolChain::ClangToolChain() :
|
2019-06-19 17:28:20 +02:00
|
|
|
ClangToolChain(Constants::CLANG_TOOLCHAIN_TYPEID)
|
2019-01-07 12:15:40 +01:00
|
|
|
{
|
|
|
|
|
}
|
2011-05-13 11:48:34 +02:00
|
|
|
|
2020-06-26 13:59:38 +02:00
|
|
|
ClangToolChain::ClangToolChain(Utils::Id typeId) :
|
2019-05-08 19:03:15 +02:00
|
|
|
GccToolChain(typeId)
|
2019-01-07 12:15:40 +01:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setTypeDisplayName(Tr::tr("Clang"));
|
2019-01-07 12:15:40 +01:00
|
|
|
syncAutodetectedWithParentToolchains();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-06 13:42:22 +02:00
|
|
|
ClangToolChain::~ClangToolChain()
|
|
|
|
|
{
|
|
|
|
|
QObject::disconnect(m_thisToolchainRemovedConnection);
|
|
|
|
|
QObject::disconnect(m_mingwToolchainAddedConnection);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 12:29:17 +01:00
|
|
|
bool ClangToolChain::matchesCompilerCommand(const FilePath &command) const
|
2022-06-08 16:00:13 +02:00
|
|
|
{
|
|
|
|
|
if (!m_resolvedCompilerCommand) {
|
|
|
|
|
m_resolvedCompilerCommand = FilePath();
|
|
|
|
|
if (HostOsInfo::isMacHost()
|
|
|
|
|
&& compilerCommand().parentDir() == FilePath::fromString("/usr/bin")) {
|
2023-05-03 16:00:22 +02:00
|
|
|
Process xcrun;
|
2022-11-23 18:38:23 +01:00
|
|
|
xcrun.setCommand({"/usr/bin/xcrun", {"-f", compilerCommand().fileName()}});
|
|
|
|
|
xcrun.runBlocking();
|
|
|
|
|
const FilePath output = FilePath::fromString(xcrun.cleanedStdOut().trimmed());
|
2022-06-08 16:00:13 +02:00
|
|
|
if (output.isExecutableFile() && output != compilerCommand())
|
|
|
|
|
m_resolvedCompilerCommand = output;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!m_resolvedCompilerCommand->isEmpty()
|
2022-11-21 12:29:17 +01:00
|
|
|
&& m_resolvedCompilerCommand->isSameExecutable(command))
|
2022-06-08 16:00:13 +02:00
|
|
|
return true;
|
2022-11-21 12:29:17 +01:00
|
|
|
return GccToolChain::matchesCompilerCommand(command);
|
2022-06-08 16:00:13 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-05 03:16:11 +01:00
|
|
|
static FilePath mingwAwareMakeCommand(const Environment &environment)
|
2011-05-13 11:48:34 +02:00
|
|
|
{
|
2016-11-24 14:57:07 +01:00
|
|
|
const QStringList makes
|
2017-02-22 15:09:35 +01:00
|
|
|
= HostOsInfo::isWindowsHost() ? QStringList({"mingw32-make.exe", "make.exe"}) : QStringList({"make"});
|
2012-09-11 15:59:17 +02:00
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
FilePath tmp;
|
2016-11-24 14:57:07 +01:00
|
|
|
for (const QString &make : makes) {
|
2012-09-11 15:59:17 +02:00
|
|
|
tmp = environment.searchInPath(make);
|
|
|
|
|
if (!tmp.isEmpty())
|
2019-05-15 10:45:36 +02:00
|
|
|
return tmp;
|
2012-09-11 15:59:17 +02:00
|
|
|
}
|
2019-05-28 13:49:26 +02:00
|
|
|
return FilePath::fromString(makes.first());
|
2011-05-13 11:48:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-05 03:16:11 +01:00
|
|
|
FilePath ClangToolChain::makeCommand(const Environment &environment) const
|
|
|
|
|
{
|
|
|
|
|
return mingwAwareMakeCommand(environment);
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-28 13:11:48 +04:00
|
|
|
/**
|
2018-10-08 09:49:02 +02:00
|
|
|
* @brief Similar to \a GccToolchain::languageExtensions, but recognizes
|
2013-04-28 13:11:48 +04:00
|
|
|
* "-fborland-extensions".
|
|
|
|
|
*/
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions ClangToolChain::languageExtensions(const QStringList &cxxflags) const
|
2013-04-28 13:11:48 +04:00
|
|
|
{
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions extensions = GccToolChain::languageExtensions(cxxflags);
|
2016-11-24 14:57:07 +01:00
|
|
|
if (cxxflags.contains("-fborland-extensions"))
|
2018-10-08 09:49:02 +02:00
|
|
|
extensions |= LanguageExtension::Borland;
|
|
|
|
|
return extensions;
|
2013-04-28 13:11:48 +04:00
|
|
|
}
|
|
|
|
|
|
2016-01-18 11:56:54 +01:00
|
|
|
WarningFlags ClangToolChain::warningFlags(const QStringList &cflags) const
|
2013-03-03 21:53:38 +04:00
|
|
|
{
|
2013-09-03 18:48:02 +02:00
|
|
|
WarningFlags flags = GccToolChain::warningFlags(cflags);
|
2022-05-03 15:40:40 +02:00
|
|
|
for (int end = cflags.size(), i = 0; i != end; ++i) {
|
|
|
|
|
const QString &flag = cflags[i];
|
2016-11-24 14:57:07 +01:00
|
|
|
if (flag == "-Wdocumentation")
|
2016-01-18 11:56:54 +01:00
|
|
|
flags |= WarningFlags::Documentation;
|
2016-11-24 14:57:07 +01:00
|
|
|
if (flag == "-Wno-documentation")
|
2016-01-18 11:56:54 +01:00
|
|
|
flags &= ~WarningFlags::Documentation;
|
2013-03-03 21:53:38 +04:00
|
|
|
}
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-27 14:22:15 +02:00
|
|
|
QStringList ClangToolChain::suggestedMkspecList() const
|
2011-05-13 11:48:34 +02:00
|
|
|
{
|
2019-07-22 16:12:21 +02:00
|
|
|
if (const ToolChain * const parentTc = ToolChainManager::findToolChain(m_parentToolChainId))
|
|
|
|
|
return parentTc->suggestedMkspecList();
|
2019-05-27 14:22:15 +02:00
|
|
|
const Abi abi = targetAbi();
|
|
|
|
|
if (abi.os() == Abi::DarwinOS)
|
|
|
|
|
return {"macx-clang", "macx-clang-32", "unsupported/macx-clang", "macx-ios-clang"};
|
|
|
|
|
if (abi.os() == Abi::LinuxOS)
|
|
|
|
|
return {"linux-clang", "unsupported/linux-clang"};
|
|
|
|
|
if (abi.os() == Abi::WindowsOS)
|
|
|
|
|
return {"win32-clang-g++"};
|
2019-07-12 13:40:00 +02:00
|
|
|
if (abi.architecture() == Abi::AsmJsArchitecture && abi.binaryFormat() == Abi::EmscriptenFormat)
|
|
|
|
|
return {"wasm-emscripten"};
|
2019-05-27 14:22:15 +02:00
|
|
|
return {}; // Note: Not supported by Qt yet, so default to the mkspec the Qt was build with
|
2011-05-18 18:38:58 +02:00
|
|
|
}
|
|
|
|
|
|
2013-06-24 17:09:24 +02:00
|
|
|
void ClangToolChain::addToEnvironment(Environment &env) const
|
|
|
|
|
{
|
|
|
|
|
GccToolChain::addToEnvironment(env);
|
2019-01-07 12:15:40 +01:00
|
|
|
|
|
|
|
|
const QString sysroot = sysRoot();
|
|
|
|
|
if (!sysroot.isEmpty())
|
2021-11-09 18:20:14 +01:00
|
|
|
env.prependOrSetPath(FilePath::fromString(sysroot) / "bin");
|
2019-01-07 12:15:40 +01:00
|
|
|
|
2013-06-24 17:09:24 +02:00
|
|
|
// 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,
|
|
|
|
|
// so we better make sure PWD is empty to begin with
|
2016-11-24 14:57:07 +01:00
|
|
|
env.unset("PWD");
|
2013-06-24 17:09:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-01-07 12:15:40 +01:00
|
|
|
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)
|
2023-08-01 20:52:58 +02:00
|
|
|
return {};
|
2019-01-07 12:15:40 +01:00
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
const FilePath mingwCompiler = parentTC->compilerCommand();
|
2019-01-07 12:15:40 +01:00
|
|
|
return mingwCompiler.parentDir().parentDir().toString();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-05 16:58:07 +02:00
|
|
|
ToolChain::BuiltInHeaderPathsRunner ClangToolChain::createBuiltInHeaderPathsRunner(
|
|
|
|
|
const Environment &env) const
|
2019-04-25 16:06:39 +02:00
|
|
|
{
|
|
|
|
|
// Using a clean environment breaks ccache/distcc/etc.
|
2019-07-05 16:58:07 +02:00
|
|
|
Environment fullEnv = env;
|
|
|
|
|
addToEnvironment(fullEnv);
|
2019-04-25 16:06:39 +02:00
|
|
|
|
|
|
|
|
// This runner must be thread-safe!
|
2020-12-14 10:50:40 +01:00
|
|
|
return [fullEnv,
|
2020-11-13 09:39:32 +01:00
|
|
|
compilerCommand = compilerCommand(),
|
2019-04-25 16:06:39 +02:00
|
|
|
platformCodeGenFlags = m_platformCodeGenFlags,
|
|
|
|
|
reinterpretOptions = m_optionsReinterpreter,
|
2019-05-09 11:24:54 +02:00
|
|
|
headerCache = headerPathsCache(),
|
2019-04-25 16:06:39 +02:00
|
|
|
languageId = language(),
|
|
|
|
|
extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags,
|
2022-06-30 09:08:47 +02:00
|
|
|
const FilePath &sysRoot,
|
2019-04-25 16:06:39 +02:00
|
|
|
const QString &target) {
|
2019-07-05 16:58:07 +02:00
|
|
|
return builtInHeaderPaths(fullEnv,
|
2019-04-25 16:06:39 +02:00
|
|
|
compilerCommand,
|
|
|
|
|
platformCodeGenFlags,
|
|
|
|
|
reinterpretOptions,
|
|
|
|
|
headerCache,
|
|
|
|
|
languageId,
|
|
|
|
|
extraHeaderPathsFunction,
|
|
|
|
|
flags,
|
|
|
|
|
sysRoot,
|
|
|
|
|
target);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 12:15:40 +01:00
|
|
|
std::unique_ptr<ToolChainConfigWidget> ClangToolChain::createConfigurationWidget()
|
|
|
|
|
{
|
|
|
|
|
return std::make_unique<ClangToolChainConfigWidget>(this);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-23 16:53:06 +02:00
|
|
|
void ClangToolChain::toMap(Store &data) const
|
2019-01-07 12:15:40 +01:00
|
|
|
{
|
2023-07-20 16:41:45 +02:00
|
|
|
GccToolChain::toMap(data);
|
2019-01-07 12:15:40 +01:00
|
|
|
data.insert(parentToolChainIdKeyC, m_parentToolChainId);
|
2022-08-17 11:14:11 +02:00
|
|
|
data.insert(priorityKeyC, m_priority);
|
2019-01-07 12:15:40 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-23 16:53:06 +02:00
|
|
|
void ClangToolChain::fromMap(const Store &data)
|
2019-01-07 12:15:40 +01:00
|
|
|
{
|
2023-07-21 19:15:02 +02:00
|
|
|
GccToolChain::fromMap(data);
|
|
|
|
|
if (hasError())
|
|
|
|
|
return;
|
2019-01-07 12:15:40 +01:00
|
|
|
|
|
|
|
|
m_parentToolChainId = data.value(parentToolChainIdKeyC).toByteArray();
|
2022-08-17 11:14:11 +02:00
|
|
|
m_priority = data.value(priorityKeyC, PriorityNormal).toInt();
|
2019-01-07 12:15:40 +01:00
|
|
|
syncAutodetectedWithParentToolchains();
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions ClangToolChain::defaultLanguageExtensions() const
|
2013-04-28 13:11:48 +04:00
|
|
|
{
|
2018-10-08 09:49:02 +02:00
|
|
|
return LanguageExtension::Gnu;
|
2013-04-28 13:11:48 +04:00
|
|
|
}
|
|
|
|
|
|
2020-04-16 13:53:05 +02:00
|
|
|
QList<OutputLineParser *> ClangToolChain::createOutputParsers() const
|
2011-05-18 18:38:58 +02:00
|
|
|
{
|
2020-04-08 17:45:39 +02:00
|
|
|
return ClangParser::clangParserSuite();
|
2011-05-13 11:48:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// ClangToolChainFactory
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
ClangToolChainFactory::ClangToolChainFactory()
|
2011-05-13 11:48:34 +02:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("Clang"));
|
2019-05-08 14:56:26 +02:00
|
|
|
setSupportedToolChainType(Constants::CLANG_TOOLCHAIN_TYPEID);
|
2019-05-08 15:36:57 +02:00
|
|
|
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
|
2019-05-10 17:35:04 +02:00
|
|
|
setToolchainConstructor([] { return new ClangToolChain; });
|
2016-07-12 11:33:17 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains ClangToolChainFactory::autoDetect(const ToolchainDetector &detector) const
|
2011-05-13 11:48:34 +02:00
|
|
|
{
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains tcs;
|
|
|
|
|
Toolchains known = detector.alreadyKnown;
|
2018-08-06 12:28:08 +02:00
|
|
|
|
2019-04-05 11:05:06 +02:00
|
|
|
tcs.append(autoDetectToolchains("clang++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::CLANG_TOOLCHAIN_TYPEID, detector));
|
2019-04-05 11:05:06 +02:00
|
|
|
tcs.append(autoDetectToolchains("clang", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::CLANG_TOOLCHAIN_TYPEID, detector));
|
2018-07-11 00:16:44 +03:00
|
|
|
known.append(tcs);
|
2018-08-06 12:30:32 +02:00
|
|
|
|
2021-08-12 09:19:55 +02:00
|
|
|
const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR);
|
2018-08-06 12:30:32 +02:00
|
|
|
if (!compilerPath.isEmpty()) {
|
2021-08-12 09:19:55 +02:00
|
|
|
const FilePath clang = compilerPath.parentDir().pathAppended("clang").withExecutableSuffix();
|
2019-04-05 11:05:06 +02:00
|
|
|
tcs.append(autoDetectToolchains(clang.toString(), DetectVariants::No,
|
|
|
|
|
Constants::C_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID,
|
2022-03-14 16:37:57 +01:00
|
|
|
ToolchainDetector(known, detector.device, detector.searchPaths)));
|
2018-08-06 12:30:32 +02:00
|
|
|
}
|
2019-01-07 12:15:40 +01:00
|
|
|
|
2018-07-11 00:16:44 +03:00
|
|
|
return tcs;
|
2011-05-13 11:48:34 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains ClangToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
2017-02-07 14:18:32 +01:00
|
|
|
{
|
2022-05-13 13:17:02 +02:00
|
|
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
|
|
|
|
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
|
|
|
|
|
|
|
|
|
|
const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
|
|
|
|
|
&& ((fileName.startsWith("clang") && !fileName.startsWith("clang++"))
|
|
|
|
|
|| (fileName == "cc" && resolvedSymlinksFileName.contains("clang")));
|
|
|
|
|
|
|
|
|
|
const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
|
|
|
|
|
&& (fileName.startsWith("clang++")
|
|
|
|
|
|| (fileName == "c++" && resolvedSymlinksFileName.contains("clang")));
|
|
|
|
|
|
|
|
|
|
if (isCCompiler || isCxxCompiler) {
|
2019-07-02 11:31:12 +02:00
|
|
|
return autoDetectToolChain(tcd);
|
2022-01-18 15:42:02 +01:00
|
|
|
}
|
2019-07-02 11:31:12 +02:00
|
|
|
return {};
|
2017-02-07 14:18:32 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-07 12:15:40 +01:00
|
|
|
ClangToolChainConfigWidget::ClangToolChainConfigWidget(ClangToolChain *tc) :
|
|
|
|
|
GccToolChainConfigWidget(tc)
|
|
|
|
|
{
|
2019-01-21 15:07:04 +01:00
|
|
|
if (!HostOsInfo::isWindowsHost() || tc->typeId() != Constants::CLANG_TOOLCHAIN_TYPEID)
|
2019-01-07 12:15:40 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Remove m_abiWidget row because the parent toolchain abi is going to be used.
|
2022-01-26 16:20:28 +01:00
|
|
|
m_mainLayout->removeRow(m_mainLayout->rowCount() - 3); // FIXME: Do something sane instead.
|
2019-01-07 12:15:40 +01:00
|
|
|
m_abiWidget = nullptr;
|
|
|
|
|
|
|
|
|
|
m_parentToolchainCombo = new QComboBox(this);
|
|
|
|
|
m_mainLayout->insertRow(m_mainLayout->rowCount() - 1,
|
2023-01-13 12:38:22 +01:00
|
|
|
Tr::tr("Parent toolchain:"),
|
2019-01-07 12:15:40 +01:00
|
|
|
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<ClangToolChain *>(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();
|
2020-06-30 15:11:15 +02:00
|
|
|
m_parentToolchainCombo->addItem(parentTC ? parentTC->displayName() : QString(),
|
|
|
|
|
parentTC ? parentId : QByteArray());
|
2019-01-07 12:15:40 +01:00
|
|
|
|
|
|
|
|
if (tc->isAutoDetected())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (const ToolChain *mingwTC : mingwToolChains()) {
|
2020-09-08 11:22:11 +02:00
|
|
|
if (mingwTC->id() == parentId)
|
|
|
|
|
continue;
|
|
|
|
|
if (mingwTC->language() != tc->language())
|
|
|
|
|
continue;
|
|
|
|
|
m_parentToolchainCombo->addItem(mingwTC->displayName(), mingwTC->id());
|
2019-01-07 12:15:40 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClangToolChainConfigWidget::setFromClangToolchain()
|
|
|
|
|
{
|
|
|
|
|
GccToolChainConfigWidget::setFromToolchain();
|
|
|
|
|
|
|
|
|
|
if (m_parentToolchainCombo)
|
|
|
|
|
updateParentToolChainComboBox();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClangToolChainConfigWidget::applyImpl()
|
|
|
|
|
{
|
|
|
|
|
GccToolChainConfigWidget::applyImpl();
|
|
|
|
|
if (!m_parentToolchainCombo)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto *tc = static_cast<ClangToolChain *>(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();
|
2019-07-22 16:12:21 +02:00
|
|
|
tc->setTargetAbi(mingwTC->targetAbi());
|
|
|
|
|
tc->setSupportedAbis(mingwTC->supportedAbis());
|
2019-01-07 12:15:40 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClangToolChainConfigWidget::isDirtyImpl() const
|
|
|
|
|
{
|
|
|
|
|
if (GccToolChainConfigWidget::isDirtyImpl())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (!m_parentToolchainCombo)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto tc = static_cast<ClangToolChain *>(toolChain());
|
|
|
|
|
Q_ASSERT(tc);
|
|
|
|
|
const MingwToolChain *parentTC = mingwToolChainFromId(tc->m_parentToolChainId);
|
2020-06-30 15:11:15 +02:00
|
|
|
const QByteArray parentId = parentTC ? parentTC->id() : QByteArray();
|
2019-01-07 12:15:40 +01:00
|
|
|
return parentId != m_parentToolchainCombo->currentData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClangToolChainConfigWidget::makeReadOnlyImpl()
|
|
|
|
|
{
|
|
|
|
|
GccToolChainConfigWidget::makeReadOnlyImpl();
|
|
|
|
|
if (m_parentToolchainCombo)
|
|
|
|
|
m_parentToolchainCombo->setEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// MingwToolChain
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2019-05-08 19:03:15 +02:00
|
|
|
MingwToolChain::MingwToolChain() :
|
|
|
|
|
GccToolChain(Constants::MINGW_TOOLCHAIN_TYPEID)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setTypeDisplayName(Tr::tr("MinGW"));
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 14:22:15 +02:00
|
|
|
QStringList MingwToolChain::suggestedMkspecList() const
|
2011-04-07 13:12:55 +02:00
|
|
|
{
|
2015-02-03 23:59:04 +02:00
|
|
|
if (HostOsInfo::isWindowsHost())
|
2019-05-27 14:22:15 +02:00
|
|
|
return {"win32-g++"};
|
2015-02-03 23:59:04 +02:00
|
|
|
if (HostOsInfo::isLinuxHost()) {
|
2016-11-24 14:57:07 +01:00
|
|
|
if (version().startsWith("4.6."))
|
2019-05-27 14:22:15 +02:00
|
|
|
return {"win32-g++-4.6-cross", "unsupported/win32-g++-4.6-cross"};
|
|
|
|
|
return {"win32-g++-cross", "unsupported/win32-g++-cross"};
|
2012-08-23 15:53:58 +02:00
|
|
|
}
|
2019-05-27 14:22:15 +02:00
|
|
|
return {};
|
2011-04-07 13:12:55 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:49:26 +02:00
|
|
|
FilePath MingwToolChain::makeCommand(const Environment &environment) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2020-11-05 03:16:11 +01:00
|
|
|
return mingwAwareMakeCommand(environment);
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// MingwToolChainFactory
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
MingwToolChainFactory::MingwToolChainFactory()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("MinGW"));
|
2019-05-08 14:56:26 +02:00
|
|
|
setSupportedToolChainType(Constants::MINGW_TOOLCHAIN_TYPEID);
|
2019-05-08 15:36:57 +02:00
|
|
|
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
|
2019-05-10 17:35:04 +02:00
|
|
|
setToolchainConstructor([] { return new MingwToolChain; });
|
2016-07-12 11:33:17 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains MingwToolChainFactory::autoDetect(const ToolchainDetector &detector) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2019-04-05 11:05:06 +02:00
|
|
|
static const auto tcChecker = [](const ToolChain *tc) {
|
|
|
|
|
return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor;
|
|
|
|
|
};
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains result = autoDetectToolchains(
|
2019-04-05 11:05:06 +02:00
|
|
|
"g++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::MINGW_TOOLCHAIN_TYPEID, detector, tcChecker);
|
2019-04-05 11:05:06 +02:00
|
|
|
result += autoDetectToolchains("gcc", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::MINGW_TOOLCHAIN_TYPEID, detector, tcChecker);
|
2016-07-13 09:47:07 +02:00
|
|
|
return result;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains MingwToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
2017-02-07 14:18:32 +01:00
|
|
|
{
|
2021-06-04 07:59:00 +02:00
|
|
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
2022-08-25 12:19:28 +02:00
|
|
|
|
|
|
|
|
const bool cCompiler = tcd.language == Constants::C_LANGUAGE_ID
|
2022-10-19 23:27:04 +02:00
|
|
|
&& ((fileName.startsWith("gcc") || fileName.endsWith("gcc"))
|
|
|
|
|
|| fileName == "cc");
|
2022-08-25 12:19:28 +02:00
|
|
|
|
|
|
|
|
const bool cxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
|
|
|
|
|
&& ((fileName.startsWith("g++") || fileName.endsWith("g++"))
|
|
|
|
|
|| (fileName.startsWith("c++") || fileName.endsWith("c++")));
|
|
|
|
|
|
|
|
|
|
if (cCompiler || cxxCompiler) {
|
2019-07-02 11:31:12 +02:00
|
|
|
return autoDetectToolChain(tcd, [](const ToolChain *tc) {
|
2019-04-05 11:05:06 +02:00
|
|
|
return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor;
|
|
|
|
|
});
|
2022-01-18 15:42:02 +01:00
|
|
|
}
|
2019-07-02 11:31:12 +02:00
|
|
|
|
|
|
|
|
return {};
|
2017-02-07 14:18:32 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// LinuxIccToolChain
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2019-05-08 19:03:15 +02:00
|
|
|
LinuxIccToolChain::LinuxIccToolChain() :
|
|
|
|
|
GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID)
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setTypeDisplayName(Tr::tr("ICC"));
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-28 13:11:48 +04:00
|
|
|
/**
|
2018-10-08 09:49:02 +02:00
|
|
|
* Similar to \a GccToolchain::languageExtensions, but uses "-openmp" instead of
|
2013-04-28 13:11:48 +04:00
|
|
|
* "-fopenmp" and "-fms-dialect[=ver]" instead of "-fms-extensions".
|
|
|
|
|
* @see UNIX manual for "icc"
|
|
|
|
|
*/
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions LinuxIccToolChain::languageExtensions(const QStringList &cxxflags) const
|
2013-04-28 13:11:48 +04:00
|
|
|
{
|
|
|
|
|
QStringList copy = cxxflags;
|
2016-11-24 14:57:07 +01:00
|
|
|
copy.removeAll("-fopenmp");
|
|
|
|
|
copy.removeAll("-fms-extensions");
|
2013-04-28 13:11:48 +04:00
|
|
|
|
2018-10-08 09:49:02 +02:00
|
|
|
LanguageExtensions extensions = GccToolChain::languageExtensions(cxxflags);
|
2016-11-24 14:57:07 +01:00
|
|
|
if (cxxflags.contains("-openmp"))
|
2018-10-08 09:49:02 +02:00
|
|
|
extensions |= LanguageExtension::OpenMP;
|
2016-11-24 14:57:07 +01:00
|
|
|
if (cxxflags.contains("-fms-dialect")
|
|
|
|
|
|| cxxflags.contains("-fms-dialect=8")
|
|
|
|
|
|| cxxflags.contains("-fms-dialect=9")
|
|
|
|
|
|| cxxflags.contains("-fms-dialect=10"))
|
2018-10-08 09:49:02 +02:00
|
|
|
extensions |= LanguageExtension::Microsoft;
|
|
|
|
|
return extensions;
|
2013-04-28 13:11:48 +04:00
|
|
|
}
|
|
|
|
|
|
2020-04-16 13:53:05 +02:00
|
|
|
QList<OutputLineParser *> LinuxIccToolChain::createOutputParsers() const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2020-04-08 17:45:39 +02:00
|
|
|
return LinuxIccParser::iccParserSuite();
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 14:22:15 +02:00
|
|
|
QStringList LinuxIccToolChain::suggestedMkspecList() const
|
2011-04-07 13:12:55 +02:00
|
|
|
{
|
2019-05-27 14:22:15 +02:00
|
|
|
return {QString("linux-icc-%1").arg(targetAbi().wordWidth())};
|
2011-04-07 13:12:55 +02:00
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
// LinuxIccToolChainFactory
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
2013-08-09 17:49:30 +02:00
|
|
|
LinuxIccToolChainFactory::LinuxIccToolChainFactory()
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2023-01-13 12:38:22 +01:00
|
|
|
setDisplayName(Tr::tr("ICC"));
|
2019-05-08 14:56:26 +02:00
|
|
|
setSupportedToolChainType(Constants::LINUXICC_TOOLCHAIN_TYPEID);
|
2019-05-08 15:36:57 +02:00
|
|
|
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
|
2019-05-10 17:35:04 +02:00
|
|
|
setToolchainConstructor([] { return new LinuxIccToolChain; });
|
2016-07-12 11:33:17 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains LinuxIccToolChainFactory::autoDetect(const ToolchainDetector &detector) const
|
2011-02-01 18:36:00 +01:00
|
|
|
{
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains result
|
2019-04-05 11:05:06 +02:00
|
|
|
= autoDetectToolchains("icpc", DetectVariants::No, Constants::CXX_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::LINUXICC_TOOLCHAIN_TYPEID, detector);
|
2019-04-05 11:05:06 +02:00
|
|
|
result += autoDetectToolchains("icc", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
|
2022-01-14 17:29:02 +01:00
|
|
|
Constants::LINUXICC_TOOLCHAIN_TYPEID, detector);
|
2018-08-21 13:53:23 +02:00
|
|
|
return result;
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-14 17:29:02 +01:00
|
|
|
Toolchains LinuxIccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
2017-02-07 14:18:32 +01:00
|
|
|
{
|
2022-05-13 13:17:02 +02:00
|
|
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
2019-07-02 11:31:12 +02:00
|
|
|
if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||
|
2022-01-18 15:42:02 +01:00
|
|
|
(tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) {
|
2019-07-02 11:31:12 +02:00
|
|
|
return autoDetectToolChain(tcd);
|
2022-01-18 15:42:02 +01:00
|
|
|
}
|
2018-08-21 13:53:23 +02:00
|
|
|
return {};
|
2017-02-07 14:18:32 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-18 11:56:54 +01:00
|
|
|
GccToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, WarningFlags &flags) :
|
2016-04-13 15:52:14 +02:00
|
|
|
m_flags(flags)
|
2013-03-03 21:53:38 +04:00
|
|
|
{
|
2016-11-24 14:57:07 +01:00
|
|
|
if (!flag.startsWith("-W")) {
|
2013-03-03 21:53:38 +04:00
|
|
|
m_triggered = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 14:57:07 +01:00
|
|
|
m_doesEnable = !flag.startsWith("-Wno-");
|
2013-03-03 21:53:38 +04:00
|
|
|
if (m_doesEnable)
|
|
|
|
|
m_flagUtf8 = flag.mid(2).toUtf8();
|
|
|
|
|
else
|
|
|
|
|
m_flagUtf8 = flag.mid(5).toUtf8();
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-18 11:56:54 +01:00
|
|
|
void GccToolChain::WarningFlagAdder::operator ()(const char name[], WarningFlags flagsSet)
|
2013-03-03 21:53:38 +04:00
|
|
|
{
|
|
|
|
|
if (m_triggered)
|
|
|
|
|
return;
|
|
|
|
|
if (0 == strcmp(m_flagUtf8.data(), name))
|
|
|
|
|
{
|
|
|
|
|
m_triggered = true;
|
|
|
|
|
if (m_doesEnable)
|
|
|
|
|
m_flags |= flagsSet;
|
|
|
|
|
else
|
|
|
|
|
m_flags &= ~flagsSet;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GccToolChain::WarningFlagAdder::triggered() const
|
|
|
|
|
{
|
|
|
|
|
return m_triggered;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-01 18:36:00 +01:00
|
|
|
} // namespace ProjectExplorer
|
|
|
|
|
|
|
|
|
|
// Unit tests:
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_TESTS
|
|
|
|
|
# include "projectexplorer.h"
|
|
|
|
|
|
|
|
|
|
# include <QTest>
|
2012-02-15 10:42:41 +01:00
|
|
|
# include <QUrl>
|
2011-02-01 18:36:00 +01:00
|
|
|
|
|
|
|
|
namespace ProjectExplorer {
|
|
|
|
|
void ProjectExplorerPlugin::testGccAbiGuessing_data()
|
|
|
|
|
{
|
|
|
|
|
QTest::addColumn<QString>("input");
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::addColumn<QByteArray>("macros");
|
2011-03-10 14:44:49 +01:00
|
|
|
QTest::addColumn<QStringList>("abiList");
|
2011-02-01 18:36:00 +01:00
|
|
|
|
|
|
|
|
QTest::newRow("invalid input")
|
|
|
|
|
<< QString::fromLatin1("Some text")
|
2013-02-20 12:23:45 +01:00
|
|
|
<< QByteArray("")
|
2011-03-10 14:44:49 +01:00
|
|
|
<< (QStringList());
|
2011-02-01 18:36:00 +01:00
|
|
|
QTest::newRow("empty input")
|
|
|
|
|
<< QString::fromLatin1("")
|
2013-02-20 12:23:45 +01:00
|
|
|
<< QByteArray("")
|
|
|
|
|
<< (QStringList());
|
|
|
|
|
QTest::newRow("empty input (with macros)")
|
|
|
|
|
<< QString::fromLatin1("")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n#define __Something\n")
|
2011-03-10 14:44:49 +01:00
|
|
|
<< (QStringList());
|
2013-11-04 13:07:20 +01:00
|
|
|
QTest::newRow("broken input -- 64bit")
|
|
|
|
|
<< QString::fromLatin1("arm-none-foo-gnueabi")
|
|
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n#define __Something\n")
|
2019-07-12 12:35:02 +02:00
|
|
|
<< QStringList({"arm-baremetal-generic-elf-64bit"});
|
2013-11-04 13:07:20 +01:00
|
|
|
QTest::newRow("broken input -- 32bit")
|
2011-02-01 18:36:00 +01:00
|
|
|
<< QString::fromLatin1("arm-none-foo-gnueabi")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n#define __Something\n")
|
2019-07-12 12:35:02 +02:00
|
|
|
<< QStringList({"arm-baremetal-generic-elf-32bit"});
|
2013-11-04 13:07:20 +01:00
|
|
|
QTest::newRow("totally broken input -- 32bit")
|
2011-03-10 14:44:49 +01:00
|
|
|
<< QString::fromLatin1("foo-bar-foo")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n#define __Something\n")
|
2016-11-24 14:57:07 +01:00
|
|
|
<< QStringList();
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 1 (32bit intel)")
|
2011-02-01 18:36:00 +01:00
|
|
|
<< QString::fromLatin1("i686-linux-gnu")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-linux-generic-elf-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 2 (32bit intel)")
|
2011-02-01 18:36:00 +01:00
|
|
|
<< QString::fromLatin1("i486-linux-gnu")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-linux-generic-elf-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 3 (64bit intel)")
|
2011-02-01 18:36:00 +01:00
|
|
|
<< QString::fromLatin1("x86_64-linux-gnu")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2019-04-08 15:13:26 +02:00
|
|
|
<< QStringList("x86-linux-generic-elf-64bit");
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 3 (64bit intel -- non 64bit)")
|
|
|
|
|
<< QString::fromLatin1("x86_64-linux-gnu")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-linux-generic-elf-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 4 (32bit mips)")
|
2011-04-06 10:04:57 +02:00
|
|
|
<< QString::fromLatin1("mipsel-linux-uclibc")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"mips-linux-generic-elf-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 5 (QTCREATORBUG-4690)") // from QTCREATORBUG-4690
|
2011-05-03 14:40:20 +02:00
|
|
|
<< QString::fromLatin1("x86_64-redhat-linux6E")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2019-04-08 15:13:26 +02:00
|
|
|
<< QStringList("x86-linux-generic-elf-64bit");
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 6 (QTCREATORBUG-4690)") // from QTCREATORBUG-4690
|
2011-05-03 14:40:20 +02:00
|
|
|
<< QString::fromLatin1("x86_64-redhat-linux")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2019-04-08 15:13:26 +02:00
|
|
|
<< QStringList("x86-linux-generic-elf-64bit");
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 7 (arm)")
|
2011-07-01 13:39:54 +02:00
|
|
|
<< QString::fromLatin1("armv5tl-montavista-linux-gnueabi")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"arm-linux-generic-elf-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Linux 8 (arm)")
|
2011-08-31 15:24:24 +00:00
|
|
|
<< QString::fromLatin1("arm-angstrom-linux-gnueabi")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"arm-linux-generic-elf-32bit"});
|
2013-03-15 16:36:48 +01:00
|
|
|
QTest::newRow("Linux 9 (ppc)")
|
|
|
|
|
<< QString::fromLatin1("powerpc-nsg-linux")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"ppc-linux-generic-elf-32bit"});
|
2013-03-15 16:36:48 +01:00
|
|
|
QTest::newRow("Linux 10 (ppc 64bit)")
|
|
|
|
|
<< QString::fromLatin1("powerpc64-suse-linux")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"ppc-linux-generic-elf-64bit"});
|
2017-05-24 14:14:39 -07:00
|
|
|
QTest::newRow("Linux 11 (64bit mips)")
|
|
|
|
|
<< QString::fromLatin1("mips64el-linux-uclibc")
|
|
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8")
|
|
|
|
|
<< QStringList({"mips-linux-generic-elf-64bit"});
|
2011-07-01 13:39:54 +02:00
|
|
|
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Mingw 1 (32bit)")
|
|
|
|
|
<< QString::fromLatin1("i686-w64-mingw32")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\r\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-windows-msys-pe-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Mingw 2 (64bit)")
|
2011-02-01 18:36:00 +01:00
|
|
|
<< QString::fromLatin1("i686-w64-mingw32")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\r\n")
|
2019-04-02 15:14:56 +02:00
|
|
|
<< QStringList({"x86-windows-msys-pe-64bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Mingw 3 (32 bit)")
|
2011-02-01 18:36:00 +01:00
|
|
|
<< QString::fromLatin1("mingw32")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\r\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-windows-msys-pe-32bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Cross Mingw 1 (64bit)")
|
2012-02-01 17:09:59 +01:00
|
|
|
<< QString::fromLatin1("amd64-mingw32msvc")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\r\n")
|
2019-04-02 15:14:56 +02:00
|
|
|
<< QStringList({"x86-windows-msys-pe-64bit"});
|
2013-02-20 12:23:45 +01:00
|
|
|
QTest::newRow("Cross Mingw 2 (32bit)")
|
2012-02-01 17:09:59 +01:00
|
|
|
<< QString::fromLatin1("i586-mingw32msvc")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\r\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-windows-msys-pe-32bit"});
|
2011-05-13 11:48:34 +02:00
|
|
|
QTest::newRow("Clang 1: windows")
|
|
|
|
|
<< QString::fromLatin1("x86_64-pc-win32")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\r\n")
|
2019-04-08 15:13:26 +02:00
|
|
|
<< QStringList("x86-windows-msys-pe-64bit");
|
2011-05-13 11:48:34 +02:00
|
|
|
QTest::newRow("Clang 1: linux")
|
|
|
|
|
<< QString::fromLatin1("x86_64-unknown-linux-gnu")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2019-04-08 15:13:26 +02:00
|
|
|
<< QStringList("x86-linux-generic-elf-64bit");
|
2011-02-01 18:36:00 +01:00
|
|
|
QTest::newRow("Mac 1")
|
|
|
|
|
<< QString::fromLatin1("i686-apple-darwin10")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-darwin-generic-mach_o-64bit", "x86-darwin-generic-mach_o-32bit"});
|
2011-03-11 12:01:39 +01:00
|
|
|
QTest::newRow("Mac 2")
|
|
|
|
|
<< QString::fromLatin1("powerpc-apple-darwin10")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"ppc-darwin-generic-mach_o-64bit", "ppc-darwin-generic-mach_o-32bit"});
|
2011-03-11 12:01:39 +01:00
|
|
|
QTest::newRow("Mac 3")
|
|
|
|
|
<< QString::fromLatin1("i686-apple-darwin9")
|
2013-11-04 15:18:26 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-darwin-generic-mach_o-32bit", "x86-darwin-generic-mach_o-64bit"});
|
2011-04-08 16:33:59 +02:00
|
|
|
QTest::newRow("Mac IOS")
|
|
|
|
|
<< QString::fromLatin1("arm-apple-darwin9")
|
2013-11-04 15:18:26 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"arm-darwin-generic-mach_o-32bit", "arm-darwin-generic-mach_o-64bit"});
|
2011-02-01 18:36:00 +01:00
|
|
|
QTest::newRow("Intel 1")
|
|
|
|
|
<< QString::fromLatin1("86_64 x86_64 GNU/Linux")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n")
|
2019-04-08 15:13:26 +02:00
|
|
|
<< QStringList("x86-linux-generic-elf-64bit");
|
2011-05-31 10:06:32 +00:00
|
|
|
QTest::newRow("FreeBSD 1")
|
|
|
|
|
<< QString::fromLatin1("i386-portbld-freebsd9.0")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-bsd-freebsd-elf-32bit"});
|
2011-05-31 10:06:32 +00:00
|
|
|
QTest::newRow("FreeBSD 2")
|
|
|
|
|
<< QString::fromLatin1("i386-undermydesk-freebsd")
|
2013-11-04 13:07:20 +01:00
|
|
|
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n")
|
2017-02-22 15:09:35 +01:00
|
|
|
<< QStringList({"x86-bsd-freebsd-elf-32bit"});
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectExplorerPlugin::testGccAbiGuessing()
|
|
|
|
|
{
|
|
|
|
|
QFETCH(QString, input);
|
2013-02-20 12:23:45 +01:00
|
|
|
QFETCH(QByteArray, macros);
|
2011-03-10 14:44:49 +01:00
|
|
|
QFETCH(QStringList, abiList);
|
2011-02-01 18:36:00 +01:00
|
|
|
|
2019-05-27 11:04:18 +02:00
|
|
|
const Abis al = guessGccAbi(input, ProjectExplorer::Macro::toMacros(macros));
|
2011-03-10 14:44:49 +01:00
|
|
|
QCOMPARE(al.count(), abiList.count());
|
2013-03-15 16:36:48 +01:00
|
|
|
for (int i = 0; i < al.count(); ++i)
|
2011-03-10 14:44:49 +01:00
|
|
|
QCOMPARE(al.at(i).toString(), abiList.at(i));
|
2011-02-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace ProjectExplorer
|
|
|
|
|
|
|
|
|
|
#endif
|
2022-01-20 16:53:55 +01:00
|
|
|
|
|
|
|
|
#include <gcctoolchain.moc>
|