1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
\chapter qmake's Advanced Concepts
\section1 qmake's Advanced Concepts
The \e qmake project files we've seen up to now have been very simple,
just a list of \e{name = value} and \e{name += value} lines. \e qmake
provides a lot more power, for example you can use a single project
file to produce makefiles for multiple platforms.
\section1 Operators
So far, you have seen the \e = operator and \e += operator being used
in a project file. There are more operators available for use; but
some of these should be used carefully as they may change more than
you expect them to.
\section2 The '=' operator
This operator simply assigns a value to a variable, it is used like
this:
\code
TARGET = myapp
\endcode
This sets the TARGET variable to \e myapp. This will remove any
previously set TARGET.
\section2 The '+=' operator
This operator appends a value to the list of values in a variable. It
is used like this:
\code
DEFINES += QT_DLL
\endcode
This appends QT_DLL to the list of pre-processor defines to be put in the
makefile.
\section2 The '-=' operator
This operator removes a value from the list of values in a variable.
It is used like this:
\code
DEFINES -= QT_DLL
\endcode
This removes QT_DLL from the list of pre-processor defines to be put
in the makefile.
\section2 The '*=' operator
This operator only adds a value to the list of values in a variable if
it doesn't already exist. It is used like this:
\code
DEFINES *= QT_DLL
\endcode
QT_DLL will only be added to the list of pre-processor defines if it
is not already defined.
\section2 The '~=' operator
This operator replaces any values that match the regexp with the
specified value. It is used like this:
\code
DEFINES ~= s/QT_[DT].+/QT
\endcode
This removes any values in the list that start with QT_D or QT_T with
QT.
\section1 Scopes
A scope are similar to 'if' statements, if a certain condition is
true, the settings inside the scope are processed. A scope is written
like this:
\code
win32 {
DEFINES += QT_DLL
}
\endcode
The above code will add the QT_DLL define to the makefile if \e qmake
is used on a Windows platform. If \e qmake is used on a different
platform than Windows, the define will be ignored. You may also perform
single line conditionals/assignments with qmake like this:
\code
win32:DEFINES += QT_DLL
\endcode
For example, suppose we want to process something on all platforms
\e except for Windows. We can achieve this by negating the scope like
this:
\code
!win32 {
DEFINES += QT_DLL
}
\endcode
Any entry on the CONFIG line is also a scope. For example, if you
write this:
\code
CONFIG += warn_on
\endcode
you will have a scope called 'warn_on'. This makes it easy to change
the configuration for a project without losing all the custom settings
that might be needed for a specific configuration. Since it is
possible to put your own values on the CONFIG line, this provides you
with a very powerful configuration tool for your makefiles. For
example:
\code
CONFIG += qt warn_on debug
debug {
TARGET = myappdebug
}
release {
TARGET = myapp
}
\endcode
In the above code, two scopes are created which depend on what
is put on the CONFIG line. In the example, \e debug is on the config
line, so the TARGET variable is set to \e myappdebug. If \e release
was on the config line, then the TARGET variable would be set to \e
myapp.
It is also possible to check for two things before processing some
settings. For instance, if you want to check if the platform is
Windows and that the thread configuration is set, you would write
this:
\code
win32 {
thread {
DEFINES += ENABLE_THREAD_SUPPORT
}
}
\endcode
To save writing many nested scopes, you can nest scopes using a colon
like this:
\code
win32:thread {
DEFINES += ENABLE_THREAD_SUPPORT
}
\endcode
Once a test has been performed you may also do else/elseif operations. With
this you may easily write complicated tests. This can be done with the
special 'else' scope, it can be combined with other scopes (separated by
colons as above) for example:
\code
win32:thread {
DEFINES += ENABLE_THREAD_SUPPORT
} else:debug {
DEFINES += NOTHREAD_DEBUG
} else {
message("Unknown configuration")
}
\endcode
\section1 Variables
The variables that we have encountered so far are system variables,
such as \e DEFINES, \e SOURCES and \e HEADERS. It is possible for you
to create your own variables so that you use them in scopes. It's
easy to create your own variable; just name it and assign something to
it. For example:
\code
MY_VARIABLE = value
\endcode
There are no restricitions on what you do to your own variables, as \e
qmake will just ignore them unless it needs to look at them for a
scope.
You can also assign the value of a current variable to another
variable by prefixing $$ to the variable name. For example:
\code
MY_DEFINES = $$DEFINES
\endcode
Now the MY_DEFINES variable contains what is in the DEFINES variable at
this point in the project file. This is also equivalent to:
\code
MY_DEFINES = $${DEFINES}
\endcode
The second notation allows you to adjoin the variable expansion to another
value without separating by space. \e qmake will allow a variable to
contain anything (including $(VALUE), which will be placed directly into
the Makefile, and allow it to expand as appropriate, usually an environment
variable). However, if you require an environment variable to be replaced
immediately then you may use the $$() notation. For example:
\code
MY_DEFINES = $$(ENV_DEFINES)
\endcode
This will set MY_DEFINES to the value of the evironment variable
ENV_DEFINES as it parses the .pro file. Additionally you may call built-in
functions in variable replacing. These functions (not to be confused with
Test Functions as enumerated in the next section) are listed below:
\section2 join( variablename, glue, before, after )
This will join the value of \e variablename with glue. If this value is
non-empty it will prefix the value with \e before and suffix it with \e
after. \e variablename is the only required field, the others will default
to empty strings. If you need to encode spaces in \e glue, \e before, or \e
after you must quote them.
\section2 prompt( question )
This will display \e question, and read from stdin as a return value.
\section2 member( variablename, position )
This will place the value in \e variablename in position \e position of the
list. If the value of \e variablename is not long this will return an empty
string. \e variablename is the only required field, if not specified
position will default to the first value in the list (0).
\section2 find( variablename, substr )
This will place all the values in \e variablename that match \e substr. \e
substr may be a regular expression as well, and will be matched
accordingly.
\code
MY_VAR = one two three four
MY_VAR2 = $$join(MY_VAR, " -L", -L) -Lfive
MY_VAR3 = $$member(MY_VAR, 2) $$find(MY_VAR, t.*)
\endcode
MY_VAR2 will contain '-Lone -Ltwo -Lthree -Lfour -Lfive', and MYVAR3 will
contains 'three two three'.
\section2 system( program_and_args )
This will return the stdout/stderr of the program executed, and parse it as
normally expected. You can use this to interrogate information about the
platform for example.
\code
UNAME = $$system(uname -s)
contains( UNAME, [lL]inux ):message( This looks like Linux ($$UNAME) to me )
\endcode
\section1 Test Functions
\e qmake provides built-in functions that perform simple, yet powerful
tests. These tests may be used in place of scopes (as described above), in
some cases it is more usefull to use the test function by itself ignoring
its test value.
\section2 contains( variablename, value )
If \e value is in the list of values stored in the variable called \e
variablename, then the settings inside the scope will be processed.
For example:
\code
contains( CONFIG, thread ) {
DEFINES += ENABLE_THREAD_SUPPORT
}
\endcode
If \e thread is in the list of values for the \e CONFIG variable, then
ENABLE_THREAD_SUPPORT will be added to the list of values in the \e
DEFINES variable.
\section2 count( variablename, number )
If \e number matches the number of values stored in the variable
called \e variablename, then the settings inside the scope will be
processed. For example:
\code
count( DEFINES, 5 ) {
CONFIG += debug
}
\endcode
\section2 error( string )
This function outputs the string given and then makes \e qmake exit.
For example:
\code
error( "An error has occured" )
\endcode
The text "An error has occured" will be displayed on the console and
\e qmake will exit.
\section2 exists( filename )
If the specified file exists, then the settings inside the scope will
be processed. For example:
\code
exists( /local/qt/qmake/main.cpp ) {
SOURCES += main.cpp
}
\endcode
If \e /local/qt/qmake/main.cpp exists then main.cpp is added to the
list of source files.
Note that "/" can be used as a directory separator regardless of the
platform.
\section2 equals( variable, value )
If the specified variable is equal to the value passed the scope will
be processed. For example:
\code
NUMBERS = 1 2 3
equals( NUMBERS, 3 4 5 ) {
message("The numbers are equal")
}
\endcode
The message will not be displayed because "1 2 3" does not equal "1 2
3". As with all functions you can pass an expanded variable as the
value argument (ie, $$NUMBERS).
\section2 include( filename )
The contents of filename are included at this point in the project
file, so any settings in the specified file will be processed. An
example of this is:
\code
include( myotherapp.pro )
\endcode
Any settings in the \e myotherapp.pro project file are now processed.
\section2 isEmpty( variablename )
This is the equivalent of using count( variablename, 0 ). If the
variable called \e variablename has no elements, then the settings
inside the scope will be processed. An example of this is:
\code
isEmpty( CONFIG ) {
CONFIG += qt warn_on debug
}
\endcode
\section2 message( string )
This function simply outputs a message on the console.
\code
message( "This is a message" )
\endcode
The text "This is a message" is output to the console and
processing of the project file carries on.
\section2 system( command )
The specified command is performed and if it returns an exit code of
1, the settings inside the scope are processed. For example:
\code
system( ls /bin ) {
SOURCES += bin/main.cpp
HEADERS += bin/main.h
}
\endcode
So if the command \e {ls /bin} returns 1 then \e bin/main.cpp is added
to the list of sources and \e bin/main.h is added to the list of
headers.
\section2 infile( filename, var, val )
This function will succeed if the file \e filename (when parsed
by qmake itself) contains the variable \e var with a value of
\e val. You may also not pass in a third argument (\e val) and the
function will only test if \e var has been assigned to in the file.
|