5858#include < QDir>
5959#include < QFileInfo>
6060#include < QFile>
61+ #include < QLibraryInfo>
6162#include < QTextStream>
6263#include < QRegularExpression>
6364
@@ -67,67 +68,85 @@ 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+ }
83+ #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
84+ QString qEnvironmentVariable (const char *varName){
85+ return QString::fromLocal8Bit (qgetenv (varName));
86+ }
87+ #endif
7088
7189 QStringList getIncludeDirectories (const QString &commandLineIncludes)
7290 {
7391 QStringList includes;
74- includes << QString (" ." );
92+ includes << QStringLiteral (" ." );
7593
76- QChar pathSplitter = QDir::listSeparator ();
94+ const QChar pathSplitter = QDir::listSeparator ();
7795
78- // Environment PYTHONQT_INCLUDE
79- QString includePath = getenv (" PYTHONQT_INCLUDE" );
80- if (!includePath.isEmpty ())
81- includes += includePath.split (pathSplitter, Qt::SkipEmptyParts);
82-
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);
96+ // From env var PYTHONQT_INCLUDE
97+ const QString envInclude = qEnvironmentVariable (" PYTHONQT_INCLUDE" );
98+ if (!envInclude.isEmpty ()) {
99+ QStringList envIncludes = envInclude.split (pathSplitter, Qt::SkipEmptyParts);
100+ for (const QString& include: qAsConst (envIncludes)) {
101+ if (isDir (include)) {
102+ includes << include;
103+ }
104+ else {
105+ qWarning () << " Include path" << include << " does not exist, ignoring." ;
106+ }
92107 }
93- else
94- {
95- ++it;
108+ }
109+
110+ // CLI-provided include paths
111+ if (!commandLineIncludes.isEmpty ()) {
112+ const QStringList cliIncludes = commandLineIncludes.split (QDir::listSeparator (), Qt::SkipEmptyParts);
113+ for (const QString& include : cliIncludes) {
114+ if (isDir (include)) {
115+ includes << QDir::cleanPath (include);
116+ }
117+ else {
118+ qWarning () << " Include path" << include << " does not exist, ignoring." ;
119+ }
96120 }
97121 }
98122
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
123+ // Prefer QLibraryInfo (works without QTDIR)
124+ QString qtInclude = QLibraryInfo::location (QLibraryInfo::HeadersPath);
125+ if (!isDir (qtInclude)) {
126+ // Fallback to QTDIR/include
127+ const QString qtDir = qEnvironmentVariable (" QTDIR" );
128+ if (qtDir.isEmpty () || !isDir (qtDir)) {
129+ const QString reason = QStringLiteral (" The QTDIR environment variable " )
130+ + (qtDir.isEmpty ()
131+ ? " is not set."
132+ : " points to a non-existing directory." );
133+ qWarning () << reason << " This may cause problems with finding the necessary include files." ;
134+ } else {
135+ qtInclude = joinPath (qtDir, QStringLiteral (" include" ));
136+ }
117137 }
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;
138+ if (!qtInclude.isEmpty () && isDir (qtInclude)) {
139+ qInfo () << " Using Qt headers at:" << qtInclude;
140+ // Check for <qtInclude>/<Module>
141+ for (const auto & qtModule : std::as_const (candidatesQtModules)) {
142+ const QString qtModuleInclude = joinPath (qtInclude, qtModule);
143+ if (isDir (qtModuleInclude)) {
144+ includes << qtModuleInclude;
145+ }
146+ }
147+ includes << qtInclude;
130148 }
149+
131150 return includes;
132151 }
133152
@@ -136,8 +155,8 @@ namespace
136155 {
137156 simplecpp::DUI dui; // settings
138157
139- for (QString include : includePaths) {
140- dui.includePaths . push_back (QDir::toNativeSeparators (include).toStdString ());
158+ for (const QString& include : includePaths) {
159+ dui.addIncludePath (QDir::toNativeSeparators (include).toStdString ());
141160 }
142161 dui.defines .push_back (" __cplusplus=1" );
143162 dui.defines .push_back (" __STDC__" );
0 commit comments