2

I would like to build many outputs based on the same input, e.g. a hex and a binary from an elf. I will do this multiple times, different places in the wscript so I'd like to wrap it in a feature.

Ideally something like:

bld(features="hex", source="output.elf")
bld(features="bin", source="output.elf")

How would I go about implementing this?

Andak
  • 371
  • 2
  • 14

1 Answers1

1

If your elf files always have the same extension, you can simply use that:

# untested, naive code

from waflib import TaskGen

@TaskGen.extension('.elf')
def process_elf(self, node): # <- self = task gen, node is the current input node
    if "bin" in self.features:
        bin_node = node.change_ext('.bin')
        self.create_task('make_bin_task', node, bin_node)

    if "hex" in self.features:
        hex_node = node.change_ext('.hex')
        self.create_task('make_hex_task', node, hex_node)

If not, you have to define the features you want like that:

from waflib import TaskGen

@Taskgen.feature("hex", "bin") # <- attach method features hex AND bin
@TaskGen.before('process_source')

def transform_source(self):  # <- here self = task generator
    self.inputs = self.to_nodes(getattr(self, 'source', []))
    self.meths.remove('process_source') # <- to disable the standard process_source

@Taskgen.feature("hex") # <- attach method to feature hex
@TaskGen.after('transform_source')
def process_hex(self):
    for i in self.inputs:
        self.create_task("make_hex_task", i, i.change_ext(".hex"))

@Taskgen.feature("bin") # <- attach method to feature bin
@TaskGen.after('transform_source')
def process_hex(self):
    for i in self.inputs:
        self.create_task("make_bin_task", i, i.change_ext(".bin"))

You have to write the two tasks make_elf_task and make_bin_task. You should put all this in a separate python file and make a "plugin".

You can also define a "shortcut" to call:

def build(bld):
    bld.make_bin(source = "output.elf")
    bld.make_hex(source = "output.elf")

    bld(features = "hex bin", source = "output.elf") # when both needed in the same place

Like that:

from waflib.Configure import conf

@conf
def make_bin(self, *k, **kw): # <- here self = build context

    kw["features"] = "bin" # <- you can add bin to existing features kw
    return self(*k, **kw)

@conf
def make_hex(self, *k, **kw):

    kw["features"] = "hex"
    return self(*k, **kw)
neuro
  • 14,948
  • 3
  • 36
  • 59
  • Perfect! I also had to add a dummy hex and bin feature function (which does nothing) to your first example, else waf would complain _"feature 'hex' does not exist - bind at least one method to it?"_ – Andak Sep 04 '19 at 07:31
  • Plus change the function prototypes of make_bin and make_hex to `make_bin(self, *k, **kw)` – Andak Sep 05 '19 at 07:40