Search code examples
variablesscopeyoctobitbake

How does the variable scope in BitBake works


I use Yocto and I was wondering how the variable scope works in a BitBake recipe:

My recipe looks like:

SRC_URI += "file://something"

python do_fetch_prepend() {
    d.appendVar("SRC_URI", "https://www.bla.com/resource.tar")
    bb.error("SRC_URI_1: %s " % d.getVar("SRC_URI"))
    d.setVar("TEST_VAR", "test")
}

python do_unpack_append() {
    bb.error("SRC_URI_2: %s " % d.getVar("SRC_URI"))
    bb.error("TEST_VAR: %s " % d.getVar("TEST_VAR"))
}

I run bitbake -v -c unpack myrecipe

SRC_URI_1 is printed as expected:"file://something https://www.bla.com/resource.tar" SRC_URI_2 is printed as: "file://something" TEST_VAR is printed as: None

It looks like setting/changing a variable in datastore (D) is only done in the scope of the do_fetch. Is this expected behaviour, because I read in the documentation that D is global variable.

If this is expected behaviour, is there away to change global variables in a task of a recipe?

The reason behind the question is that I need another native-recipe before I can add the extra URI to the SRC_URI. I tried first Inline Python Variable Expansion, but the BitBake parser already expanse the variable before the native recipe is put in 'native directory'. So I try to change the SRC_URI during fetch task and I 'load' my native recipe as follow:

python () {
  d.appendVarFlag('do_parse', 'depends', 'my-recipe-native:do_populate_sysroot')
}

In the do_fetch_prepend I use this native recipe which gives me the correct URL, which I wanted to append to the SRC_URI. So the fetching, unpacking, cleaning, etc works. It looks like the fetching works, but the unpacking not because the SRC_URI is not updated.


Solution

  • With a given task, variable changes are only local. This means do_unpack does not "see" a change made by the do_fetch task.

    This is necessary to allow some tasks to rerun when others are covered by sstate, to ensure things are deterministic.

    If you really want to do what you describe, you'd need something like a prefunc for the tasks where you need to modify SRC_URI.

    python myprefunc() {
        d.appendVar("SRC_URI", "https://www.bla.com/resource.tar")
    }
    do_fetch[prefuncs] += "myprefunc"
    do_unpack[prefuncs] += "myprefunc"
    

    However note that whilst this will do some of what you want, source archives, license manifests and sstate checksums may not work correctly since you're "hiding" source data from bitbake and this data is only present at task execution time, not parse time.