5858#include < QDir>
5959#include < QFileInfo>
6060#include < QFile>
61+ #include < QLibraryInfo>
6162#include < QTextStream>
6263#include < QRegularExpression>
6364
@@ -67,67 +68,80 @@ void displayHelp(GeneratorSet *generatorSet);
6768
6869namespace
6970{
71+ static const QStringList candidatesQtModules {
72+ QStringLiteral (" QtCore" ),
73+ QStringLiteral (" QtGui" ),
74+ QStringLiteral (" QtNetwork" ),
75+ QStringLiteral (" QtOpenGL" ),
76+ QStringLiteral (" QtXml" ),
77+ };
78+
79+ static bool isDir (const QString& p) { return QFileInfo (p).isDir (); }
80+ static QString joinPath (const QString& base, const QString& child) {
81+ return QDir (base).filePath (child);
82+ }
7083
7184 QStringList getIncludeDirectories (const QString &commandLineIncludes)
7285 {
7386 QStringList includes;
74- includes << QString (" ." );
75-
76- QChar pathSplitter = QDir::listSeparator ();
87+ includes << QStringLiteral (" ." );
7788
78- // Environment PYTHONQT_INCLUDE
79- QString includePath = getenv (" PYTHONQT_INCLUDE" );
80- if (!includePath.isEmpty ())
81- includes += includePath.split (pathSplitter, Qt::SkipEmptyParts);
89+ const QChar pathSplitter = QDir::listSeparator ();
8290
83- // Includes from the command line
84- if (!commandLineIncludes.isEmpty ())
85- includes += commandLineIncludes.split (pathSplitter, Qt::SkipEmptyParts);
86- for (auto it = includes.begin (); it != includes.end ();)
87- {
88- if (!QDir (*it).exists ())
89- {
90- qWarning () << " Include path " << it->toUtf8 () << " does not exist, ignoring it." ;
91- it = includes.erase (it);
91+ // From env var PYTHONQT_INCLUDE
92+ const QString envInclude = qEnvironmentVariable (" PYTHONQT_INCLUDE" );
93+ if (!envInclude.isEmpty ()) {
94+ QStringList envIncludes = envInclude.split (pathSplitter, Qt::SkipEmptyParts);
95+ for (const QString& include: qAsConst (envIncludes)) {
96+ if (isDir (include)) {
97+ includes << include;
98+ }
99+ else {
100+ qWarning () << " Include path" << include << " does not exist, ignoring." ;
101+ }
92102 }
93- else
94- {
95- ++it;
103+ }
104+
105+ // CLI-provided include paths
106+ if (!commandLineIncludes.isEmpty ()) {
107+ const QStringList cliIncludes = commandLineIncludes.split (QDir::listSeparator (), Qt::SkipEmptyParts);
108+ for (const QString& include : cliIncludes) {
109+ if (isDir (include)) {
110+ includes << QDir::cleanPath (include);
111+ }
112+ else {
113+ qWarning () << " Include path" << include << " does not exist, ignoring." ;
114+ }
96115 }
97116 }
98117
99- // Include Qt
100- QString qtdir = getenv (" QTDIR" );
101- if (qtdir.isEmpty () || !QDir (qtdir).exists (qtdir))
102- {
103- QString reason = " The QTDIR environment variable " + qtdir.isEmpty () ?
104- " is not set. " : " points to a non-existing directory. " ;
105- #if defined(Q_OS_MAC)
106- qWarning () << reason << " Assuming standard binary install using frameworks." ;
107- QString frameworkDir = " /Library/Frameworks" ;
108- includes << (frameworkDir + " /QtXml.framework/Headers" );
109- includes << (frameworkDir + " /QtNetwork.framework/Headers" );
110- includes << (frameworkDir + " /QtCore.framework/Headers" );
111- includes << (frameworkDir + " /QtGui.framework/Headers" );
112- includes << (frameworkDir + " /QtOpenGL.framework/Headers" );
113- includes << frameworkDir;
114- #else
115- qWarning () << reason << " This may cause problems with finding the necessary include files." ;
116- #endif
118+ // Prefer QLibraryInfo (works without QTDIR)
119+ QString qtInclude = QLibraryInfo::location (QLibraryInfo::HeadersPath);
120+ if (!isDir (qtInclude)) {
121+ // Fallback to QTDIR/include
122+ const QString qtDir = qEnvironmentVariable (" QTDIR" );
123+ if (qtDir.isEmpty () || !isDir (qtDir)) {
124+ const QString reason = QStringLiteral (" The QTDIR environment variable " )
125+ + (qtDir.isEmpty ()
126+ ? " is not set."
127+ : " points to a non-existing directory." );
128+ qWarning () << reason << " This may cause problems with finding the necessary include files." ;
129+ } else {
130+ qtInclude = joinPath (qtDir, QStringLiteral (" include" ));
131+ }
117132 }
118- else
119- {
120- std::cout << " -------------------------------------------------------------" << std::endl;
121- std::cout << " Using QT at: " << qtdir.toLocal8Bit ().constData () << std::endl;
122- std::cout << " -------------------------------------------------------------" << std::endl;
123- qtdir += " /include" ;
124- includes << (qtdir + " /QtXml" );
125- includes << (qtdir + " /QtNetwork" );
126- includes << (qtdir + " /QtCore" );
127- includes << (qtdir + " /QtGui" );
128- includes << (qtdir + " /QtOpenGL" );
129- includes << qtdir;
133+ if (!qtInclude.isEmpty () && isDir (qtInclude)) {
134+ qInfo () << " Using Qt headers at:" << qtInclude;
135+ // Check for <qtInclude>/<Module>
136+ for (const auto & qtModule : std::as_const (candidatesQtModules)) {
137+ const QString qtModuleInclude = joinPath (qtInclude, qtModule);
138+ if (isDir (qtModuleInclude)) {
139+ includes << qtModuleInclude;
140+ }
141+ }
142+ includes << qtInclude;
130143 }
144+
131145 return includes;
132146 }
133147
@@ -136,8 +150,8 @@ namespace
136150 {
137151 simplecpp::DUI dui; // settings
138152
139- for (QString include : includePaths) {
140- dui.includePaths . push_back (QDir::toNativeSeparators (include).toStdString ());
153+ for (const QString& include : includePaths) {
154+ dui.addIncludePath (QDir::toNativeSeparators (include).toStdString ());
141155 }
142156 dui.defines .push_back (" __cplusplus=1" );
143157 dui.defines .push_back (" __STDC__" );
0 commit comments