Defining variants

Using different build folders is very useful for checking at some point if a different configuration would compile properly. To create different kinds of builds at once, it is possible to use Waf variants to predefine the configuration sets for specific output subdirectories.

We will now demonstrate the definition and the usage of two variants named default and debug respectively:

srcdir = '.'
blddir = 'out_bld'

def configure(conf):
	conf.env.NAME = 'default'
	dbg = conf.env.copy() 1
	rel = conf.env.copy()

	dbg.set_variant('debug') 2
	conf.set_env_name('debug', dbg) 3
	conf.setenv('debug') 4
	# conf.check_tool('gcc') 5
	conf.env.NAME = 'foo' 6

	rel.set_variant('release') 7
	conf.set_env_name('cfg_name', rel)
	conf.setenv('cfg_name')
	conf.env.NAME = 'bar'

def build(bld):
	bld(rule='echo ${NAME} > ${TGT}', target='test.txt') 8
	bld(rule='echo ${NAME} > ${TGT}', target='test.txt'9, env=bld.env_of_name('debug').copy()) 10
	bld(rule='echo ${NAME} > ${TGT}', target='test.txt', env=bld.env_of_name('cfg_name').copy())
			

1

Create a copy of the default data set.

2

Set the copy to use the variant named debug: task using it will output their files into out_bld/debug

3

Bind the configuration set to the configuration. The configuration set will be saved when the configuration terminates

4

Replace conf.env by our new debug configuration set

5

Waf tools store their configuration data on conf.env, in this case the debug configuration set, not in the default

6

Store a variable on the debug configuration set

7

Define another variant called release. The variant name and the configuration set name may be different.

8

Task generator for the default variant.

9

The argument env is given to specify the task generator configuration set. The configuration set holds the variant definition.

10

Environments may be retrieved by name from the build context object. It is recommended to make copies to avoid accidental data sharing.

Upon execution, an output similar to the following will be observed:

$  waf distclean configure build
'distclean' finished successfully (0.000s)
'configure' finished successfully (0.001s)
Waf: Entering directory `/tmp/smallproject/out_bld'
[1/3] test.txt:  -> out_bld/default/test.txt
[2/3] test.txt:  -> out_bld/debug/test.txt 1
[3/3] test.txt:  -> out_bld/release/test.txt
Waf: Leaving directory `/tmp/smallproject/out_bld'
'build' finished successfully (0.020s)

$  tree out_bld/
out_bld/
|-- c4che
|   |-- cfg_name.cache.py 2
|   |-- build.config.py
|   |-- debug.cache.py
|   `-- default.cache.py
|-- config.log
|-- debug
|   `-- test.txt
|-- default
|   `-- test.txt 3
`-- release
    `-- test.txt

$  cat out_bld/default/test.txt out_bld/debug/test.txt out_bld/release/test.txt
default 4
foo
bar
			

1

The files are output in their respective variants

2

The configuration sets are stored and retrieved by names, which must be valid filenames without blanks.

3

The tasks output their files in the relevant variant

4

The file contents are different and correspond to the configuration sets used

[Note]Note
As a general rule, tasks created for a particular variant should not share data with the tasks from another variant.