Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

[Prev: qmake Concepts] [Home] [Next: qmake Tutorial]

## qmake's Advanced Concepts

Even though it appears that qmake can only be used for simple purposes, it can also be very powerful. It also allows you to decide what to do on certain platforms. This avoids having to create a project file for each platform.

### Operators

So far, you have seen the = operator and += 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.

#### The '=' operator

This operator simply assigns a value to a variable, it should be used in the following form:

    	TARGET = myapp

This sets the TARGET variable to myapp. This will remove any previously set TARGET.

#### The '+=' operator

This operator adds a value to the list of values in a variable. It should be used in the following form:

    	DEFINES += QT_DLL

This adds QT_DLL to the list of pre-processor defines to be put in the makefile.

#### The '-=' operator

This operator removes a value from the list of values in a variable. It should be used in the following form:

    	DEFINES -= QT_DLL

This removes QT_DLL from the list of pre-processor defines to be put in the makefile.

#### The '*=' operator

This operator only adds a value to the list of values in a variable if it doesn't already exist. It should be used in the following form:

    	DEFINES *= QT_DLL

If QT_DLL is already in the list of pre-processor defines then it is not added, otherwise it is.

#### The '~=' operator

This operator replaces any values that match the regexp with the specified value. It should be used in the following form:

    	DEFINES ~= s/QT_[DT].+/QT

This removes any values in the list that start with QT_D or QT_T with QT.

### Scopes

A scope are similar to 'if' statements, if a certain condition is true, the settings inside the scope are processed. A scope should be written in the following form:

    	win32 {
    		DEFINES += QT_DLL
    	}

The above code will add the QT_DLL define to the makefile if qmake is used on a Windows platform. If qmake is used on a different platform than Windows, the define will be ignored.

Let's say we want to process something on all platforms except for the Windows platform. In this case all we would need to do is put ! before win32, so the scope will look like:

    	!win32 {
    		DEFINES += QT_DLL
    	}

This means that the above code will be processed on all platforms except for Windows.

Scopes also apply for anything that is put on the CONFIG line, so if it is on the CONFIG line then it is true. 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.

    	CONFIG += qt warn_on debug
    	debug {
    		TARGET = myappdebug
    	}
    	release {
    		TARGET = myapp
    	}

In the above code, two scopes are created which would depend on what is put on the CONFIG line. In the example, debug is on the config line, so the TARGET variable is set to myappdebug. If release was on the config line, then the TARGET variable would be set to myapp.

It is also possible to check for two things before processing some settings. For instance, if you want to check if qmake is used on Windows and that the thread configuration is set, then using the way already shown, it would look like:

    	win32 {
    		thread {
    			DEFINES += QT_THREAD_SUPPORT
    		}
    	}

This can be shortened down, so it looks like:

    	win32:thread {
    		DEFINES += QT_THREAD_SUPPORT
    	}

Which makes it easier to understand and easier to maintain.

### Variables

The variables that we have encountered so far are system variables, such as DEFINES, SOURCES and 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. An example of this is:

    	THIS_IS_MY_OWN = variable

There are no restricitions on what you do to your own variables, as 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. An example of this:

    	MY_DEFINES = $$DEFINES

Now the MY_DEFINES variable contains what is currently in the DEFINES variable.

### Functions

qmake provides built-in functions that perform simple, yet powerful tasks. The following are a few functions that are available for use.

#### contains( variablename, value )

If value is in the list of values for variablename, then the settings inside the scope will be processed. For example:

    	contains( CONFIG, thread ) {
    		DEFINES += QT_THREAD_SUPPORT
    	}

If thread is in the list of values for the CONFIG variable, then QT_THREAD_SUPPORT will be added to the list of values in the DEFINES variable.

#### count( variablename, number )

If number matches the number of elements in variablename, then the settings inside the scope will be processed. For example:

    	count( DEFINES, 5 ) {
    		CONFIG += debug
    	}

#### error( string )

This function just simply outputs the string given and then qmake will exit. For example:

    	error( "An error has occured" )

The text "An error has occured" will be displayed on the console and qmake will exit.

#### exists( filename )

If the specified file exists, then the settings inside the scope will be processed. For example:

    	exists( /local/qt/qmake/main.cpp ) {
    		SOURCES += main.cpp
    	}

If /local/qt/qmake/main.cpp exists then main.cpp is added to the list of source files.

#### 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:

    	include( myotherapp.pro )

Any settings in the myotherapp.pro project file are now processed.

#### isEmpty( variablename )

This is the equivalent of using count( variablename, 0 ). If the variablename has no elements, then the settings inside the scope will be processed. An example of this is:

    	isEmpty( CONFIG ) {
    		CONFIG += qt warn_on debug
    	}

#### message( string )

This function simply outputs a message on the console without interfering with any further processing.

    	message( "This is a message" )

The text "This is a message" is outputted to the console and processing of the project file carries on.

#### 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:

    	system( ls /bin ) {
    		SOURCES += bin/main.cpp
    		HEADERS += bin/main.h
    	}

So if the command ls /bin returns 1 then bin/main.cpp is added to the list of sources and bin/main.h is added to the list of headers.

[Prev: qmake Concepts] [Home] [Next: qmake Tutorial]