[bitbake-devel] python function used in variable expansion called multiple times per recipe
Daniel Lazzari
dlazzari at leapfrog.com
Thu Apr 19 21:24:08 UTC 2012
>> I think immediate expansion is what I’ll need to use, thanks for the tip.
>> That at least brings the invocation down to once per run. Unfortunately, the
>> variable doesn’t seem to get filled in when I change to immediate
>expansion.
>>
>> def testFunc(bb, d):
>> print( bb.data.getVar("PN", d, True) )
>> return "e1"
>>
>> EXTERNPV := "${@testFunc(bb, d)}"
>>
>> Now only prints the package name once, but using –e, I don’t see the
>> variable EXTERNPV at all.
>
>Don't know what to tell you. It does work, so it's something wrong on
>your end. Either it's returning an empty string, which will result in
>-e only showing the commented out definition, or it's raising an
>exception, or something else in your setup. Aside: you don't need to
>pass 'bb' in. That namespace is always accessible, even from def'd
>python functions.
>--
>Christopher Larson
Just thought I'd provide an update real quick on this. I discovered, to my dismay, that even doing an immediate expansion still ran the code before every task for that recipe. I switched to using an event handler, but the RecipeParsed event occurs before every task for that recipe. Eventually I discovered that the variable BB_WORKERCONTEXT is set for RecipeParsed events when they are occurring before a task, but not for the initial parse. Also, I discovered that setting a variable in the event handler would not necessarily keep it set through building the recipe. Thus I devised the below code to run the time intensive code during initial parse and cache the value in a file so it can be picked up again in later events. I'm leaving this here in case it helps someone else.
addhandler svn_extern_eventhandler
python svn_extern_eventhandler() {
from bb.event import getName
from bb import data
if getName(e) == "RecipeParsed":
extern_cache_dir = os.path.join( data.getVar('TMPDIR', e.data, True),
'stamps',
data.getVar('MULTIMACH_TARGET_SYS', e.data, True) )
extern_cache = os.path.join( extern_cache_dir,
data.getVar('PN', e.data, True) + '.extern_cache' )
#If BB_WORKERCONTEXT is "1", this is NOT the initial recipe parse
if data.getVar('BB_WORKERCONTEXT', e.data, True) == "1":
#Pull cached copy
try:
cache_file = open(extern_cache, 'r')
externpv = cache_file.read()
cache_file.close()
except IOError:
#Failed to get cached copy, do it the hard way
externpv = getExternRevs(e.data)
else:
externpv = getExternRevs(e.data)
try:
os.makedirs(extern_cache_dir)
except OSError:
pass
#Generate the cache for later use
cache_file = open(extern_cache, 'w')
cache_file.write(externpv)
cache_file.close()
data.setVar('EXTERNPV', externpv, e.data)
}
More information about the bitbake-devel
mailing list