Code generators may lead to complicated scenarios, especially when they create files which are not known in advance. The usual process consists in adding specific task classes which will read the files after the execution, create the corresponding node objects, and update the node signatures.

When the generated files are kept in the source directory (and redistributed with the source code), a more simple (and less correct) solution is still possible. In the following example, a code generator will create C files in the folder named "generated":

def options(opt):
opt.load('compiler_c')
def configure(cnf):
cnf.load('compiler_c')
def build(bld):
from waflib import Build
bld.post_mode = Build.POST_LAZY

def create_files(tsk):
out = tsk.generator.path.make_node('generated')
from waflib import Utils
for x in out.ant_glob('*.c'):
x.delete()
import random
for x in range(2):
num = random.randint(0, 2**31)
k = out.make_node('test%d.c' % num)
k.write('int k%d = %d;' % (num, num))
bld(rule=create_files, source='wscript', name='codegen')

bld.add_group()

bld.program(features='find_them',
source=['main.c'], target='app')

from waflib.TaskGen import feature, before
from waflib import Utils
@feature('find_them')
@before('process_source')
def list_the_source_files(self):
self.source = Utils.to_list(self.source) +
self.path.ant_glob('generated/*.c')

The first rule create_files will remove any C file from the generated directory, and add new ones with random names. The generated files, and main.c will be compiled into a program, but only after the files are correctly created.

The POST_LAZY scheme will force the build groups to be processed sequentially, so the total of tasks to execute will be incorrect. For example, the progress bar will reach 100% each time a build group is processed. For example, the task counter will jump from 1 to 5:

12:52:14 /playground/codegen> waf clean build
'clean' finished successfully (0.005s)
Waf: Entering directory `/playground/codegen/build'
[1/1] codegen: wscript
[2/5] c: main.c -> build/main.c.1.o
[3/5] c: generated/test2017594948.c -> build/generated/test2017594948.c.1.o
[4/5] c: generated/test277184706.c -> build/generated/test277184706.c.1.o
[5/5] cprogram: build/main.c.1.o build/generated/test2017594948.c.1.o build/generated/test277184706.c.1.o -> build/app
Waf: Leaving directory `/playground/codegen/build'
'build' finished successfully (0.235s)

The feature find_them is will complete the program source list after code generator is executed, as adding  source=bld.ant_glob('**/*.c') would only read old files.

The code source for this example has been added to the playground folder.