summaryrefslogtreecommitdiffstats
path: root/qmake/book/qmake-advanced.leaf
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/book/qmake-advanced.leaf')
-rw-r--r--qmake/book/qmake-advanced.leaf401
1 files changed, 401 insertions, 0 deletions
diff --git a/qmake/book/qmake-advanced.leaf b/qmake/book/qmake-advanced.leaf
new file mode 100644
index 00000000..21c58242
--- /dev/null
+++ b/qmake/book/qmake-advanced.leaf
@@ -0,0 +1,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 += QT_THREAD_SUPPORT
+ }
+ }
+\endcode
+
+To save writing many nested scopes, you can nest scopes using a colon
+like this:
+
+\code
+ win32:thread {
+ DEFINES += QT_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 += QT_THREAD_SUPPORT
+ } else:debug {
+ DEFINES += QT_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 retquire 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 retquired 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 retquired 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 += QT_THREAD_SUPPORT
+ }
+\endcode
+
+If \e thread is in the list of values for the \e CONFIG variable, then
+QT_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.