Skip to content

Commit a0b2965

Browse files
committed
Fixed: When generating wrappers for non-Qt code, includes lost their directories
The preprocessed file only contains absolute paths, so we have to reconstruct the relative path to be able to emit the correct includes.
1 parent 63b168c commit a0b2965

File tree

6 files changed

+68
-22
lines changed

6 files changed

+68
-22
lines changed

generator/abstractmetabuilder.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#endif
6060
#include <QtCore/QTextStream>
6161
#include <QtCore/QVariant>
62+
#include <QtCore/QDir>
6263

6364
static QString strip_template_args(const QString &name)
6465
{
@@ -413,6 +414,39 @@ AbstractMetaClass* AbstractMetaBuilder::getGlobalNamespace(const TypeEntry* type
413414
return global;
414415
}
415416

417+
Include AbstractMetaBuilder::getRelativeInclude(const QString& path)
418+
{
419+
QString bestRelativePath;
420+
int bestNumDirectories = 0;
421+
// find the shortest relative path relative to all given include directories
422+
for (QString includePath : m_include_paths) {
423+
QDir includeDir(includePath);
424+
QString relativePath = includeDir.relativeFilePath(path);
425+
QFileInfo info(relativePath);
426+
if (!info.isRelative()) {
427+
// not relative - different drives?
428+
continue;
429+
}
430+
int numDirectories = relativePath.count('/');
431+
if (bestRelativePath.isEmpty() || numDirectories < bestNumDirectories) {
432+
bestRelativePath = relativePath;
433+
bestNumDirectories = numDirectories;
434+
if (numDirectories == 0) {
435+
// optimal relative path
436+
break;
437+
}
438+
}
439+
}
440+
if (bestRelativePath.isEmpty()) {
441+
// This shouldn't happen
442+
QFileInfo info(path);
443+
return Include(Include::IncludePath, info.fileName());
444+
}
445+
else {
446+
return Include(Include::IncludePath, bestRelativePath);
447+
}
448+
}
449+
416450
bool AbstractMetaBuilder::build()
417451
{
418452
Q_ASSERT(!m_file_name.isEmpty());
@@ -756,13 +790,11 @@ AbstractMetaClass *AbstractMetaBuilder::traverseNamespace(NamespaceModelItem nam
756790
m_namespace_prefix = currentScope()->qualifiedName().join("::");
757791

758792
if (!type->include().isValid()) {
759-
QFileInfo info(namespace_item->fileName());
760-
type->setInclude(Include(Include::IncludePath, info.fileName()));
793+
type->setInclude(getRelativeInclude(namespace_item->fileName()));
761794
}
762795
// namespace items might come from different include files:
763796
for (const QString& oneIncludeFile : includeFiles) {
764-
QFileInfo info(oneIncludeFile);
765-
type->addExtraInclude(Include(Include::IncludePath, info.fileName()));
797+
type->addExtraInclude(getRelativeInclude(oneIncludeFile));
766798
}
767799

768800
return meta_class;
@@ -837,8 +869,7 @@ AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, Abs
837869
m_enum_values[meta_enum_value->name()] = meta_enum_value;
838870
}
839871

840-
QFileInfo info(enum_item->fileName());
841-
meta_enum->typeEntry()->setInclude(Include(Include::IncludePath, info.fileName()));
872+
meta_enum->typeEntry()->setInclude(getRelativeInclude(enum_item->fileName()));
842873

843874
m_enums << meta_enum;
844875

@@ -872,8 +903,7 @@ AbstractMetaClass *AbstractMetaBuilder::traverseTypeAlias(TypeAliasModelItem typ
872903

873904
// Set the default include file name
874905
if (!type->include().isValid()) {
875-
QFileInfo info(typeAlias->fileName());
876-
type->setInclude(Include(Include::IncludePath, info.fileName()));
906+
type->setInclude(getRelativeInclude(typeAlias->fileName()));
877907
}
878908

879909
return meta_class;
@@ -986,8 +1016,7 @@ AbstractMetaClass *AbstractMetaBuilder::traverseClass(ClassModelItem class_item)
9861016
// Set the default include file name. In case we saw an template instance earlier,
9871017
// overwrite the include file when we see the actual declaration.
9881018
if (!type->include().isValid() || class_item->hasActualDeclaration()) {
989-
QFileInfo info(class_item->fileName());
990-
type->setInclude(Include(Include::IncludePath, info.fileName()));
1019+
type->setInclude(getRelativeInclude(class_item->fileName()));
9911020
}
9921021

9931022
return meta_class;

generator/abstractmetabuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class AbstractMetaBuilder
7878
QString fileName() const { return m_file_name; }
7979
void setFileName(const QString &fileName) { m_file_name = fileName; }
8080

81+
//! Set list of include directories. This will be used to make absolute include paths relative.
82+
void setIncludePaths(const QStringList& includePaths) { m_include_paths = includePaths; }
83+
8184
void dumpLog();
8285

8386
bool build();
@@ -153,7 +156,11 @@ class AbstractMetaBuilder
153156

154157
AbstractMetaClass* getGlobalNamespace(const TypeEntry* typeEntry);
155158

159+
// turn absolute file path into a relative include
160+
Include getRelativeInclude(const QString& path);
161+
156162
QString m_file_name;
163+
QStringList m_include_paths;
157164

158165
AbstractMetaClassList m_meta_classes;
159166
QHash<QString,AbstractMetaClass*> m_templates;

generator/generatorset.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class GeneratorSet : public QObject
5858
virtual bool readParameters(const QMap<QString, QString> args) = 0;
5959
virtual void buildModel(const QString pp_file) = 0;
6060
virtual void dumpObjectTree() = 0;
61+
virtual void setIncludePaths(const QStringList& includePaths) = 0;
6162
virtual QString generate() = 0;
6263

6364
static GeneratorSet *getInstance();

generator/generatorsetqtscript.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ void GeneratorSetQtScript::dumpObjectTree() {
8585

8686
}
8787

88+
void GeneratorSetQtScript::setIncludePaths(const QStringList& includePaths)
89+
{
90+
builder.setIncludePaths(includePaths);
91+
}
92+
8893
QString GeneratorSetQtScript::generate() {
8994
AbstractMetaClassList classes = builder.classesTopologicalSorted();
9095
QSet<QString> declaredTypeNames = builder.qtMetaTypeDeclaredTypeNames();

generator/generatorsetqtscript.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ class GeneratorSetQtScript : public GeneratorSet
5252
public:
5353
GeneratorSetQtScript();
5454

55-
QString usage();
56-
bool readParameters(const QMap<QString, QString> args);
55+
QString usage() override;
56+
bool readParameters(const QMap<QString, QString> args) override;
5757

58-
void buildModel(const QString pp_file);
59-
void dumpObjectTree();
58+
void buildModel(const QString pp_file) override;
59+
void dumpObjectTree() override;
60+
void setIncludePaths(const QStringList& includePaths) override;
6061

61-
QString generate( );
62+
QString generate() override;
6263

6364
private:
6465
MetaQtScriptBuilder builder;

generator/main.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ namespace
127127
}
128128

129129
bool
130-
preprocess(const QString& sourceFile, const QString& targetFile, const QString& commandLineIncludes = QString())
130+
preprocess(const QString& sourceFile, const QString& targetFile, const QStringList& includePaths)
131131
{
132132
simplecpp::DUI dui; // settings
133133

134-
for(QString include : getIncludeDirectories(commandLineIncludes)) {
134+
for(QString include : includePaths) {
135135
dui.includePaths.push_back(QDir::toNativeSeparators(include).toStdString());
136136
}
137137
dui.defines.push_back("__cplusplus=1");
@@ -212,10 +212,10 @@ namespace
212212
return true;
213213
}
214214

215-
unsigned int getQtVersion(const QString &commandLineIncludes)
215+
unsigned int getQtVersion(const QStringList& includePaths)
216216
{
217217
QRegularExpression re("#define\\s+QTCORE_VERSION\\s+0x([0-9a-f]+)", QRegularExpression::CaseInsensitiveOption);
218-
for (const QString &includeDir: getIncludeDirectories(commandLineIncludes))
218+
for (const QString &includeDir: includePaths)
219219
{
220220
QFileInfo fi(QDir(includeDir), "qtcoreversion.h");
221221
if (fi.exists())
@@ -244,7 +244,7 @@ namespace
244244
}
245245
}
246246
printf("Error: Could not find Qt version (looked for qtcoreversion.h in %s)\n",
247-
qPrintable(commandLineIncludes));
247+
qPrintable(includePaths.join(QDir::listSeparator())));
248248
return 0;
249249
}
250250
};
@@ -348,9 +348,10 @@ int main(int argc, char *argv[])
348348

349349
printf("Please wait while source files are being generated...\n");
350350

351+
QStringList includePaths = getIncludeDirectories(args.value("include-paths"));
351352
if (!qtVersion) {
352353
printf("Trying to determine Qt version...\n");
353-
qtVersion = getQtVersion(args.value("include-paths"));
354+
qtVersion = getQtVersion(includePaths);
354355
if (!qtVersion)
355356
{
356357
fprintf(stderr, "Aborting\n"); // the error message was printed by getQtVersion
@@ -372,7 +373,8 @@ int main(int argc, char *argv[])
372373
printf("PreProcessing - Generate [%s] using [%s] and include-paths [%s]\n",
373374
qPrintable(pp_file), qPrintable(fileName), qPrintable(args.value("include-paths")));
374375
ReportHandler::setContext("Preprocess");
375-
if (!preprocess(fileName, pp_file, args.value("include-paths"))) {
376+
377+
if (!preprocess(fileName, pp_file, includePaths)) {
376378
fprintf(stderr, "Preprocessor failed on file: '%s'\n", qPrintable(fileName));
377379
return 1;
378380
}
@@ -387,6 +389,7 @@ int main(int argc, char *argv[])
387389

388390
printf("Building model using [%s]\n", qPrintable(pp_file));
389391
ReportHandler::setContext("Build");
392+
gs->setIncludePaths(includePaths);
390393
gs->buildModel(pp_file);
391394
if (args.contains("dump-object-tree")) {
392395
gs->dumpObjectTree();

0 commit comments

Comments
 (0)