forked from qt-creator/qt-creator
macOS: Fix importing command line builds with CMake
When configuring a CMake project on the command line, CMake will (correctly) find and use the compiler from the current developer directory, usually somewhere in /Applications/Xcode.app/Contents/Developer But Qt Creator auto-detects and sets up the compiler /usr/bin/clang(++) for desktop kits. This leads to a compiler mismatch between kits and the imported build, and to new kits registered in Qt Creator for the import. Since /usr/bin/clang(++) is just a thin wrapper that resolves to the compiler in the current developer directory, resolve that in Qt Creator with "xcrun -f <command>" too (caching the result), and include that when comparing toolchains for importing builds. Fixes: QTCREATORBUG-27591 Change-Id: I301e2a4e267450b488b49d0c32d4ce89001bb5ec Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -394,10 +394,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const
|
|||||||
if (!Utils::contains(allLanguages, [&tcd](const Id& language) {return language == tcd.language;}))
|
if (!Utils::contains(allLanguages, [&tcd](const Id& language) {return language == tcd.language;}))
|
||||||
continue;
|
continue;
|
||||||
ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language);
|
ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language);
|
||||||
if (!tc
|
if (!tc || !tc->matchesCompilerCommand(tcd.compilerPath)) {
|
||||||
|| !Utils::Environment::systemEnvironment()
|
|
||||||
.isSameExecutable(tc->compilerCommand().toString(),
|
|
||||||
tcd.compilerPath.toString())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1580,6 +1580,27 @@ ClangToolChain::~ClangToolChain()
|
|||||||
QObject::disconnect(m_mingwToolchainAddedConnection);
|
QObject::disconnect(m_mingwToolchainAddedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClangToolChain::matchesCompilerCommand(const Utils::FilePath &command,
|
||||||
|
const Utils::Environment &env) const
|
||||||
|
{
|
||||||
|
if (!m_resolvedCompilerCommand) {
|
||||||
|
m_resolvedCompilerCommand = FilePath();
|
||||||
|
if (HostOsInfo::isMacHost()
|
||||||
|
&& compilerCommand().parentDir() == FilePath::fromString("/usr/bin")) {
|
||||||
|
std::unique_ptr<QtcProcess> xcrun(new QtcProcess);
|
||||||
|
xcrun->setCommand({"/usr/bin/xcrun", {"-f", compilerCommand().fileName()}});
|
||||||
|
xcrun->runBlocking();
|
||||||
|
const FilePath output = FilePath::fromString(xcrun->stdOut().trimmed());
|
||||||
|
if (output.isExecutableFile() && output != compilerCommand())
|
||||||
|
m_resolvedCompilerCommand = output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!m_resolvedCompilerCommand->isEmpty()
|
||||||
|
&& env.isSameExecutable(m_resolvedCompilerCommand->toString(), command.toString()))
|
||||||
|
return true;
|
||||||
|
return GccToolChain::matchesCompilerCommand(command, env);
|
||||||
|
}
|
||||||
|
|
||||||
static FilePath mingwAwareMakeCommand(const Environment &environment)
|
static FilePath mingwAwareMakeCommand(const Environment &environment)
|
||||||
{
|
{
|
||||||
const QStringList makes
|
const QStringList makes
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "headerpath.h"
|
#include "headerpath.h"
|
||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
#include <utils/optional.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -211,6 +212,10 @@ public:
|
|||||||
explicit ClangToolChain(Utils::Id typeId);
|
explicit ClangToolChain(Utils::Id typeId);
|
||||||
~ClangToolChain() override;
|
~ClangToolChain() override;
|
||||||
|
|
||||||
|
bool matchesCompilerCommand(
|
||||||
|
const Utils::FilePath &command,
|
||||||
|
const Utils::Environment &env = Utils::Environment::systemEnvironment()) const override;
|
||||||
|
|
||||||
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
|
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
|
||||||
|
|
||||||
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
|
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
|
||||||
@@ -237,6 +242,9 @@ protected:
|
|||||||
void syncAutodetectedWithParentToolchains();
|
void syncAutodetectedWithParentToolchains();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// "resolved" on macOS from /usr/bin/clang(++) etc to <DeveloperDir>/usr/bin/clang(++)
|
||||||
|
// which is used for comparison with matchesCompileCommand
|
||||||
|
mutable Utils::optional<Utils::FilePath> m_resolvedCompilerCommand;
|
||||||
QByteArray m_parentToolChainId;
|
QByteArray m_parentToolChainId;
|
||||||
QMetaObject::Connection m_mingwToolchainAddedConnection;
|
QMetaObject::Connection m_mingwToolchainAddedConnection;
|
||||||
QMetaObject::Connection m_thisToolchainRemovedConnection;
|
QMetaObject::Connection m_thisToolchainRemovedConnection;
|
||||||
|
@@ -414,9 +414,7 @@ ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const
|
|||||||
{
|
{
|
||||||
ToolChainData result;
|
ToolChainData result;
|
||||||
result.tcs = ToolChainManager::toolchains([&tcd](const ToolChain *tc) {
|
result.tcs = ToolChainManager::toolchains([&tcd](const ToolChain *tc) {
|
||||||
return tc->language() == tcd.language &&
|
return tc->language() == tcd.language && tc->matchesCompilerCommand(tcd.compilerPath);
|
||||||
Utils::Environment::systemEnvironment().isSameExecutable(
|
|
||||||
tc->compilerCommand().toString(), tcd.compilerPath.toString());
|
|
||||||
});
|
});
|
||||||
for (const ToolChain *tc : qAsConst(result.tcs)) {
|
for (const ToolChain *tc : qAsConst(result.tcs)) {
|
||||||
const QByteArray tcId = tc->id();
|
const QByteArray tcId = tc->id();
|
||||||
|
@@ -343,6 +343,11 @@ void ToolChain::setCompilerCommand(const FilePath &command)
|
|||||||
toolChainUpdated();
|
toolChainUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ToolChain::matchesCompilerCommand(const Utils::FilePath &command, const Environment &env) const
|
||||||
|
{
|
||||||
|
return env.isSameExecutable(compilerCommand().toString(), command.toString());
|
||||||
|
}
|
||||||
|
|
||||||
void ToolChain::setCompilerCommandKey(const QString &commandKey)
|
void ToolChain::setCompilerCommandKey(const QString &commandKey)
|
||||||
{
|
{
|
||||||
d->m_compilerCommandKey = commandKey;
|
d->m_compilerCommandKey = commandKey;
|
||||||
|
@@ -156,6 +156,9 @@ public:
|
|||||||
|
|
||||||
virtual Utils::FilePath compilerCommand() const; // FIXME: De-virtualize.
|
virtual Utils::FilePath compilerCommand() const; // FIXME: De-virtualize.
|
||||||
void setCompilerCommand(const Utils::FilePath &command);
|
void setCompilerCommand(const Utils::FilePath &command);
|
||||||
|
virtual bool matchesCompilerCommand(
|
||||||
|
const Utils::FilePath &command,
|
||||||
|
const Utils::Environment &env = Utils::Environment::systemEnvironment()) const;
|
||||||
|
|
||||||
virtual QList<Utils::OutputLineParser *> createOutputParsers() const = 0;
|
virtual QList<Utils::OutputLineParser *> createOutputParsers() const = 0;
|
||||||
|
|
||||||
|
@@ -1390,7 +1390,7 @@ void QmakeBuildSystem::testToolChain(ToolChain *tc, const FilePath &path) const
|
|||||||
const Utils::FilePath expected = tc->compilerCommand();
|
const Utils::FilePath expected = tc->compilerCommand();
|
||||||
Environment env = buildConfiguration()->environment();
|
Environment env = buildConfiguration()->environment();
|
||||||
|
|
||||||
if (env.isSameExecutable(path.toString(), expected.toString()))
|
if (tc->matchesCompilerCommand(expected, env))
|
||||||
return;
|
return;
|
||||||
const QPair<Utils::FilePath, Utils::FilePath> pair = qMakePair(expected, path);
|
const QPair<Utils::FilePath, Utils::FilePath> pair = qMakePair(expected, path);
|
||||||
if (m_toolChainWarnings.contains(pair))
|
if (m_toolChainWarnings.contains(pair))
|
||||||
|
Reference in New Issue
Block a user