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;}))
|
||||
continue;
|
||||
ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language);
|
||||
if (!tc
|
||||
|| !Utils::Environment::systemEnvironment()
|
||||
.isSameExecutable(tc->compilerCommand().toString(),
|
||||
tcd.compilerPath.toString())) {
|
||||
if (!tc || !tc->matchesCompilerCommand(tcd.compilerPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -1580,6 +1580,27 @@ ClangToolChain::~ClangToolChain()
|
||||
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)
|
||||
{
|
||||
const QStringList makes
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "headerpath.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -211,6 +212,10 @@ public:
|
||||
explicit ClangToolChain(Utils::Id typeId);
|
||||
~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::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
|
||||
@@ -237,6 +242,9 @@ protected:
|
||||
void syncAutodetectedWithParentToolchains();
|
||||
|
||||
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;
|
||||
QMetaObject::Connection m_mingwToolchainAddedConnection;
|
||||
QMetaObject::Connection m_thisToolchainRemovedConnection;
|
||||
|
@@ -414,9 +414,7 @@ ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const
|
||||
{
|
||||
ToolChainData result;
|
||||
result.tcs = ToolChainManager::toolchains([&tcd](const ToolChain *tc) {
|
||||
return tc->language() == tcd.language &&
|
||||
Utils::Environment::systemEnvironment().isSameExecutable(
|
||||
tc->compilerCommand().toString(), tcd.compilerPath.toString());
|
||||
return tc->language() == tcd.language && tc->matchesCompilerCommand(tcd.compilerPath);
|
||||
});
|
||||
for (const ToolChain *tc : qAsConst(result.tcs)) {
|
||||
const QByteArray tcId = tc->id();
|
||||
|
@@ -343,6 +343,11 @@ void ToolChain::setCompilerCommand(const FilePath &command)
|
||||
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)
|
||||
{
|
||||
d->m_compilerCommandKey = commandKey;
|
||||
|
@@ -156,6 +156,9 @@ public:
|
||||
|
||||
virtual Utils::FilePath compilerCommand() const; // FIXME: De-virtualize.
|
||||
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;
|
||||
|
||||
|
@@ -1390,7 +1390,7 @@ void QmakeBuildSystem::testToolChain(ToolChain *tc, const FilePath &path) const
|
||||
const Utils::FilePath expected = tc->compilerCommand();
|
||||
Environment env = buildConfiguration()->environment();
|
||||
|
||||
if (env.isSameExecutable(path.toString(), expected.toString()))
|
||||
if (tc->matchesCompilerCommand(expected, env))
|
||||
return;
|
||||
const QPair<Utils::FilePath, Utils::FilePath> pair = qMakePair(expected, path);
|
||||
if (m_toolChainWarnings.contains(pair))
|
||||
|
Reference in New Issue
Block a user