forked from qt-creator/qt-creator
bare-metal: Search the include paths of IAR toolchain
Seems, the IAR compiler has not an explicitly options to show a list of system include paths. But, we use the following trick to enumerate this directories. We specify the '--preinclude' option with the wrong value (e.g. a dot). In this case the compiler fails and its error output contains a mention about the using search paths in a form of tokens: ' searched: "<path/to/include>" '. Where are the resulting paths are escaped with a quotes. Change-Id: Ie9cbf08ae84971bfc8ea4b1cd2ffe3385324710f Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -103,6 +103,71 @@ static Macros dumpPredefinedMacros(const FileName &compiler, const QStringList &
|
|||||||
return Macro::toMacros(output);
|
return Macro::toMacros(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HeaderPaths dumpHeaderPaths(const FileName &compiler, const Core::Id languageId,
|
||||||
|
const QStringList &env)
|
||||||
|
{
|
||||||
|
if (!compiler.exists())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Seems, that IAR compiler has not options to show a list of system
|
||||||
|
// include directories. But, we can use the following trick to enumerate
|
||||||
|
// this directories. We need to specify the '--preinclude' option with
|
||||||
|
// the wrong value (e.g. a dot). In this case the compiler fails and its
|
||||||
|
// error output will contains a mention about the using search directories
|
||||||
|
// in a form of tokens, like: ' searched: "<path/to/include>" '. Where are
|
||||||
|
// the resulting paths are escaped with a quotes.
|
||||||
|
|
||||||
|
QTemporaryFile fakeIn;
|
||||||
|
if (!fakeIn.open())
|
||||||
|
return {};
|
||||||
|
fakeIn.close();
|
||||||
|
|
||||||
|
SynchronousProcess cpp;
|
||||||
|
cpp.setEnvironment(env);
|
||||||
|
cpp.setTimeoutS(10);
|
||||||
|
|
||||||
|
QStringList arguments;
|
||||||
|
arguments.push_back(fakeIn.fileName());
|
||||||
|
if (languageId == ProjectExplorer::Constants::CXX_LANGUAGE_ID)
|
||||||
|
arguments.push_back("--ec++");
|
||||||
|
arguments.push_back("--preinclude");
|
||||||
|
arguments.push_back(".");
|
||||||
|
|
||||||
|
// Note: Response should retutn an error, just don't check on errors.
|
||||||
|
const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(),
|
||||||
|
arguments);
|
||||||
|
|
||||||
|
HeaderPaths headerPaths;
|
||||||
|
|
||||||
|
const QByteArray output = response.allOutput().toUtf8();
|
||||||
|
for (auto pos = 0; pos < output.size(); ++pos) {
|
||||||
|
const int searchIndex = output.indexOf("searched:", pos);
|
||||||
|
if (searchIndex == -1)
|
||||||
|
break;
|
||||||
|
const int startQuoteIndex = output.indexOf('"', searchIndex + 1);
|
||||||
|
if (startQuoteIndex == -1)
|
||||||
|
break;
|
||||||
|
const int endQuoteIndex = output.indexOf('"', startQuoteIndex + 1);
|
||||||
|
if (endQuoteIndex == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const QByteArray candidate = output.mid(startQuoteIndex + 1,
|
||||||
|
endQuoteIndex - startQuoteIndex - 1)
|
||||||
|
.simplified();
|
||||||
|
|
||||||
|
const QString headerPath = QFileInfo(QFile::decodeName(candidate))
|
||||||
|
.canonicalFilePath();
|
||||||
|
|
||||||
|
// Ignore the QtC binary directory path.
|
||||||
|
if (headerPath != QCoreApplication::applicationDirPath())
|
||||||
|
headerPaths.append({headerPath, HeaderPathType::BuiltIn});
|
||||||
|
|
||||||
|
pos = endQuoteIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerPaths;
|
||||||
|
}
|
||||||
|
|
||||||
static Abi::Architecture guessArchitecture(const Macros ¯os)
|
static Abi::Architecture guessArchitecture(const Macros ¯os)
|
||||||
{
|
{
|
||||||
for (const Macro ¯o : macros) {
|
for (const Macro ¯o : macros) {
|
||||||
@@ -155,7 +220,8 @@ static QString buildDisplayName(Abi::Architecture arch, Core::Id language,
|
|||||||
|
|
||||||
IarToolChain::IarToolChain(Detection d) :
|
IarToolChain::IarToolChain(Detection d) :
|
||||||
ToolChain(Constants::IAREW_TOOLCHAIN_TYPEID, d),
|
ToolChain(Constants::IAREW_TOOLCHAIN_TYPEID, d),
|
||||||
m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>())
|
m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
|
||||||
|
m_headerPathsCache(std::make_shared<HeaderPathsCache>())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
IarToolChain::IarToolChain(Core::Id language, Detection d) :
|
IarToolChain::IarToolChain(Core::Id language, Detection d) :
|
||||||
@@ -227,15 +293,31 @@ WarningFlags IarToolChain::warningFlags(const QStringList &cxxflags) const
|
|||||||
|
|
||||||
ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner() const
|
ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner() const
|
||||||
{
|
{
|
||||||
return {};
|
Environment env = Environment::systemEnvironment();
|
||||||
|
addToEnvironment(env);
|
||||||
|
|
||||||
|
const Utils::FileName compilerCommand = m_compilerCommand;
|
||||||
|
const Core::Id languageId = language();
|
||||||
|
|
||||||
|
HeaderPathsCachePtr headerPathsCache = m_headerPathsCache;
|
||||||
|
|
||||||
|
return [env, compilerCommand, headerPathsCache, languageId]
|
||||||
|
(const QStringList &flags, const QString &fileName) {
|
||||||
|
Q_UNUSED(flags)
|
||||||
|
Q_UNUSED(fileName)
|
||||||
|
|
||||||
|
const HeaderPaths paths = dumpHeaderPaths(compilerCommand, languageId,
|
||||||
|
env.toStringList());
|
||||||
|
headerPathsCache->insert({}, paths);
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderPaths IarToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
|
HeaderPaths IarToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
|
||||||
const FileName &fileName) const
|
const FileName &fileName) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(cxxFlags)
|
return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString());
|
||||||
Q_UNUSED(fileName)
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IarToolChain::addToEnvironment(Environment &env) const
|
void IarToolChain::addToEnvironment(Environment &env) const
|
||||||
@@ -311,6 +393,7 @@ ToolChain *IarToolChain::clone() const
|
|||||||
void IarToolChain::toolChainUpdated()
|
void IarToolChain::toolChainUpdated()
|
||||||
{
|
{
|
||||||
m_predefinedMacrosCache->invalidate();
|
m_predefinedMacrosCache->invalidate();
|
||||||
|
m_headerPathsCache->invalidate();
|
||||||
ToolChain::toolChainUpdated();
|
ToolChain::toolChainUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ private:
|
|||||||
using MacrosCache = std::shared_ptr<ProjectExplorer::Cache<MacroInspectionReport, 64>>;
|
using MacrosCache = std::shared_ptr<ProjectExplorer::Cache<MacroInspectionReport, 64>>;
|
||||||
mutable MacrosCache m_predefinedMacrosCache;
|
mutable MacrosCache m_predefinedMacrosCache;
|
||||||
|
|
||||||
|
using HeaderPathsCache = ProjectExplorer::Cache<ProjectExplorer::HeaderPaths>;
|
||||||
|
using HeaderPathsCachePtr = std::shared_ptr<HeaderPathsCache>;
|
||||||
|
mutable HeaderPathsCachePtr m_headerPathsCache;
|
||||||
|
|
||||||
friend class IarToolChainFactory;
|
friend class IarToolChainFactory;
|
||||||
friend class IarToolChainConfigWidget;
|
friend class IarToolChainConfigWidget;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user