CompilationDatabase: Asjust the sysroot and target handling

If the sysroot option is found - set it as a kit sysroot (only
in CompilationDatabase project where we have a cloned kit
which does not affect the other existing kits).
In other cases use the backup for the sysroot from the
toolchain (can exist for clang toolchains based on mingw).

Provide target when searching builtin include paths for clang.

Fixes: QTCREATORBUG-22339
Change-Id: Ibe07c2e490ba4f7e0d259e6df698d641dbfd0298
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Ivan Donchevskii
2019-04-25 16:06:39 +02:00
committed by Ivan Donchevskii
parent a5148b5363
commit cc9d246b02
12 changed files with 172 additions and 81 deletions

View File

@@ -302,13 +302,13 @@ ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner
HeaderPathsCachePtr headerPathsCache = m_headerPathsCache;
return [env, compilerCommand, headerPathsCache, languageId]
(const QStringList &flags, const QString &fileName) {
return [env, compilerCommand, headerPathsCache, languageId](const QStringList &flags,
const QString &fileName,
const QString &) {
Q_UNUSED(flags)
Q_UNUSED(fileName)
const HeaderPaths paths = dumpHeaderPaths(compilerCommand, languageId,
env.toStringList());
const HeaderPaths paths = dumpHeaderPaths(compilerCommand, languageId, env.toStringList());
headerPathsCache->insert({}, paths);
return paths;
@@ -318,7 +318,7 @@ ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner
HeaderPaths IarToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
const FileName &fileName) const
{
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString());
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
}
void IarToolChain::addToEnvironment(Environment &env) const

View File

@@ -315,8 +315,8 @@ ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunne
HeaderPathsCachePtr headerPathsCache = m_headerPathsCache;
return [compilerCommand, headerPathsCache]
(const QStringList &flags, const QString &fileName) {
return [compilerCommand,
headerPathsCache](const QStringList &flags, const QString &fileName, const QString &) {
Q_UNUSED(flags)
Q_UNUSED(fileName)
@@ -330,7 +330,7 @@ ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunne
HeaderPaths KeilToolchain::builtInHeaderPaths(const QStringList &cxxFlags,
const FileName &fileName) const
{
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString());
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
}
void KeilToolchain::addToEnvironment(Environment &env) const

View File

@@ -298,13 +298,13 @@ ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunne
HeaderPathsCachePtr headerPathsCache = m_headerPathsCache;
return [env, compilerCommand, headerPathsCache, languageId, abi]
(const QStringList &flags, const QString &fileName) {
return [env, compilerCommand, headerPathsCache, languageId, abi](const QStringList &flags,
const QString &fileName,
const QString &) {
Q_UNUSED(flags)
Q_UNUSED(fileName)
const HeaderPaths paths = dumpHeaderPaths(compilerCommand, env.toStringList(),
abi);
const HeaderPaths paths = dumpHeaderPaths(compilerCommand, env.toStringList(), abi);
headerPathsCache->insert({}, paths);
return paths;
@@ -314,7 +314,7 @@ ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunne
HeaderPaths SdccToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
const FileName &fileName) const
{
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString());
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
}
void SdccToolChain::addToEnvironment(Environment &env) const

View File

@@ -92,6 +92,11 @@ bool isGccCompiler(const QString &compilerName)
|| (compilerName.contains("g++") && !compilerName.contains("clang"));
}
bool isClCompatibleCompiler(const QString &compilerName)
{
return compilerName.endsWith("cl");
}
Core::Id getCompilerId(QString compilerName)
{
if (Utils::HostOsInfo::isWindowsHost()) {
@@ -99,9 +104,9 @@ Core::Id getCompilerId(QString compilerName)
compilerName.chop(4);
if (isGccCompiler(compilerName))
return ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID;
// Default is clang-cl
if (isClCompatibleCompiler(compilerName))
return ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID;
return ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID;
}
if (isGccCompiler(compilerName))
return ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
@@ -196,8 +201,7 @@ void addDriverModeFlagIfNeeded(const ToolChain *toolchain,
CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile,
Kit *kit,
ToolChain *&cToolchain,
ToolChain *&cxxToolchain,
CppTools::KitInfo &kitInfo,
const QString &workingDir,
const Utils::FileName &fileName,
QStringList flags)
@@ -212,7 +216,8 @@ CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile,
flags,
headerPaths,
macros,
fileKind);
fileKind,
kitInfo.sysRootPath);
CppTools::RawProjectPart rpp;
rpp.setProjectFileLocation(projectFile.toString());
@@ -224,21 +229,23 @@ CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile,
if (fileKind == CppTools::ProjectFile::Kind::CHeader
|| fileKind == CppTools::ProjectFile::Kind::CSource) {
if (!cToolchain) {
cToolchain = toolchainFromFlags(kit, originalFlags,
if (!kitInfo.cToolChain) {
kitInfo.cToolChain = toolchainFromFlags(kit,
originalFlags,
ProjectExplorer::Constants::C_LANGUAGE_ID);
ToolChainKitAspect::setToolChain(kit, cToolchain);
ToolChainKitAspect::setToolChain(kit, kitInfo.cToolChain);
}
addDriverModeFlagIfNeeded(cToolchain, flags, originalFlags);
rpp.setFlagsForC({cToolchain, flags});
addDriverModeFlagIfNeeded(kitInfo.cToolChain, flags, originalFlags);
rpp.setFlagsForC({kitInfo.cToolChain, flags});
} else {
if (!cxxToolchain) {
cxxToolchain = toolchainFromFlags(kit, originalFlags,
if (!kitInfo.cxxToolChain) {
kitInfo.cxxToolChain = toolchainFromFlags(kit,
originalFlags,
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
ToolChainKitAspect::setToolChain(kit, cxxToolchain);
ToolChainKitAspect::setToolChain(kit, kitInfo.cxxToolChain);
}
addDriverModeFlagIfNeeded(cxxToolchain, flags, originalFlags);
rpp.setFlagsForCxx({cxxToolchain, flags});
addDriverModeFlagIfNeeded(kitInfo.cxxToolChain, flags, originalFlags);
rpp.setFlagsForCxx({kitInfo.cxxToolChain, flags});
}
return rpp;
@@ -433,8 +440,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName
CppTools::RawProjectPart rpp = makeRawProjectPart(projectFile,
m_kit.get(),
kitInfo.cToolChain,
kitInfo.cxxToolChain,
kitInfo,
entry.workingDir,
entry.fileName,
entry.flags);

View File

@@ -98,7 +98,8 @@ void filteredFlags(const QString &fileName,
QStringList &flags,
HeaderPaths &headerPaths,
Macros &macros,
CppTools::ProjectFile::Kind &fileKind)
CppTools::ProjectFile::Kind &fileKind,
QString &sysRoot)
{
if (flags.empty())
return;
@@ -182,6 +183,12 @@ void filteredFlags(const QString &fileName,
continue;
}
if (flag.startsWith("--sysroot=")) {
if (sysRoot.isEmpty())
sysRoot = flag.mid(10);
continue;
}
if ((flag.startsWith("-std=") || flag.startsWith("/std:"))
&& fileKind == CppTools::ProjectFile::Unclassified) {
const bool cpp = (flag.contains("c++") || flag.contains("gnu++"));

View File

@@ -45,7 +45,8 @@ void filteredFlags(const QString &fileName,
QStringList &flags,
QVector<ProjectExplorer::HeaderPath> &headerPaths,
QVector<ProjectExplorer::Macro> &macros,
CppTools::ProjectFile::Kind &fileKind);
CppTools::ProjectFile::Kind &fileKind,
QString &sysRoot);
QStringList splitCommandLine(QString commandLine, QSet<QString> &flagsCache);

View File

@@ -182,7 +182,9 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
// Header paths
if (tcInfo.headerPathsRunner) {
const ProjectExplorer::HeaderPaths builtInHeaderPaths
= tcInfo.headerPathsRunner(flags.commandLineFlags, tcInfo.sysRootPath);
= tcInfo.headerPathsRunner(flags.commandLineFlags,
tcInfo.sysRootPath,
tcInfo.targetTriple);
ProjectExplorer::HeaderPaths &headerPaths = part->headerPaths;
for (const ProjectExplorer::HeaderPath &header : builtInHeaderPaths) {

View File

@@ -169,7 +169,7 @@ ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRun
const HeaderPaths builtInHeaderPaths = m_builtInHeaderPaths;
// This runner must be thread-safe!
return [builtInHeaderPaths](const QStringList &cxxFlags, const QString &) {
return [builtInHeaderPaths](const QStringList &cxxFlags, const QString &, const QString &) {
HeaderPaths flagHeaderPaths;
for (const QString &cxxFlag : cxxFlags) {
if (cxxFlag.startsWith(QLatin1String("-I"))) {
@@ -184,7 +184,7 @@ ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRun
HeaderPaths CustomToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
const FileName &fileName) const
{
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString());
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
}
void CustomToolChain::addToEnvironment(Environment &env) const

View File

@@ -569,33 +569,34 @@ void GccToolChain::initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extra
m_extraHeaderPathsFunction = std::move(extraHeaderPathsFunction);
}
ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner() const
HeaderPaths GccToolChain::builtInHeaderPaths(const Utils::Environment &env,
const Utils::FileName &compilerCommand,
const QStringList &platformCodeGenFlags,
OptionsReinterpreter reinterpretOptions,
std::shared_ptr<Cache<HeaderPaths>> headerCache,
Core::Id languageId,
ExtraHeaderPathsFunction extraHeaderPathsFunction,
const QStringList &flags,
const QString &sysRoot,
const QString &originalTargetTriple)
{
// Using a clean environment breaks ccache/distcc/etc.
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
QStringList arguments = gccPrepareArguments(flags,
sysRoot,
platformCodeGenFlags,
languageId,
reinterpretOptions);
const Utils::FileName compilerCommand = m_compilerCommand;
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
QTC_CHECK(reinterpretOptions);
std::shared_ptr<Cache<HeaderPaths>> headerCache = m_headerPathsCache;
Core::Id languageId = language();
// This runner must be thread-safe!
return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, headerCache, languageId,
extraHeaderPathsFunction = m_extraHeaderPathsFunction]
(const QStringList &flags, const QString &sysRoot) {
QStringList arguments = gccPrepareArguments(flags, sysRoot, platformCodeGenFlags,
languageId, reinterpretOptions);
// Must be clang case only.
if (!originalTargetTriple.isEmpty())
arguments << "-target" << originalTargetTriple;
const Utils::optional<HeaderPaths> cachedPaths = headerCache->check(arguments);
if (cachedPaths)
return cachedPaths.value();
HeaderPaths paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env),
arguments, env.toStringList());
arguments,
env.toStringList());
extraHeaderPathsFunction(paths);
headerCache->insert(arguments, paths);
@@ -603,18 +604,48 @@ ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner
for (const HeaderPath &hp : paths) {
qCDebug(gccLog) << compilerCommand.toUserOutput()
<< (languageId == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
<< arguments.join(", ") << "]"
<< hp.path;
<< arguments.join(", ") << "]" << hp.path;
}
return paths;
}
ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner() const
{
// Using a clean environment breaks ccache/distcc/etc.
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
// This runner must be thread-safe!
return [env,
compilerCommand = m_compilerCommand,
platformCodeGenFlags = m_platformCodeGenFlags,
reinterpretOptions = m_optionsReinterpreter,
headerCache = m_headerPathsCache,
languageId = language(),
extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags,
const QString &sysRoot,
const QString &) {
return builtInHeaderPaths(env,
compilerCommand,
platformCodeGenFlags,
reinterpretOptions,
headerCache,
languageId,
extraHeaderPathsFunction,
flags,
sysRoot,
/*target=*/""); // Target must be empty for gcc.
};
}
HeaderPaths GccToolChain::builtInHeaderPaths(const QStringList &flags,
const FileName &sysRoot) const
const FileName &sysRootPath) const
{
return createBuiltInHeaderPathsRunner()(flags, sysRoot.toString());
return createBuiltInHeaderPathsRunner()(flags,
sysRootPath.isEmpty() ? sysRoot()
: sysRootPath.toString(),
originalTargetTriple());
}
void GccToolChain::addCommandPathToEnvironment(const FileName &command, Environment &env)
@@ -1398,6 +1429,35 @@ QString ClangToolChain::sysRoot() const
return mingwCompiler.parentDir().parentDir().toString();
}
ToolChain::BuiltInHeaderPathsRunner ClangToolChain::createBuiltInHeaderPathsRunner() const
{
// Using a clean environment breaks ccache/distcc/etc.
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
// This runner must be thread-safe!
return [env,
compilerCommand = m_compilerCommand,
platformCodeGenFlags = m_platformCodeGenFlags,
reinterpretOptions = m_optionsReinterpreter,
headerCache = m_headerPathsCache,
languageId = language(),
extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags,
const QString &sysRoot,
const QString &target) {
return builtInHeaderPaths(env,
compilerCommand,
platformCodeGenFlags,
reinterpretOptions,
headerCache,
languageId,
extraHeaderPathsFunction,
flags,
sysRoot,
target);
};
}
std::unique_ptr<ToolChainConfigWidget> ClangToolChain::createConfigurationWidget()
{
return std::make_unique<ClangToolChainConfigWidget>(this);

View File

@@ -86,7 +86,7 @@ public:
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
HeaderPaths builtInHeaderPaths(const QStringList &flags,
const Utils::FileName &sysRoot) const override;
const Utils::FileName &sysRootPath) const override;
void addToEnvironment(Utils::Environment &env) const override;
QString makeCommand(const Utils::Environment &environment) const override;
@@ -151,6 +151,17 @@ protected:
using ExtraHeaderPathsFunction = std::function<void(HeaderPaths &)>;
void initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extraHeaderPathsFunction) const;
static HeaderPaths builtInHeaderPaths(const Utils::Environment &env,
const Utils::FileName &compilerCommand,
const QStringList &platformCodeGenFlags,
OptionsReinterpreter reinterpretOptions,
std::shared_ptr<Cache<HeaderPaths>> headerCache,
Core::Id languageId,
ExtraHeaderPathsFunction extraHeaderPathsFunction,
const QStringList &flags,
const QString &sysRoot,
const QString &originalTargetTriple);
static HeaderPaths gccHeaderPaths(const Utils::FileName &gcc, const QStringList &args,
const QStringList &env);
@@ -179,12 +190,16 @@ private:
Core::Id languageId,
OptionsReinterpreter reinterpretOptions);
protected:
Utils::FileName m_compilerCommand;
QStringList m_platformCodeGenFlags;
QStringList m_platformLinkerFlags;
OptionsReinterpreter m_optionsReinterpreter = [](const QStringList &v) { return v; };
mutable std::shared_ptr<Cache<HeaderPaths>> m_headerPathsCache;
mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {};
private:
Abi m_targetAbi;
mutable QList<Abi> m_supportedAbis;
mutable QString m_originalTargetTriple;
@@ -192,8 +207,6 @@ private:
mutable QString m_version;
mutable std::shared_ptr<Cache<MacroInspectionReport, 64>> m_predefinedMacrosCache;
mutable std::shared_ptr<Cache<HeaderPaths>> m_headerPathsCache;
mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {};
friend class Internal::GccToolChainConfigWidget;
friend class Internal::GccToolChainFactory;
@@ -226,6 +239,8 @@ public:
QString originalTargetTriple() const override;
QString sysRoot() const override;
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
QVariantMap toMap() const override;

View File

@@ -1131,7 +1131,7 @@ ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunne
Utils::Environment env(m_lastEnvironment);
addToEnvironment(env);
return [this, env](const QStringList &, const QString &) {
return [this, env](const QStringList &, const QString &, const QString &) {
QMutexLocker locker(m_headerPathsMutex);
if (m_headerPaths.isEmpty()) {
foreach (const QString &path,
@@ -1146,7 +1146,7 @@ ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunne
HeaderPaths MsvcToolChain::builtInHeaderPaths(const QStringList &cxxflags,
const Utils::FileName &sysRoot) const
{
return createBuiltInHeaderPathsRunner()(cxxflags, sysRoot.toString());
return createBuiltInHeaderPathsRunner()(cxxflags, sysRoot.toString(), "");
}
void MsvcToolChain::addToEnvironment(Utils::Environment &env) const

View File

@@ -126,8 +126,8 @@ public:
virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0;
// A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread.
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(const QStringList &cxxflags,
const QString &sysRoot)>;
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(
const QStringList &cxxflags, const QString &sysRoot, const QString &originalTargetTriple)>;
virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const = 0;
virtual HeaderPaths builtInHeaderPaths(const QStringList &cxxflags,
const Utils::FileName &sysRoot) const = 0;