1

I have created a waf feature to run size on all build files, but I do not want to do it like I orginally wanted (see Custom waf task does neither run nor find sources).

So I wrote now a feature, which works generally, but does again not find the sources correctly. I use @after('apply_link'), therefore the binaries should be present...

  • First run: all binaries are generated, but size has no input files.
  • Second run: all binaries are there and the size feature is run correctly. Why is it like this?

waf feature:

from waflib.TaskGen import extension
from waflib.TaskGen import after

class size(Task.Task):
    color = 'BLUE'
    run_str = '${SIZE} ${SRC} > ${TGT}'

@extension('.o', '.a', '.elf')
@after('apply_link')
def add_size(self, node):
    name = 'size'
    out = node.change_ext('.log')
    task = self.create_task(name, node, out)
    try:
        self.size_tasks.append(task)
    except AttributeError:
        self.size_tasks = [task]
    return task

Using the feature:

    bld(source=bld.path.get_bld().ant_glob('**/*.o **/*.a **/*.elf'),
    features='size')

Side question: Is there a better option to log the output of this task as redirecting the output with > into the output file?

neuro
  • 14,948
  • 3
  • 36
  • 59
wafwafwaf
  • 191
  • 9

1 Answers1

1

When you use the Taskgen.after decorator you just tell waf to run the add_size method after the apply_link method in the task generation step. As your task generator does not link anything, you do not have any apply_link method, you don't need it.

Your problem is that you use ant_glob on the build directory. The first time, there is nothing in it, so ant_glob returns nothing, so your task have nothing to do :)

You have to add a feature to the task generator that creates the objects you want to size. For example:

@feature("size") # or feature("*") for every taskgen
@after('apply_link')
def process_sizes(self):

    if getattr(self, "link_task", None) is None:
        return

    objets_to_size = []

    objects_to_size.extend(self.link_task.inputs) # object files
    objects_to_size.extend(self.link_task.outputs) # exe, libs ...

    for node in objects_to_size:
         out = node.change_ext('.log')
         self.create_task("size", node, out)

To use:

bld.program(source = "main.c", features = "size", target = "myexe")

You will get the size of all files of the link process.

@Taskgen.extension is only used by Taskgen.process_source which process the source attribute of the task generator. It does not work well with intermediate objects not expressed in wscript.

neuro
  • 14,948
  • 3
  • 36
  • 59
  • Hm, this does not work on my machine ``Cycle detected in the method execution: - process_use after ['propagate_uselib_vars'] - process_source after ['process_use', 'apply_link'] - apply_link after ['process_use', 'update_sources'] - propagate_uselib_vars after [] - update_sources after ['process_source'] `` – wafwafwaf Dec 11 '18 at 16:51
  • 1
    @waf3: yep, my mistake. `apply_link` comes after `process_source`. I will edit my answer ... – neuro Dec 11 '18 at 17:16
  • ok, wonderfull, it works now :) thanks for the edit! But I can not figure out, what tasks are generating the *.a and *.elf files, since there only seems to be the `link_task` described in to the documenation. – wafwafwaf Dec 12 '18 at 11:05
  • 1
    static libs are usually generated by the `bld.stlib` shortcut. You can use `link_task.outputs`. For .elf I do not know. Probably some side effect of compilation/link ? – neuro Dec 12 '18 at 11:27
  • 1
    If you have a clear mapping between .o and .elf for example, you can use change_ext to achieve what you want – neuro Dec 12 '18 at 11:30
  • Your hint to use the `link_task.outputs` also, was the solution. It is now working for all binary output! Perfect answer, many thanks again! – wafwafwaf Dec 12 '18 at 12:06
  • is there a option to "reduce" the logging level of the feature? – wafwafwaf Dec 13 '18 at 09:16
  • 1
    You can use `Logs.debug("myfeature: any log message")`. Those logs will not print on terminal, unless you use the option `--zone myfeature`. Use `Logs.info("any log")` for logs you always want to print. – neuro Dec 13 '18 at 11:16