moc: Add --debug-includes option to moc
Because moc silently ignores missing headers, or sometimes includes the wrong header, it is useful to have a facility to print which header paths were considered and found. Add a new --debug-includes option that does that. Task-number: QTBUG-101775 Change-Id: I72b294ae53d6e47252c7d8afe0f2245da78bfadb Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>bb10
parent
7db6aa4395
commit
da97bc5f53
|
|
@ -306,6 +306,10 @@ int runMoc(int argc, char **argv)
|
|||
jsonOption.setDescription(QStringLiteral("In addition to generating C++ code, create a machine-readable JSON file in a file that matches the output file and an extra .json extension."));
|
||||
parser.addOption(jsonOption);
|
||||
|
||||
QCommandLineOption debugIncludesOption(QStringLiteral("debug-includes"));
|
||||
debugIncludesOption.setDescription(QStringLiteral("Display debug messages of each considered include path."));
|
||||
parser.addOption(debugIncludesOption);
|
||||
|
||||
QCommandLineOption collectOption(QStringLiteral("collect-json"));
|
||||
collectOption.setDescription(QStringLiteral("Instead of processing C++ code, collect previously generated JSON output into a single file."));
|
||||
parser.addOption(collectOption);
|
||||
|
|
@ -358,6 +362,7 @@ int runMoc(int argc, char **argv)
|
|||
|
||||
const bool ignoreConflictingOptions = parser.isSet(ignoreConflictsOption);
|
||||
pp.preprocessOnly = parser.isSet(preprocessOption);
|
||||
pp.setDebugIncludes(parser.isSet(debugIncludesOption));
|
||||
if (parser.isSet(noIncludeOption)) {
|
||||
moc.noInclude = true;
|
||||
autoInclude = false;
|
||||
|
|
@ -499,6 +504,17 @@ int runMoc(int argc, char **argv)
|
|||
moc.currentFilenames.push(filename.toLocal8Bit());
|
||||
moc.includes = pp.includes;
|
||||
|
||||
if (Q_UNLIKELY(parser.isSet(debugIncludesOption))) {
|
||||
fprintf(stderr, "debug-includes: include search list:\n");
|
||||
|
||||
for (auto &includePath : pp.includes) {
|
||||
fprintf(stderr, "debug-includes: '%s' framework: %d \n",
|
||||
includePath.path.constData(),
|
||||
includePath.isFrameworkPath);
|
||||
}
|
||||
fprintf(stderr, "debug-includes: end of search list.\n");
|
||||
}
|
||||
|
||||
// 1. preprocess
|
||||
const auto includeFiles = parser.values(includeOption);
|
||||
QStringList validIncludesFiles;
|
||||
|
|
|
|||
|
|
@ -1016,9 +1016,15 @@ static void mergeStringLiterals(Symbols *_symbols)
|
|||
}
|
||||
|
||||
static QByteArray searchIncludePaths(const QList<Parser::IncludePath> &includepaths,
|
||||
const QByteArray &include)
|
||||
const QByteArray &include,
|
||||
const bool debugIncludes)
|
||||
{
|
||||
QFileInfo fi;
|
||||
|
||||
if (Q_UNLIKELY(debugIncludes)) {
|
||||
fprintf(stderr, "debug-includes: searching for '%s'\n", include.constData());
|
||||
}
|
||||
|
||||
for (int j = 0; j < includepaths.size() && !fi.exists(); ++j) {
|
||||
const Parser::IncludePath &p = includepaths.at(j);
|
||||
if (p.isFrameworkPath) {
|
||||
|
|
@ -1030,6 +1036,12 @@ static QByteArray searchIncludePaths(const QList<Parser::IncludePath> &includepa
|
|||
} else {
|
||||
fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include));
|
||||
}
|
||||
|
||||
if (Q_UNLIKELY(debugIncludes)) {
|
||||
const auto candidate = fi.filePath().toLocal8Bit();
|
||||
fprintf(stderr, "debug-includes: considering '%s'\n", candidate.constData());
|
||||
}
|
||||
|
||||
// try again, maybe there's a file later in the include paths with the same name
|
||||
// (186067)
|
||||
if (fi.isDir()) {
|
||||
|
|
@ -1038,9 +1050,20 @@ static QByteArray searchIncludePaths(const QList<Parser::IncludePath> &includepa
|
|||
}
|
||||
}
|
||||
|
||||
if (!fi.exists() || fi.isDir())
|
||||
if (!fi.exists() || fi.isDir()) {
|
||||
if (Q_UNLIKELY(debugIncludes)) {
|
||||
fprintf(stderr, "debug-includes: can't find '%s'\n", include.constData());
|
||||
}
|
||||
return QByteArray();
|
||||
return fi.canonicalFilePath().toLocal8Bit();
|
||||
}
|
||||
|
||||
const auto result = fi.canonicalFilePath().toLocal8Bit();
|
||||
|
||||
if (Q_UNLIKELY(debugIncludes)) {
|
||||
fprintf(stderr, "debug-includes: found '%s'\n", result.constData());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo)
|
||||
|
|
@ -1054,7 +1077,11 @@ QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteAr
|
|||
|
||||
auto it = nonlocalIncludePathResolutionCache.find(include);
|
||||
if (it == nonlocalIncludePathResolutionCache.end())
|
||||
it = nonlocalIncludePathResolutionCache.insert(include, searchIncludePaths(includes, include));
|
||||
it = nonlocalIncludePathResolutionCache.insert(include,
|
||||
searchIncludePaths(
|
||||
includes,
|
||||
include,
|
||||
debugIncludes));
|
||||
return it.value();
|
||||
}
|
||||
|
||||
|
|
@ -1319,4 +1346,10 @@ void Preprocessor::until(Token t)
|
|||
;
|
||||
}
|
||||
|
||||
void Preprocessor::setDebugIncludes(bool value)
|
||||
{
|
||||
debugIncludes = value;
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -81,10 +81,13 @@ public:
|
|||
enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude, PrepareDefine, TokenizeDefine };
|
||||
static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp);
|
||||
|
||||
void setDebugIncludes(bool value);
|
||||
|
||||
private:
|
||||
void until(Token);
|
||||
|
||||
void preprocess(const QByteArray &filename, Symbols &preprocessed);
|
||||
bool debugIncludes = false;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
Loading…
Reference in New Issue