summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Larson <chris_larson@mentor.com>2010-03-19 17:22:19 -0700
committerChris Larson <chris_larson@mentor.com>2010-03-23 19:02:53 -0700
commit4ee9a56e16f1eb3c1649eaa3127b09ab0e93d1ec (patch)
treea55ba9d14c7230ab5cb9ced18a10c81e17ffadaa /lib
parentb2486ec57c6a7adf09d0960fdf6727881b324d2f (diff)
downloadbitbake-4ee9a56e16f1eb3c1649eaa3127b09ab0e93d1ec.tar.gz
Implement BBVERSIONS
This implements a feature similar to BBCLASSEXTEND, but for generating multiple versions of a given recipe. For example: BBVERSIONS = "1.0 2.0 git". In addition to the above, one can utilize [a-b] style patterns, and can have a :<basever> postfix, which allows you to essentially name the range of versions. Both the current version and the basever end up in OVERRIDES, and the basever gets placed into the BPV variable. The default BPV, if none is specified, is the original PV of the recipe, before bbversions processing. In this way, you can do things like: BBVERSIONS = "1.0.[0-6]:1.0.0+ 1.0.[7-9]:1.0.7+" SRC_URI_append_1.0.7+ = "file://some_extra_patch.patch;patch=1" Or you can create a recipe per range, and name the recipe file as such: nano_1.0.7+.bb. Signed-off-by: Chris Larson <chris_larson@mentor.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/bb/cache.py10
-rw-r--r--lib/bb/parse/ast.py114
-rw-r--r--lib/bb/parse/parse_py/BBHandler.py26
3 files changed, 121 insertions, 29 deletions
diff --git a/lib/bb/cache.py b/lib/bb/cache.py
index 43091daa2..9a962ecc7 100644
--- a/lib/bb/cache.py
+++ b/lib/bb/cache.py
@@ -143,8 +143,8 @@ class Cache:
if dep not in self.depends_cache[fn]["__depends"]:
self.depends_cache[fn]["__depends"].append(dep)
- # Make sure BBCLASSEXTEND always makes the cache too
- self.getVar('BBCLASSEXTEND', virtualfn, True)
+ # Make sure the variants always make it into the cache too
+ self.getVar('__VARIANTS', virtualfn, True)
self.depends_cache[virtualfn]["CACHETIMESTAMP"] = bb.parse.cached_mtime(fn)
@@ -199,7 +199,7 @@ class Cache:
self.cacheValidUpdate(fn)
if self.cacheValid(fn):
- multi = self.getVar('BBCLASSEXTEND', fn, True)
+ multi = self.getVar('__VARIANTS', fn, True)
for cls in (multi or "").split() + [""]:
virtualfn = self.realfn2virtual(fn, cls)
if self.depends_cache[virtualfn]["__SKIPPED"]:
@@ -292,7 +292,7 @@ class Cache:
self.clean[fn] = ""
# Mark extended class data as clean too
- multi = self.getVar('BBCLASSEXTEND', fn, True)
+ multi = self.getVar('__VARIANTS', fn, True)
for cls in (multi or "").split():
virtualfn = self.realfn2virtual(fn, cls)
self.clean[virtualfn] = ""
@@ -443,7 +443,7 @@ class Cache:
# Touch this to make sure its in the cache
self.getVar('__BB_DONT_CACHE', file_name, True)
- self.getVar('BBCLASSEXTEND', file_name, True)
+ self.getVar('__VARIANTS', file_name, True)
def load_bbfile( self, bbfile , config):
"""
diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index 70a69b8d1..59aa44bee 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -22,9 +22,11 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import bb, re, string
+from itertools import chain
__word__ = re.compile(r"\S+")
__parsed_methods__ = bb.methodpool.get_parsed_dict()
+_bbversions_re = re.compile(r"\[(?P<from>[0-9]+)-(?P<to>[0-9]+)\]")
class StatementGroup(list):
def eval(self, data):
@@ -335,3 +337,115 @@ def finalise(fn, d):
bb.event.fire(bb.event.RecipeParsed(fn), d)
+def _create_variants(datastores, names, function):
+ def create_variant(name, orig_d, arg = None):
+ new_d = bb.data.createCopy(orig_d)
+ function(arg or name, new_d)
+ datastores[name] = new_d
+
+ for variant, variant_d in datastores.items():
+ for name in names:
+ if not variant:
+ # Based on main recipe
+ create_variant(name, variant_d)
+ else:
+ create_variant("%s-%s" % (variant, name), variant_d, name)
+
+def _expand_versions(versions):
+ def expand_one(version, start, end):
+ for i in xrange(start, end + 1):
+ ver = _bbversions_re.sub(str(i), version, 1)
+ yield ver
+
+ versions = iter(versions)
+ while True:
+ try:
+ version = versions.next()
+ except StopIteration:
+ break
+
+ range_ver = _bbversions_re.search(version)
+ if not range_ver:
+ yield version
+ else:
+ newversions = expand_one(version, int(range_ver.group("from")),
+ int(range_ver.group("to")))
+ versions = chain(newversions, versions)
+
+def multi_finalize(fn, d):
+ safe_d = d
+
+ d = bb.data.createCopy(safe_d)
+ try:
+ finalise(fn, d)
+ except bb.parse.SkipPackage:
+ bb.data.setVar("__SKIPPED", True, d)
+ datastores = {"": safe_d}
+
+ versions = (d.getVar("BBVERSIONS", True) or "").split()
+ if versions:
+ pv = orig_pv = d.getVar("PV", True)
+ baseversions = {}
+
+ def verfunc(ver, d, pv_d = None):
+ if pv_d is None:
+ pv_d = d
+
+ overrides = d.getVar("OVERRIDES", True).split(":")
+ pv_d.setVar("PV", ver)
+ overrides.append(ver)
+ bpv = baseversions.get(ver) or orig_pv
+ pv_d.setVar("BPV", bpv)
+ overrides.append(bpv)
+ d.setVar("OVERRIDES", ":".join(overrides))
+
+ versions = list(_expand_versions(versions))
+ for pos, version in enumerate(list(versions)):
+ try:
+ pv, bpv = version.split(":", 2)
+ except ValueError:
+ pass
+ else:
+ versions[pos] = pv
+ baseversions[pv] = bpv
+
+ if pv in versions and not baseversions.get(pv):
+ versions.remove(pv)
+ else:
+ pv = versions.pop()
+
+ # This is necessary because our existing main datastore
+ # has already been finalized with the old PV, we need one
+ # that's been finalized with the new PV.
+ d = bb.data.createCopy(safe_d)
+ verfunc(pv, d, safe_d)
+ try:
+ finalise(fn, d)
+ except bb.parse.SkipPackage:
+ bb.data.setVar("__SKIPPED", True, d)
+
+ _create_variants(datastores, versions, verfunc)
+
+ extended = d.getVar("BBCLASSEXTEND", True) or ""
+ if extended:
+ pn = d.getVar("PN", True)
+ def extendfunc(name, d):
+ d.setVar("PN", "%s-%s" % (pn, name))
+ bb.parse.BBHandler.inherit([name], d)
+
+ safe_d.setVar("BBCLASSEXTEND", extended)
+ _create_variants(datastores, extended.split(), extendfunc)
+
+ for variant, variant_d in datastores.items():
+ if variant:
+ try:
+ finalise(fn, variant_d)
+ except bb.parse.SkipPackage:
+ bb.data.setVar("__SKIPPED", True, variant_d)
+
+ if len(datastores) > 1:
+ variants = filter(None, datastores.keys())
+ safe_d.setVar("__VARIANTS", " ".join(variants))
+
+ datastores[""] = d
+ return datastores
diff --git a/lib/bb/parse/parse_py/BBHandler.py b/lib/bb/parse/parse_py/BBHandler.py
index 4641c13d9..262c883c9 100644
--- a/lib/bb/parse/parse_py/BBHandler.py
+++ b/lib/bb/parse/parse_py/BBHandler.py
@@ -152,30 +152,8 @@ def handle(fn, d, include):
classes.remove(__classname__)
else:
if include == 0:
- safe_d = d
- d = bb.data.createCopy(safe_d)
- try:
- ast.finalise(fn, d)
- except bb.parse.SkipPackage:
- bb.data.setVar("__SKIPPED", True, d)
- darray = {"": d}
-
- extended = bb.data.getVar("BBCLASSEXTEND", d, True)
- if extended:
- bb.data.setVar("BBCLASSEXTEND", extended, safe_d)
-
- for cls in (extended or "").split():
- pn = data.getVar('PN', d, True)
- variant_d = bb.data.createCopy(safe_d)
- data.setVar('PN', pn + '-' + cls, variant_d)
- inherit([cls], variant_d)
- try:
- ast.finalise(fn, variant_d)
- except bb.parse.SkipPackage:
- bb.data.setVar("__SKIPPED", True, variant_d)
- darray[cls] = variant_d
- return darray
-
+ return ast.multi_finalize(fn, d)
+
if oldfile:
bb.data.setVar("FILE", oldfile, d)