QtBase  v6.3.1
qmakeevaluator.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the qmake application of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #ifndef QMAKEEVALUATOR_H
30 #define QMAKEEVALUATOR_H
31 
32 #if defined(PROEVALUATOR_FULL) && defined(PROEVALUATOR_THREAD_SAFE)
33 # error PROEVALUATOR_FULL is incompatible with PROEVALUATOR_THREAD_SAFE due to cache() implementation
34 #endif
35 
36 #include "qmakeparser.h"
37 #include "qmakevfs.h"
38 #include "ioutils.h"
39 
40 #include <qlist.h>
41 #include <qmap.h>
42 #include <qset.h>
43 #include <qstack.h>
44 #include <qstring.h>
45 #include <qstringlist.h>
46 #include <qshareddata.h>
47 #if QT_CONFIG(process)
48 # include <qprocess.h>
49 #else
50 # include <qiodevice.h>
51 #endif
52 #ifdef PROEVALUATOR_THREAD_SAFE
53 # include <qmutex.h>
54 #endif
55 
56 #include <list>
57 
59 
60 class QMakeGlobals;
61 
63 {
64 public:
65  enum {
66  SourceEvaluator = 0x10,
67 
68  CumulativeEvalMessage = 0x1000,
69 
70  EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage,
71  EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated,
72 
73  EvalError = ErrorMessage | SourceEvaluator
74  };
75 
76  // error(), warning() and message() from .pro file
77  virtual void fileMessage(int type, const QString &msg) = 0;
78 
79  enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile };
80  virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type) = 0;
81  virtual void doneWithEval(ProFile *parent) = 0;
82 };
83 
86 
88 {
89 public:
90  QMakeFeatureRoots(const QStringList &_paths) : paths(_paths) {}
93 #ifdef PROEVALUATOR_THREAD_SAFE
94  mutable QMutex mutex;
95 #endif
96 };
97 
98 // We use a list-based stack instead of a vector-based one, so that
99 // the addresses of value maps stay constant. The qmake generators rely on that.
100 class QMAKE_EXPORT ProValueMapStack : public std::list<ProValueMap>
101 {
102 public:
103  inline void push(const ProValueMap &t) { push_back(t); }
104  inline ProValueMap pop() { auto r = std::move(back()); pop_back(); return r; }
105  ProValueMap &top() { return back(); }
106  const ProValueMap &top() const { return back(); }
107 };
108 
109 namespace QMakeInternal { struct QMakeBuiltin; }
110 
112 {
113 public:
114  enum LoadFlag {
115  LoadProOnly = 0,
116  LoadPreFiles = 1,
117  LoadPostFiles = 2,
118  LoadAll = LoadPreFiles|LoadPostFiles,
119  LoadSilent = 0x10,
120  LoadHidden = 0x20
121  };
122  Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
123 
124  static void initStatics();
125  static void initFunctionStatics();
127  QMakeHandler *handler);
128  ~QMakeEvaluator();
129 
130  void setExtraVars(const ProValueMap &extraVars) { m_extraVars = extraVars; }
131  void setExtraConfigs(const ProStringList &extraConfigs) { m_extraConfigs = extraConfigs; }
132  void setOutputDir(const QString &outputDir) { m_outputDir = outputDir; }
133 
134  ProStringList values(const ProKey &variableName) const;
135  ProStringList &valuesRef(const ProKey &variableName);
136  ProString first(const ProKey &variableName) const;
137  ProString propertyValue(const ProKey &val) const;
138 
139  ProString dirSep() const { return m_dirSep; }
140  bool isHostBuild() const { return m_hostBuild; }
141 
142  enum VisitReturn {
148  ReturnReturn
149  };
150 
152  { return b ? ReturnTrue : ReturnFalse; }
153 
154  static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
155  VisitReturn evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
156  static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
157  static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
158  void skipExpression(const ushort *&tokPtr);
159 
160  void loadDefaults();
161  bool prepareProject(const QString &inDir);
162  bool loadSpecInternal();
163  bool loadSpec();
164  void initFrom(const QMakeEvaluator *other);
165  void setupProject();
166  void evaluateCommand(const QString &cmds, const QString &where);
167  void applyExtraConfigs();
168  VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type,
169  LoadFlags flags);
170  VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
171  VisitReturn visitProBlock(const ushort *tokPtr);
172  VisitReturn visitProLoop(const ProKey &variable, const ushort *exprPtr,
173  const ushort *tokPtr);
174  void visitProFunctionDef(ushort tok, const ProKey &name, const ushort *tokPtr);
175  VisitReturn visitProVariable(ushort tok, const ProStringList &curr, const ushort *&tokPtr);
176 
177  ALWAYS_INLINE const ProKey &map(const ProString &var) { return map(var.toKey()); }
178  const ProKey &map(const ProKey &var);
179  ProValueMap *findValues(const ProKey &variableName, ProValueMap::Iterator *it);
180 
181  void setTemplate();
182 
183  ProStringList split_value_list(QStringView vals, int source = 0);
184  VisitReturn expandVariableReferences(const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined);
185 
186  QString currentFileName() const;
187  QString currentDirectory() const;
188  ProFile *currentProFile() const;
189  int currentFileId() const;
191  { return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
192  QString filePathArg0(const ProStringList &args);
193  QString filePathEnvArg0(const ProStringList &args);
194 
195  VisitReturn evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
196  LoadFlags flags);
197  VisitReturn evaluateFileChecked(const QString &fileName, QMakeHandler::EvalFileType type,
198  LoadFlags flags);
199  VisitReturn evaluateFeatureFile(const QString &fileName, bool silent = false);
200  VisitReturn evaluateFileInto(const QString &fileName,
201  ProValueMap *values, // output-only
202  LoadFlags flags);
203  VisitReturn evaluateConfigFeatures();
204  void message(int type, const QString &msg) const;
205  void evalError(const QString &msg) const
207  void languageWarning(const QString &msg) const
209  void deprecationWarning(const QString &msg) const
211 
212  VisitReturn prepareFunctionArgs(const ushort *&tokPtr, QList<ProStringList> *ret);
213  VisitReturn evaluateFunction(const ProFunctionDef &func,
214  const QList<ProStringList> &argumentsList, ProStringList *ret);
215  VisitReturn evaluateBoolFunction(const ProFunctionDef &func,
216  const QList<ProStringList> &argumentsList,
217  const ProString &function);
218 
219  VisitReturn evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr, ProStringList *ret);
220  VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr);
221 
222  VisitReturn evaluateBuiltinExpand(const QMakeInternal::QMakeBuiltin &adef,
223  const ProKey &function, const ProStringList &args, ProStringList &ret);
224  VisitReturn evaluateBuiltinConditional(const QMakeInternal::QMakeBuiltin &adef,
225  const ProKey &function, const ProStringList &args);
226 
227  VisitReturn evaluateConditional(QStringView cond, const QString &where, int line = -1);
228 #ifdef PROEVALUATOR_FULL
229  VisitReturn checkRequirements(const ProStringList &deps);
230 #endif
231 
232  void updateMkspecPaths();
233  void updateFeaturePaths();
234 
235  bool isActiveConfig(QStringView config, bool regex = false);
236 
237  void populateDeps(
238  const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
239  const ProString &priosfx,
240  QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
241  QMultiMap<int, ProString> &rootSet) const;
242 
243  bool getMemberArgs(const ProKey &name, int srclen, const ProStringList &args,
244  int *start, int *end);
245  VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value);
246 
247  VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
248  QMakeVfs::VfsFlags flags, const QString &contents);
249 #if QT_CONFIG(process)
250  void runProcess(QProcess *proc, const QString &command) const;
251 #endif
252  QByteArray getCommandOutput(const QString &args, int *exitCode) const;
253 
254 private:
255  // Implementation detail of evaluateBuiltinConditional():
256  VisitReturn testFunc_cache(const ProStringList &args);
257 
258 public:
260 #ifdef PROEVALUATOR_CUMULATIVE
261  bool m_cumulative;
262  int m_skipLevel;
263 #else
264  enum { m_cumulative = 0 };
265  enum { m_skipLevel = 0 };
266 #endif
267 
268  static QString quoteValue(const ProString &val);
269 
270 #ifdef PROEVALUATOR_DEBUG
271  void debugMsgInternal(int level, const char *fmt, ...) const;
272  void traceMsgInternal(const char *fmt, ...) const;
273  static QString formatValue(const ProString &val, bool forceQuote = false);
274  static QString formatValueList(const ProStringList &vals, bool commas = false);
275  static QString formatValueListList(const QList<ProStringList> &vals);
276 
277  const int m_debugLevel;
278 #else
279  ALWAYS_INLINE void debugMsgInternal(int, const char *, ...) const {}
280  ALWAYS_INLINE void traceMsgInternal(const char *, ...) const {}
281 
282  enum { m_debugLevel = 0 };
283 #endif
284 
285  struct Location {
286  Location() : pro(nullptr), line(0) {}
287  Location(ProFile *_pro, ushort _line) : pro(_pro), line(_line) {}
288  void clear() { pro = nullptr; line = 0; }
291  };
292 
293  Location m_current; // Currently evaluated location
294  QStack<Location> m_locationStack; // All execution location changes
296 
300 
302  int m_toggle;
320  ProValueMapStack m_valuemapStack; // VariableName must be us-ascii, the content however can be non-us-ascii.
321  QString m_tmp1, m_tmp2, m_tmp3, m_tmp[2]; // Temporaries for efficient toQString
322 
327 };
329 
330 Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
331 
333 
334 #endif // QMAKEEVALUATOR_H
const char msg[]
Definition: arch.cpp:46
ProValueMap & top()
ProValueMap pop()
void push(const ProValueMap &t)
const ProValueMap & top() const
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
Definition: qlist.h:108
QStringList m_mkspecPaths
QString resolvePath(const QString &fileName) const
ProFunctionDefs m_functionDefs
QMakeHandler * m_handler
QStringList m_qmakefeatures
ProValueMap m_extraVars
static ALWAYS_INLINE VisitReturn returnBool(bool b)
QStack< ProFile * > m_profileStack
QString m_qmakespecName
ALWAYS_INLINE const ProKey & map(const ProString &var)
QMakeParser * m_parser
QExplicitlySharedDataPointer< QMakeFeatureRoots > m_featureRoots
QMakeGlobals * m_option
QString m_sourceRoot
QMakeVfs * m_vfs
QStack< Location > m_locationStack
void languageWarning(const QString &msg) const
ProStringList m_returnValue
ProStringList m_extraConfigs
ProString m_dirSep
ALWAYS_INLINE void traceMsgInternal(const char *,...) const
void setExtraConfigs(const ProStringList &extraConfigs)
QStringList m_qmakepath
Location m_current
ALWAYS_INLINE void debugMsgInternal(int, const char *,...) const
ProString dirSep() const
void setOutputDir(const QString &outputDir)
void setExtraVars(const ProValueMap &extraVars)
void evalError(const QString &msg) const
ProValueMapStack m_valuemapStack
void deprecationWarning(const QString &msg) const
QMakeEvaluator * m_caller
bool isHostBuild() const
const QStringList paths
QMakeFeatureRoots(const QStringList &_paths)
QMakeFeatureHash cache
virtual void fileMessage(int type, const QString &msg)=0
virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type)=0
virtual void doneWithEval(ProFile *parent)=0
static QString resolvePath(const QString &baseDir, const QString &fileName)
Definition: ioutils.cpp:138
virtual void message(int type, const QString &msg, const QString &fileName=QString(), int lineNo=0)=0
The QMutex class provides access serialization between threads.
Definition: qmutex.h:285
Definition: qset.h:54
The QSharedData class is a base class for shared data objects. \reentrant.
Definition: qshareddata.h:55
The QStack class is a template class that provides a stack.
Definition: qstack.h:49
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QStringList class provides a list of strings.
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
QMap< QString, QString > map
[6]
opt initFrom(q)
[0]
parser
Definition: devices.py:74
@ ErrorMessage
std::pair< T1, T2 > QPair
Definition: qcontainerfwd.h:56
EGLOutputLayerEXT EGLint EGLAttrib value
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition: qflags.h:210
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition: qflags.h:227
unsigned int uint
Definition: qglobal.h:334
unsigned short ushort
Definition: qglobal.h:333
#define ALWAYS_INLINE
Definition: qmake_global.h:51
#define QMAKE_EXPORT
Definition: qmake_global.h:41
QPair< QString, QString > QMakeFeatureKey
Q_DECLARE_TYPEINFO(QMakeEvaluator::Location, Q_PRIMITIVE_TYPE)
QHash< QMakeFeatureKey, QString > QMakeFeatureHash
GLenum type
Definition: qopengl.h:270
GLenum GLsizei GLsizei GLint * values
[16]
GLboolean GLboolean GLboolean b
GLenum mode
GLenum GLuint GLint level
GLboolean r
[2]
GLuint GLuint end
GLsizei const GLuint * paths
GLbitfield flags
GLuint start
GLuint name
GLint first
GLsizei GLsizei GLchar * source
GLenum func
Definition: qopenglext.h:663
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint GLenum option
Definition: qopenglext.h:5929
GLenum GLenum variable
Definition: qopenglext.h:10816
@ Q_PRIMITIVE_TYPE
Definition: qtypeinfo.h:155
bool runProcess(const QString &binary, const QStringList &args, const QString &workingDirectory, unsigned long *exitCode, QByteArray *stdOut, QByteArray *stdErr, QString *errorMessage)
Definition: utils.cpp:346
QObject::connect nullptr
void writeFile(QCborStreamWriter &writer, const QString &fileName)
[6]
QSharedPointer< T > other(t)
[5]
QStringList::Iterator it
QStringList list
[0]
Location(ProFile *_pro, ushort _line)
QWaitCondition cond
int fn(int &i)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent
QMutex mutex