summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
authorStefan Schmidt <stefan@datenfreihafen.org>2009-08-29 13:19:23 +0100
committerStefan Schmidt <stefan@datenfreihafen.org>2009-08-29 13:19:23 +0100
commitcbca70add0d3c814c25cde9fe7afff2e3a0344d3 (patch)
tree928d14912b63471e0a9c0395c8af6034a4baf07b /classes
parentefde023af7da8e638e67f1e4b755fe8d9e193371 (diff)
parentd24436424f2a706d70d2ef2cb8906cce6526698c (diff)
Merge branch 'org.openembedded.dev' of git@git.openembedded.org:openembedded into org.openembedded.dev
Diffstat (limited to 'classes')
-rw-r--r--classes/base.bbclass15
-rw-r--r--classes/clean.bbclass53
-rw-r--r--classes/gitver.bbclass54
-rw-r--r--classes/package_ipk.bbclass7
-rw-r--r--classes/srctree.bbclass115
-rw-r--r--classes/task-metadata-track.bbclass96
6 files changed, 334 insertions, 6 deletions
diff --git a/classes/base.bbclass b/classes/base.bbclass
index 598a7bb77f..97ccf5dfc3 100644
--- a/classes/base.bbclass
+++ b/classes/base.bbclass
@@ -523,6 +523,12 @@ python base_do_clean() {
os.system('rm -f '+ dir)
}
+python do_cleanall() {
+ pass
+}
+do_cleanall[recrdeptask] = "do_clean"
+addtask cleanall after do_clean
+
#Uncomment this for bitbake 1.8.12
#addtask rebuild after do_${BB_DEFAULT_TASK}
addtask rebuild
@@ -728,9 +734,14 @@ base_do_buildall() {
:
}
+def subprocess_setup():
+ import signal
+ # Python installs a SIGPIPE handler by default. This is usually not what
+ # non-Python subprocesses expect.
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
def oe_unpack_file(file, data, url = None):
- import bb, os
+ import bb, os, subprocess
if not url:
url = "file://%s" % file
dots = file.split(".")
@@ -799,7 +810,7 @@ def oe_unpack_file(file, data, url = None):
cmd = "PATH=\"%s\" %s" % (bb.data.getVar('PATH', data, 1), cmd)
bb.note("Unpacking %s to %s/" % (base_path_out(file, data), base_path_out(os.getcwd(), data)))
- ret = os.system(cmd)
+ ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True)
os.chdir(save_cwd)
diff --git a/classes/clean.bbclass b/classes/clean.bbclass
new file mode 100644
index 0000000000..65c1ab5d76
--- /dev/null
+++ b/classes/clean.bbclass
@@ -0,0 +1,53 @@
+def clean_builddir(d):
+ from shutil import rmtree
+
+ builddir = d.getVar("B", True)
+ srcdir = d.getVar("S", True)
+ if builddir != srcdir:
+ rmtree(builddir, ignore_errors=True)
+
+def clean_stamps(d):
+ from glob import glob
+ from bb import note
+ from bb.data import expand
+ from os import unlink
+
+ note("Removing stamps")
+ for stamp in glob(expand('${STAMP}.*', d)):
+ try:
+ unlink(stamp)
+ except OSError:
+ pass
+
+def clean_workdir(d):
+ from shutil import rmtree
+ from bb import note
+
+ workdir = d.getVar("WORKDIR", 1)
+ note("Removing %s" % workdir)
+ rmtree(workdir, ignore_errors=True)
+
+def clean_git(d):
+ from subprocess import call
+
+ call(["git", "clean", "-d", "-f", "-X"], cwd=d.getVar("S", True))
+
+def clean_make(d):
+ import bb
+
+ bb.note("Running make clean")
+ try:
+ bb.build.exec_func("__do_clean_make", d)
+ except bb.build.FuncFailed:
+ pass
+
+__do_clean_make () {
+ oe_runmake clean
+}
+
+python do_clean () {
+ clean_stamps(d)
+ clean_workdir(d)
+ clean_builddir(d)
+ clean_make(d)
+}
diff --git a/classes/gitver.bbclass b/classes/gitver.bbclass
new file mode 100644
index 0000000000..92c053ae24
--- /dev/null
+++ b/classes/gitver.bbclass
@@ -0,0 +1,54 @@
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# gitver.bbclass provides a GITVER variable which is a (fairly) sane version,
+# for use in ${PV}, extracted from the ${S} git checkout, assuming it is one.
+# This is most useful in concert with srctree.bbclass.
+
+
+GITVER = "${@get_git_pv('${S}', d)}"
+
+def gitver_mark_dependency(d):
+ from bb.data import expand
+ from bb.parse import mark_dependency
+ from os.path import abspath
+
+ fn = abspath(expand("${S}/.git/HEAD", d))
+ mark_dependency(d, fn)
+
+def get_git_pv(path, d, tagadjust=None):
+ from subprocess import Popen, PIPE
+ from os.path import join
+ from bb import error
+
+ env = {"GIT_DIR": join(d.getVar("S", True), ".git")}
+
+ def popen(cmd, **kwargs):
+ kwargs["stderr"] = PIPE
+ kwargs["stdout"] = PIPE
+ kwargs["env"] = env
+ try:
+ pipe = Popen(cmd, **kwargs)
+ except OSError, e:
+ #error("Execution of %s failed: %s" % (cmd, e))
+ return
+
+ (stdout, stderr) = pipe.communicate(None)
+ if pipe.returncode != 0:
+ #error("Execution of %s failed: %s" % (cmd, stderr))
+ return
+ return stdout.rstrip()
+
+ gitver_mark_dependency(d)
+
+ ver = popen(["git", "describe", "--tags"], cwd=path)
+ if not ver:
+ ver = popen(["git", "rev-parse", "--short", "HEAD"], cwd=path)
+ if ver:
+ return "0.0-%s" % ver
+ else:
+ return "0.0"
+ else:
+ if tagadjust:
+ ver = tagadjust(ver)
+ return ver
diff --git a/classes/package_ipk.bbclass b/classes/package_ipk.bbclass
index e3a7522619..e5561082fd 100644
--- a/classes/package_ipk.bbclass
+++ b/classes/package_ipk.bbclass
@@ -266,10 +266,9 @@ python do_package_ipk () {
ctrlfile.write("Replaces: %s\n" % ", ".join(rreplaces))
if rconflicts:
ctrlfile.write("Conflicts: %s\n" % ", ".join(rconflicts))
- src_uri = bb.data.getVar("SRC_URI", localdata, 1)
- if src_uri:
- src_uri = re.sub("\s+", " ", src_uri)
- ctrlfile.write("Source: %s\n" % " ".join(src_uri.split()))
+ src_uri = bb.data.getVar("SRC_URI", localdata, 1) or d.getVar("FILE", True)
+ src_uri = re.sub("\s+", " ", src_uri)
+ ctrlfile.write("Source: %s\n" % " ".join(src_uri.split()))
ctrlfile.close()
for script in ["preinst", "postinst", "prerm", "postrm"]:
diff --git a/classes/srctree.bbclass b/classes/srctree.bbclass
new file mode 100644
index 0000000000..dbf8ad2c3f
--- /dev/null
+++ b/classes/srctree.bbclass
@@ -0,0 +1,115 @@
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# srctree.bbclass enables operation inside of an existing source tree for a
+# project, rather than using the fetch/unpack/patch idiom.
+#
+# By default, it expects that you're keeping the recipe(s) inside the
+# aforementioned source tree, but you could override S to point at an external
+# directory and place the recipes in a normal collection/overlay, if you so
+# chose.
+#
+# It also provides some convenience python functions for assembling your
+# do_clean, if you want to leverage things like 'git clean' to simplify the
+# operation.
+
+
+# Grab convenience methods & sane default for do_clean
+inherit clean
+
+# Build here
+S = "${FILE_DIRNAME}"
+SRC_URI = ""
+
+
+def merge_tasks(d):
+ """
+ merge_tasks performs two operations:
+ 1) removes do_patch and its deps from the build entirely.
+ 2) merges all of the operations that occur prior to do_populate_staging
+ into do_populate_staging.
+
+ This is necessary, because of recipe variants (normal, native, cross,
+ sdk). If a bitbake run happens to want to build more than one of
+ these variants in a single run, it's possible for them to step on one
+ another's toes, due to the shared ${S}. Interleaved
+ configure/compile/install amongst variants will break things badly.
+ """
+ from itertools import chain
+ from bb import note
+
+ def __gather_taskdeps(task, seen):
+ for dep in d.getVarFlag(task, "deps"):
+ if not dep in seen:
+ __gather_taskdeps(dep, seen)
+ if not task in seen:
+ seen.append(task)
+
+ def gather_taskdeps(task):
+ items = []
+ __gather_taskdeps(task, items)
+ return items
+
+ newtask = "do_populate_staging"
+ mergedtasks = gather_taskdeps(newtask)
+ mergedtasks.pop()
+ deltasks = gather_taskdeps("do_patch")
+
+ for task in (key for key in d.keys()
+ if d.getVarFlag(key, "task") and
+ not key in mergedtasks):
+ deps = d.getVarFlag(task, "deps")
+ for mergetask in mergedtasks:
+ if mergetask in (d.getVarFlag(task, "recrdeptask"),
+ d.getVarFlag(task, "recdeptask"),
+ d.getVarFlag(task, "deptask")):
+ continue
+
+ if mergetask in deps:
+ deps.remove(mergetask)
+ #note("removing dep on %s from %s" % (mergetask, task))
+
+ if not mergetask in deltasks and \
+ not newtask in deps:
+ #note("adding dep on %s to %s" % (newtask, task))
+ deps.append(newtask)
+ d.setVarFlag(task, "deps", deps)
+
+ for task in mergedtasks[:-1]:
+ deps = d.getVarFlag(task, "deps")
+ for deltask in deltasks:
+ if deltask in deps:
+ deps.remove(deltask)
+ d.setVarFlag(task, "deps", deps)
+
+ # Pull cross recipe task deps over
+ depends = (d.getVarFlag(task, "depends") or ""
+ for task in mergedtasks[:-1]
+ if not task in deltasks)
+ d.setVarFlag("do_populate_staging", "depends", " ".join(depends))
+
+python () {
+ merge_tasks(d)
+}
+
+# Manually run do_install & all of its deps, then do_stage
+python do_populate_staging () {
+ from os.path import exists
+ from bb.build import exec_task, exec_func
+ from bb import note
+
+ stamp = d.getVar("STAMP", True)
+
+ def rec_exec_task(task, seen):
+ for dep in d.getVarFlag(task, "deps"):
+ if not dep in seen:
+ rec_exec_task(dep, seen)
+ seen.add(task)
+ #if not exists("%s.%s" % (stamp, task)):
+ note("%s: executing task %s" % (d.getVar("PF", True), task))
+ exec_task(task, d)
+
+ rec_exec_task("do_install", set())
+ exec_func("do_stage", d)
+}
+do_populate_staging[lockfiles] += "${S}/.lock"
diff --git a/classes/task-metadata-track.bbclass b/classes/task-metadata-track.bbclass
new file mode 100644
index 0000000000..d3622aef68
--- /dev/null
+++ b/classes/task-metadata-track.bbclass
@@ -0,0 +1,96 @@
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# This class uses events to capture the state of the datastore when the task
+# starts, and after it completes. It diffs those captured states, and emits
+# messages showing which variables changed, and what their values were changed
+# to.
+#
+# It provides a mechanism to blacklist variables you expect to change, both
+# globally and on a per-task basis.
+#
+# Known instances of tasks changing metadata:
+#
+# PSTAGE_PKGMANAGER changes by calls to pstage_set_pkgmanager in:
+# do_clean, do_setscene, do_package_stage
+#
+# Subpackage metadata, read by the pkgdata functions in base.bbclass, in:
+# do_package, do_package_stage, do_package_write_*
+
+
+TASK_METADATA_BLACKLIST = "\
+ __RUNQUEUE_DO_NOT_USE_EXTERNALLY \
+"
+
+#TASK_METADATA_BLACKLIST_do_clean = "\
+# PSTAGE_PKGMANAGER \
+#"
+
+
+def dict_diff(olddict, newdict):
+ diff = {}
+ for key in set(olddict).union(set(newdict)):
+ old = olddict.get(key)
+ new = newdict.get(key)
+ if old != new:
+ diff[key] = (old, new)
+
+ return diff
+
+def dict_for_data(data):
+ newdict = {}
+ for key in data.keys():
+ newdict[key] = data.getVar(key, False)
+ return newdict
+
+def task_metadata_track_start(task, data):
+ originaldata = dict_for_data(data)
+ data.setVar("__originaldata_%s" % task, originaldata)
+
+def task_metadata_track_stop(task, data):
+ from bb import note
+
+ pf = data.getVar("PF", True)
+ def emit(msg):
+ note("%s: %s" % (pf, msg))
+
+ originaldata = data.getVar("__originaldata_%s" % task, False)
+ newdata = dict_for_data(data)
+ blacklist = data.getVar("TASK_METADATA_BLACKLIST", True).split() + \
+ (data.getVar("TASK_METADATA_BLACKLIST_%s" % task, True) or "").split()
+
+ diff = dict_diff(originaldata, newdata)
+ diff_clean = [key for key in diff \
+ if not key in blacklist and \
+ not key.startswith("__originaldata_")]
+
+ if diff_clean:
+ emit("Variables changed by %s:" % task)
+ for key in diff_clean:
+ (old, new) = diff[key]
+ emit(" %s:" % key)
+ emit(" '%s' -> '%s'" % (old, new))
+
+python __task_metadata_track_eh () {
+ from bb.build import TaskStarted, TaskSucceeded
+
+ if isinstance(e, TaskStarted):
+ if e.data is None:
+ from bb import fatal
+ fatal("e.data is none for %s" % e)
+ task_metadata_track_start(e.task, e.data)
+ elif isinstance(e, TaskSucceeded):
+ task_metadata_track_stop(e.task, e.data)
+}
+addhandler __task_metadata_track_eh
+
+addtask py_listtasks
+do_py_listtasks[nostamp] = "1"
+do_py_listtasks[recrdeptask] = "do_py_listtasks"
+python do_py_listtasks() {
+ import sys
+ for e in d.keys():
+ if d.getVarFlag(e, "task") and \
+ d.getVarFlag(e, "python"):
+ sys.stdout.write("%s\n" % e)
+}