Tasks can have side effects besides executing their content. For example, recently do_rootfs was changed so that it creates ${IMGDEPLOYDIR}, the directory which all following image-related tasks write into: do_rootfs[cleandirs] += "${S} ${IMGDEPLOYDIR}" meta-swupd has a special image creation mode where do_rootfs is set to empty with e.data.setVar("do_rootfs", "") in a virtual recipe and the final rootfs gets created in do_image. Setting do_rootfs to empty had the effect that it was skipped *completely*, including the creation of ${IMGDEPLOYDIR}, which broke creating of such images. This might be intentional, but at first glance it looks like a somewhat too eager optimization: IMHO an empty task with side effects is valid and those side effects should be applied. There's a patch for meta-swupd which works around that (by setting do_rootfs to "pass" instead of ""), so fixing this is not urgent. Closing as "works-as-intended" would also be okay.
This can be explained if you look at http://git.yoctoproject.org/cgit.cgi/poky/tree/bitbake/lib/bb/build.py#n188 which is the start of the exec_func() which does: body = d.getVar(func, False) if not body: if body is None: logger.warning("Function %s doesn't exist", func) return I suspect this could be moved after the directory handling pieces to avoid the effect you describe.
http://git.yoctoproject.org/cgit.cgi/poky/commit/?id=53b1fa2d3e1244c46a705d9a40ca0dbee92eab98