
The Waf features are names linked to specific functions by the decorator
:py:func:`waflib.TaskGen.feature`. The functions
are mapped to the class :py:class:`waflib.TaskGen.task_gen` as methods.

The association between feature names and methods is *many-to-many*, which means
that a method may be involved in several features, and that a feature may be bound
to several methods.

Here is how to create and use a new feature named **foo**::

	from waflib.TaskGen import feature
	@feature('foo')
	def print_hello(self):
		print("Hello, World!")

The function *print_hello* is now associated with the :py:class:`waflib.TaskGen.task_gen` class, which means
that it may be used directly::

	def build(bld):
		tg = bld()
		tg.print_hello()

The method may be called directly, and several times. If a method creates task, the same tasks will be created
more than once, which may cause build errors. The *feature* attribute is used to have the associated 
methods called *exactly once* before the build starts::

	def build(bld):
		bld(features='foo')

Here is a more complete example with two methods::

	from waflib.TaskGen import feature, after_method

	@feature('foo')
	@after_method('print_bar')
	def print_hello(self):
		print("Hello, Foo!")

	@feature('bar')
	def print_bar(self):
		print("Hello, Bar!")

	def build(bld):
		bld(features='foo bar')

The order of method execution is unrelated to the order of the features given. For instance,
this example will print "Hello, Bar!" then "Hello, Foo!". The decorators
:py:func:`waflib.TaskGen.after` and :py:func:`waflib.TaskGen.before` are
enforcing partial order constraints on the methods to execute.

The following maps represent the associations betwen feature methods (represented in yellow) and
methods associated to other feature names.

