[yocto] [PATCH] bb.build.addtask: add simple check for circular dependency

Ulf Samuelsson yocto at emagii.com
Thu Jan 17 14:50:04 PST 2019



> 17 jan. 2019 kl. 22:05 skrev Richard Purdie <richard.purdie at linuxfoundation.org>:
> 
>> On Thu, 2019-01-17 at 19:15 +0100, Ulf Samuelsson wrote:
>> From 864e49bedbdab480c5ada9588ce8f980f23919dd Mon Sep 17 00:00:00
>> 2001
>> From: Ulf Samuelsson <ulf at emagii.com>
>> Date: Thu, 17 Jan 2019 19:07:17 +0100
>> Subject: [PATCH] bb.build.addtask: add simple check for circular
>> dependency
> 
> We really can't hardcode a list of tasks like this in bitbake :(
> 
> The list is also incorrect (at a quick look its packagedata and
> populate_sysroot is missing).

I would say it may be incomplete, but it is only wrong, if they are in the wrong order.

> 
> We'll need to come up with a better algorithm than this. From
> experience with circular task dependencies within bitbake's runqueue,
> this is a hard problem though.

It is an attempt to do a reasonable effort.
It will not handle a lot of user tasks which depends on each other for sure...
Is it better to have no detection, than a detection which works on the most common cases?
I will not have the time to look into a clean cover all cases algorithm, unfortunately.

Best Regards,
Ulf Samuelsson
> 
> Cheers,
> 
> Richard
> 
>> Signed-off-by: Ulf Samuelsson <ulf at emagii.com>
>> ---
>>  bitbake/lib/bb/build.py | 48 
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 48 insertions(+)
>> 
>> diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py
>> index 3e2a94e..887ced1 100644
>> --- a/bitbake/lib/bb/build.py
>> +++ b/bitbake/lib/bb/build.py
>> @@ -43,6 +43,25 @@ logger = logging.getLogger('BitBake.Build')
>> 
>>  __mtime_cache = {}
>> 
>> +KNOWN_TASKS = {
>> +    'do_fetch' :           1 ,
>> +    'do_unpack' :          2 ,
>> +    'do_patch' :           3 ,
>> +    'do_configure' :       4 ,
>> +    'do_compile' :         5 ,
>> +    'do_install' :         6 ,
>> +    'do_package' :         7 ,
>> +    'do_package_data' :    8 ,
>> +    'do_rootfs' :          9 ,
>> +    'do_image_qa' :       10 ,
>> +    'do_image' :          11 ,
>> +    'do_image_tar' :      12 ,
>> +    'do_image_ubifs' :    12 ,
>> +    'do_image_jffs2' :    12 ,
>> +    'do_image_complete' : 13 ,
>> +    'do_build' :          14
>> +}
>> +
>>  def cached_mtime_noerror(f):
>>      if f not in __mtime_cache:
>>          try:
>> @@ -820,7 +839,34 @@ def add_tasks(tasklist, d):
>>      # don't assume holding a reference
>>      d.setVar('_task_deps', task_deps)
>> 
>> +def circular(after, before):
>> +    if after == None:
>> +        return False
>> +    if before == None:
>> +        return False
>> +    for a in after.split():
>> +        if a in KNOWN_TASKS:
>> +            for b in before.split():
>> +                if a == b:
>> +                    return True
>> +                if b in KNOWN_TASKS:
>> +                    if KNOWN_TASKS[b] < KNOWN_TASKS[a]:
>> +                        return True
>> +                    else:
>> +                        # tasks OK
>> +                        pass
>> +                else:
>> +                    # b is unknown
>> +                    pass
>> +        else:
>> +            # a is unknown
>> +            pass
>> +
>>  def addtask(task, before, after, d):
>> +    if circular(after, before):
>> +        logger.error("addtask: %s cannot be after %s and before %s"
>> % 
>> (task, after, before))
>> +        raise
>> +
>>      if task[:3] != "do_":
>>          task = "do_" + task
>> 
>> @@ -909,3 +955,5 @@ def tasksbetween(task_start, task_end, d):
>>          chain.pop()
>>      follow_chain(task_start, task_end)
>>      return outtasks
>> +
>> +
> 



More information about the yocto mailing list