package_ipk.bbclass: use common function to write relationship fields
[openembedded.git] / classes / package.bbclass
index a12bfb0..662b0db 100644 (file)
@@ -2,7 +2,14 @@
 # General packaging help functions
 #
 
-PKGDEST = "${WORKDIR}/install"
+PKGD    = "${WORKDIR}/package"
+PKGDEST = "${WORKDIR}/packages-split"
+
+PKGV   ?= "${PV}"
+PKGR   ?= "${PR}${DISTRO_PR}"
+
+EXTENDPKGEVER = "${@['','${PKGE\x7d:'][bb.data.getVar('PKGE',d,1) > 0]}"
+EXTENDPKGV ?= "${EXTENDPKGEVER}${PKGV}-${PKGR}"
 
 def legitimize_package_name(s):
        """
@@ -26,14 +33,10 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
        Used in .bb files to split up dynamically generated subpackages of a 
        given package, usually plugins or modules.
        """
-       import os, os.path, bb
 
-       dvar = bb.data.getVar('D', d, 1)
-       if not dvar:
-               bb.error("D not defined")
-               return
+       dvar = bb.data.getVar('PKGD', d, True)
 
-       packages = bb.data.getVar('PACKAGES', d, 1).split()
+       packages = bb.data.getVar('PACKAGES', d, True).split()
 
        if postinst:
                postinst = '#!/bin/sh\n' + postinst + '\n'
@@ -94,7 +97,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
                                        the_files.append(aux_files_pattern_verbatim % m.group(1))
                        bb.data.setVar('FILES_' + pkg, " ".join(the_files), d)
                        if extra_depends != '':
-                               the_depends = bb.data.getVar('RDEPENDS_' + pkg, d, 1)
+                               the_depends = bb.data.getVar('RDEPENDS_' + pkg, d, True)
                                if the_depends:
                                        the_depends = '%s %s' % (the_depends, extra_depends)
                                else:
@@ -106,7 +109,7 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst
                        if postrm:
                                bb.data.setVar('pkg_postrm_' + pkg, postrm, d)
                else:
-                       oldfiles = bb.data.getVar('FILES_' + pkg, d, 1)
+                       oldfiles = bb.data.getVar('FILES_' + pkg, d, True)
                        if not oldfiles:
                                bb.fatal("Package '%s' exists but has no files" % pkg)
                        bb.data.setVar('FILES_' + pkg, oldfiles + " " + os.path.join(root, o), d)
@@ -132,7 +135,6 @@ def package_stash_hook(func, name, d):
        f.close()
 
 python () {
-    import bb
     if bb.data.getVar('PACKAGES', d, True) != '':
         deps = bb.data.getVarFlag('do_package', 'depends', d) or ""
         for dep in (bb.data.getVar('PACKAGE_DEPENDS', d, True) or "").split():
@@ -150,9 +152,9 @@ def runstrip(file, d):
     # A working 'file' (one which works on the target architecture)
     # is necessary for this stuff to work, hence the addition to do_package[depends]
 
-    import bb, os, commands, stat
+    import commands, stat
 
-    pathprefix = "export PATH=%s; " % bb.data.getVar('PATH', d, 1)
+    pathprefix = "export PATH=%s; " % bb.data.getVar('PATH', d, True)
 
     ret, result = commands.getstatusoutput("%sfile '%s'" % (pathprefix, file))
 
@@ -166,11 +168,11 @@ def runstrip(file, d):
     # If the file is in a .debug directory it was already stripped,
     # don't do it again...
     if os.path.dirname(file).endswith(".debug"):
-        bb.note("Already ran strip")
+        bb.debug(2, "Already ran strip on %s" % file)
         return 0
 
-    strip = bb.data.getVar("STRIP", d, 1)
-    objcopy = bb.data.getVar("OBJCOPY", d, 1)
+    strip = bb.data.getVar("STRIP", d, True)
+    objcopy = bb.data.getVar("OBJCOPY", d, True)
 
     newmode = None
     if not os.access(file, os.W_OK):
@@ -183,6 +185,9 @@ def runstrip(file, d):
         extraflags = "--remove-section=.comment --remove-section=.note --strip-unneeded"
     elif "shared" in result or "executable" in result:
         extraflags = "--remove-section=.comment --remove-section=.note"
+    elif file.endswith(".a"):
+        extraflags = "--remove-section=.comment --strip-debug"
+
 
     bb.mkdirhier(os.path.join(os.path.dirname(file), ".debug"))
     debugfile=os.path.join(os.path.dirname(file), ".debug", os.path.basename(file))
@@ -202,13 +207,76 @@ def runstrip(file, d):
 
     return 1
 
+PACKAGESTRIPFUNCS += "do_runstrip"
+python do_runstrip() {
+       import stat
+
+       dvar = bb.data.getVar('PKGD', d, True)
+       def isexec(path):
+               try:
+                       s = os.stat(path)
+               except (os.error, AttributeError):
+                       return 0
+               return (s[stat.ST_MODE] & stat.S_IEXEC)
+
+       for root, dirs, files in os.walk(dvar):
+               for f in files:
+                       file = os.path.join(root, f)
+                       if not os.path.islink(file) and not os.path.isdir(file) and isexec(file):
+                               runstrip(file, d)
+}
+
+
+def write_package_md5sums (root, outfile, ignorepaths):
+    # For each regular file under root, writes an md5sum to outfile.
+    # With thanks to patch.bbclass.
+    import bb, os
+
+    try:
+        # Python 2.5+
+        import hashlib
+        ctor = hashlib.md5
+    except ImportError:
+        import md5
+        ctor = md5.new
+
+    outf = file(outfile, 'w')
+
+    # Each output line looks like: "<hex...>  <filename without leading slash>"
+    striplen = len(root)
+    if not root.endswith('/'):
+        striplen += 1
+
+    for walkroot, dirs, files in os.walk(root):
+        # Skip e.g. the DEBIAN directory
+        if walkroot[striplen:] in ignorepaths:
+            dirs[:] = []
+            continue
+
+        for name in files:
+            fullpath = os.path.join(walkroot, name)
+            if os.path.islink(fullpath) or (not os.path.isfile(fullpath)):
+                continue
+
+            m = ctor()
+            f = file(fullpath, 'rb')
+            while True:
+                d = f.read(8192)
+                if not d:
+                    break
+                m.update(d)
+            f.close()
+
+            print >> outf, "%s  %s" % (m.hexdigest(), fullpath[striplen:])
+
+    outf.close()
+
+
 #
 # Package data handling routines
 #
 
 def get_package_mapping (pkg, d):
-       import bb, os
-
        data = read_subpkgdata(pkg, d)
        key = "PKG_%s" % pkg
 
@@ -218,12 +286,10 @@ def get_package_mapping (pkg, d):
        return pkg
 
 def runtime_mapping_rename (varname, d):
-       import bb, os
-
-       #bb.note("%s before: %s" % (varname, bb.data.getVar(varname, d, 1)))    
+       #bb.note("%s before: %s" % (varname, bb.data.getVar(varname, d, True))) 
 
        new_depends = []
-       for depend in explode_deps(bb.data.getVar(varname, d, 1) or ""):
+       for depend in explode_deps(bb.data.getVar(varname, d, True) or ""):
                # Have to be careful with any version component of the depend
                split_depend = depend.split(' (')
                new_depend = get_package_mapping(split_depend[0].strip(), d)
@@ -234,35 +300,26 @@ def runtime_mapping_rename (varname, d):
 
        bb.data.setVar(varname, " ".join(new_depends) or None, d)
 
-       #bb.note("%s after: %s" % (varname, bb.data.getVar(varname, d, 1)))
+       #bb.note("%s after: %s" % (varname, bb.data.getVar(varname, d, True)))
 
 #
 # Package functions suitable for inclusion in PACKAGEFUNCS
 #
 
 python package_do_split_locales() {
-       import os
-
-       if (bb.data.getVar('PACKAGE_NO_LOCALE', d, 1) == '1'):
+       if (bb.data.getVar('PACKAGE_NO_LOCALE', d, True) == '1'):
                bb.debug(1, "package requested not splitting locales")
                return
 
-       packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
+       packages = (bb.data.getVar('PACKAGES', d, True) or "").split()
 
-       datadir = bb.data.getVar('datadir', d, 1)
+       datadir = bb.data.getVar('datadir', d, True)
        if not datadir:
                bb.note("datadir not defined")
                return
 
-       dvar = bb.data.getVar('D', d, 1)
-       if not dvar:
-               bb.error("D not defined")
-               return
-
-       pn = bb.data.getVar('PN', d, 1)
-       if not pn:
-               bb.error("PN not defined")
-               return
+       dvar = bb.data.getVar('PKGD', d, True)
+       pn = bb.data.getVar('PN', d, True)
 
        if pn + '-locale' in packages:
                packages.remove(pn + '-locale')
@@ -293,54 +350,31 @@ python package_do_split_locales() {
                bb.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d)
 
        bb.data.setVar('PACKAGES', ' '.join(packages), d)
-
-       # Disabled by RP 18/06/07
-       # Wildcards aren't supported in debian
-       # They break with ipkg since glibc-locale* will mean that 
-       # glibc-localedata-translit* won't install as a dependency
-       # for some other package which breaks meta-toolchain
-       # Probably breaks since virtual-locale- isn't provided anywhere
-       #rdep = (bb.data.getVar('RDEPENDS_%s' % mainpkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "").split()
-       #rdep.append('%s-locale*' % pn)
-       #bb.data.setVar('RDEPENDS_%s' % mainpkg, ' '.join(rdep), d)
 }
 
-python populate_packages () {
-       import glob, stat, errno, re
-
-       workdir = bb.data.getVar('WORKDIR', d, 1)
-       if not workdir:
-               bb.error("WORKDIR not defined, unable to package")
-               return
-
-       import os # path manipulations
-       outdir = bb.data.getVar('DEPLOY_DIR', d, 1)
-       if not outdir:
-               bb.error("DEPLOY_DIR not defined, unable to package")
-               return
-       bb.mkdirhier(outdir)
+python perform_packagecopy () {
+       dest = bb.data.getVar('D', d, True)
+       dvar = bb.data.getVar('PKGD', d, True)
 
-       dvar = bb.data.getVar('D', d, 1)
-       if not dvar:
-               bb.error("D not defined, unable to package")
-               return
        bb.mkdirhier(dvar)
 
-       packages = bb.data.getVar('PACKAGES', d, 1)
+       # Start by package population by taking a copy of the installed 
+       # files to operate on
+       os.system('rm -rf %s/*' % (dvar))
+       os.system('cp -pPR %s/* %s/' % (dest, dvar))
+}
 
-       pn = bb.data.getVar('PN', d, 1)
-       if not pn:
-               bb.error("PN not defined")
-               return
+python populate_packages () {
+       import glob, errno, re,os
 
-       os.chdir(dvar)
+       workdir = bb.data.getVar('WORKDIR', d, True)
+       outdir = bb.data.getVar('DEPLOY_DIR', d, True)
+       dvar = bb.data.getVar('PKGD', d, True)
+       packages = bb.data.getVar('PACKAGES', d, True)
+       pn = bb.data.getVar('PN', d, True)
 
-       def isexec(path):
-               try:
-                       s = os.stat(path)
-               except (os.error, AttributeError):
-                       return 0
-               return (s[stat.ST_MODE] & stat.S_IEXEC)
+       bb.mkdirhier(outdir)
+       os.chdir(dvar)
 
        # Sanity check PACKAGES for duplicates - should be moved to 
        # sanity.bbclass once we have the infrastucture
@@ -354,19 +388,17 @@ python populate_packages () {
                else:
                        package_list.append(pkg)
 
-       if (bb.data.getVar('INHIBIT_PACKAGE_STRIP', d, 1) != '1'):
-               for root, dirs, files in os.walk(dvar):
-                       for f in files:
-                               file = os.path.join(root, f)
-                               if not os.path.islink(file) and not os.path.isdir(file) and isexec(file):
-                                       runstrip(file, d)
 
-       pkgdest = bb.data.getVar('PKGDEST', d, 1)
+       if (bb.data.getVar('INHIBIT_PACKAGE_STRIP', d, True) != '1'):
+               for f in (bb.data.getVar('PACKAGESTRIPFUNCS', d, True) or '').split():
+                       bb.build.exec_func(f, d)
+
+       pkgdest = bb.data.getVar('PKGDEST', d, True)
        os.system('rm -rf %s' % pkgdest)
 
        seen = []
        main_is_empty = 1
-       main_pkg = bb.data.getVar('PN', d, 1)
+       main_pkg = bb.data.getVar('PN', d, True)
 
        for pkg in package_list:
                localdata = bb.data.createCopy(d)
@@ -374,13 +406,13 @@ python populate_packages () {
                bb.mkdirhier(root)
 
                bb.data.setVar('PKG', pkg, localdata)
-               overrides = bb.data.getVar('OVERRIDES', localdata, 1)
+               overrides = bb.data.getVar('OVERRIDES', localdata, True)
                if not overrides:
                        raise bb.build.FuncFailed('OVERRIDES not defined')
                bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata)
                bb.data.update_data(localdata)
 
-               filesvar = bb.data.getVar('FILES', localdata, 1) or ""
+               filesvar = bb.data.getVar('FILES', localdata, True) or ""
                files = filesvar.split()
                for file in files:
                        if os.path.isabs(file):
@@ -394,8 +426,12 @@ python populate_packages () {
                        globbed = glob.glob(file)
                        if globbed:
                                if [ file ] != globbed:
-                                       files += globbed
-                                       continue
+                                       if not file in globbed:
+                                               files += globbed
+                                               continue
+                                       else:
+                                               globbed.remove(file)
+                                               files += globbed
                        if (not os.path.islink(file)) and (not os.path.exists(file)):
                                continue
                        if file in seen:
@@ -409,8 +445,8 @@ python populate_packages () {
                        dpath = os.path.dirname(fpath)
                        bb.mkdirhier(dpath)
                        ret = bb.copyfile(file, fpath)
-                       if ret is False or ret == 0:
-                               raise bb.build.FuncFailed("File population failed")
+                       if ret is False:
+                               raise bb.build.FuncFailed("File population failed when copying %s to %s" % (file, fpath))
                        if pkg == main_pkg and main_is_empty:
                                main_is_empty = 0
                del localdata
@@ -431,7 +467,7 @@ python populate_packages () {
        bb.build.exec_func("package_name_hook", d)
 
        for pkg in package_list:
-               pkgname = bb.data.getVar('PKG_%s' % pkg, d, 1)
+               pkgname = bb.data.getVar('PKG_%s' % pkg, d, True)
                if pkgname is None:
                        bb.data.setVar('PKG_%s' % pkg, pkg, d)
 
@@ -459,7 +495,7 @@ python populate_packages () {
        for pkg in package_list:
                rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "")
 
-               remstr = "${PN} (= ${DEBPV})"
+               remstr = "${PN} (= ${EXTENDPKGV})"
                if main_is_empty and remstr in rdepends:
                        rdepends.remove(remstr)
                for l in dangling_links[pkg]:
@@ -477,7 +513,7 @@ python populate_packages () {
                                                break
                        if found == False:
                                bb.note("%s contains dangling symlink to %s" % (pkg, l))
-               bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d)
+               bb.data.setVar('RDEPENDS_' + pkg, " ".join(rdepends), d)
 }
 populate_packages[dirs] = "${D}"
 
@@ -490,11 +526,17 @@ python emit_pkgdata() {
                        c = codecs.getencoder("string_escape")
                        return c(str)[0]
 
-               val = bb.data.getVar('%s_%s' % (var, pkg), d, 1)
+               val = bb.data.getVar('%s_%s' % (var, pkg), d, True)
                if val:
                        f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
+                       return
+               val = bb.data.getVar('%s' % (var), d, True)
+               if val:
+                       f.write('%s: %s\n' % (var, encode(val)))
+               return
 
        packages = bb.data.getVar('PACKAGES', d, True)
+       pkgdest = bb.data.getVar('PKGDEST', d, 1)
        pkgdatadir = bb.data.getVar('PKGDATA_DIR', d, True)
 
        pstageactive = bb.data.getVar('PSTAGING_ACTIVE', d, True)
@@ -507,13 +549,16 @@ python emit_pkgdata() {
        f.close()
        package_stagefile(data_file, d)
 
-       workdir = bb.data.getVar('WORKDIR', d, 1)
+       workdir = bb.data.getVar('WORKDIR', d, True)
 
        for pkg in packages.split():
                subdata_file = pkgdatadir + "/runtime/%s" % pkg
                sf = open(subdata_file, 'w')
                write_if_exists(sf, pkg, 'PN')
+               write_if_exists(sf, pkg, 'PV')
                write_if_exists(sf, pkg, 'PR')
+               write_if_exists(sf, pkg, 'PKGV')
+               write_if_exists(sf, pkg, 'PKGR')
                write_if_exists(sf, pkg, 'DESCRIPTION')
                write_if_exists(sf, pkg, 'RDEPENDS')
                write_if_exists(sf, pkg, 'RPROVIDES')
@@ -534,12 +579,12 @@ python emit_pkgdata() {
                #if pkgdatadir2:
                #       bb.copyfile(subdata_file, pkgdatadir2 + "/runtime/%s" % pkg)
 
-               allow_empty = bb.data.getVar('ALLOW_EMPTY_%s' % pkg, d, 1)
+               allow_empty = bb.data.getVar('ALLOW_EMPTY_%s' % pkg, d, True)
                if not allow_empty:
-                       allow_empty = bb.data.getVar('ALLOW_EMPTY', d, 1)
-               root = "%s/install/%s" % (workdir, pkg)
+                       allow_empty = bb.data.getVar('ALLOW_EMPTY', d, True)
+               root = "%s/%s" % (pkgdest, pkg)
                os.chdir(root)
-               g = glob('*')
+               g = glob('*') + glob('.[!.]*')
                if g or allow_empty == "1":
                        packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
                        file(packagedfile, 'w').close()
@@ -551,38 +596,37 @@ emit_pkgdata[dirs] = "${PKGDATA_DIR}/runtime"
 
 ldconfig_postinst_fragment() {
 if [ x"$D" = "x" ]; then
-       [ -x /sbin/ldconfig ] && /sbin/ldconfig
+       if [ -e /etc/ld.so.conf ] ; then
+               [ -x /sbin/ldconfig ] && /sbin/ldconfig
+       fi
 fi
 }
 
 SHLIBSDIR = "${STAGING_DIR_HOST}/shlibs"
 
 python package_do_shlibs() {
-       import os, re, os.path
+       import re
 
        exclude_shlibs = bb.data.getVar('EXCLUDE_FROM_SHLIBS', d, 0)
        if exclude_shlibs:
-               bb.note("not generating shlibs")
+               bb.debug(1, "not generating shlibs")
                return
                
        lib_re = re.compile("^lib.*\.so")
        libdir_re = re.compile(".*/lib$")
 
-       packages = bb.data.getVar('PACKAGES', d, 1)
+       packages = bb.data.getVar('PACKAGES', d, True)
 
-       workdir = bb.data.getVar('WORKDIR', d, 1)
-       if not workdir:
-               bb.error("WORKDIR not defined")
-               return
+       workdir = bb.data.getVar('WORKDIR', d, True)
 
-       ver = bb.data.getVar('PV', d, 1)
+       ver = bb.data.getVar('PKGV', d, True)
        if not ver:
-               bb.error("PV not defined")
+               bb.error("PKGV not defined")
                return
 
-       pkgdest = bb.data.getVar('PKGDEST', d, 1)
+       pkgdest = bb.data.getVar('PKGDEST', d, True)
 
-       shlibs_dir = bb.data.getVar('SHLIBSDIR', d, 1)
+       shlibs_dir = bb.data.getVar('SHLIBSDIR', d, True)
        bb.mkdirhier(shlibs_dir)
 
        pstageactive = bb.data.getVar('PSTAGING_ACTIVE', d, True)
@@ -594,12 +638,23 @@ python package_do_shlibs() {
        else:
                snap_symlinks = False
 
+       if (bb.data.getVar('USE_LDCONFIG', d, True) or "1") == "1":
+               use_ldconfig = True
+       else:
+               use_ldconfig = False
+
        needed = {}
-       private_libs = bb.data.getVar('PRIVATE_LIBS', d, 1)
+       private_libs = bb.data.getVar('PRIVATE_LIBS', d, True)
        for pkg in packages.split():
                needs_ldconfig = False
                bb.debug(2, "calculating shlib provides for %s" % pkg)
 
+               pkgver = bb.data.getVar('PKGV_' + pkg, d, True)
+               if not pkgver:
+                       pkgver = bb.data.getVar('PV_' + pkg, d, True)
+               if not pkgver:
+                       pkgver = ver
+
                needed[pkg] = []
                sonames = list()
                top = os.path.join(pkgdest, pkg)
@@ -608,9 +663,9 @@ python package_do_shlibs() {
                        for file in files:
                                soname = None
                                path = os.path.join(root, file)
-                               if os.access(path, os.X_OK) or lib_re.match(file):
-                                       cmd = bb.data.getVar('OBJDUMP', d, 1) + " -p " + path + " 2>/dev/null"
-                                       cmd = "PATH=\"%s\" %s" % (bb.data.getVar('PATH', d, 1), cmd)
+                               if (os.access(path, os.X_OK) or lib_re.match(file)) and not os.path.islink(path):
+                                       cmd = bb.data.getVar('OBJDUMP', d, True) + " -p " + path + " 2>/dev/null"
+                                       cmd = "PATH=\"%s\" %s" % (bb.data.getVar('PATH', d, True), cmd)
                                        fd = os.popen(cmd)
                                        lines = fd.readlines()
                                        fd.close()
@@ -644,15 +699,15 @@ python package_do_shlibs() {
                        fd.close()
                        package_stagefile(shlibs_file, d)
                        fd = open(shver_file, 'w')
-                       fd.write(ver + '\n')
+                       fd.write(pkgver + '\n')
                        fd.close()
                        package_stagefile(shver_file, d)
-               if needs_ldconfig:
+               if needs_ldconfig and use_ldconfig:
                        bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
-                       postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1)
+                       postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, True) or bb.data.getVar('pkg_postinst', d, True)
                        if not postinst:
                                postinst = '#!/bin/sh\n'
-                       postinst += bb.data.getVar('ldconfig_postinst_fragment', d, 1)
+                       postinst += bb.data.getVar('ldconfig_postinst_fragment', d, True)
                        bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d)
 
        if pstageactive == "1":
@@ -679,7 +734,7 @@ python package_do_shlibs() {
                                for l in lines:
                                        shlib_provider[l.rstrip()] = (dep_pkg, lib_ver)
 
-       assumed_libs = bb.data.getVar('ASSUME_SHLIBS', d, 1)
+       assumed_libs = bb.data.getVar('ASSUME_SHLIBS', d, True)
        if assumed_libs:
            for e in assumed_libs.split():
                l, dep_pkg = e.split(":")
@@ -725,18 +780,13 @@ python package_do_shlibs() {
 }
 
 python package_do_pkgconfig () {
-       import re, os
-
-       packages = bb.data.getVar('PACKAGES', d, 1)
-
-       workdir = bb.data.getVar('WORKDIR', d, 1)
-       if not workdir:
-               bb.error("WORKDIR not defined")
-               return
+       import re
 
-       pkgdest = bb.data.getVar('PKGDEST', d, 1)
+       packages = bb.data.getVar('PACKAGES', d, True)
+       workdir = bb.data.getVar('WORKDIR', d, True)
+       pkgdest = bb.data.getVar('PKGDEST', d, True)
 
-       shlibs_dir = bb.data.getVar('SHLIBSDIR', d, 1)
+       shlibs_dir = bb.data.getVar('SHLIBSDIR', d, True)
        bb.mkdirhier(shlibs_dir)
 
        pc_re = re.compile('(.*)\.pc$')
@@ -831,7 +881,7 @@ python package_do_pkgconfig () {
 }
 
 python read_shlibdeps () {
-       packages = bb.data.getVar('PACKAGES', d, 1).split()
+       packages = bb.data.getVar('PACKAGES', d, True).split()
        for pkg in packages:
                rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "")
                for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
@@ -842,7 +892,7 @@ python read_shlibdeps () {
                                fd.close()
                                for l in lines:
                                        rdepends.append(l.rstrip())
-               bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d)
+               bb.data.setVar('RDEPENDS_' + pkg, " ".join(rdepends), d)
 }
 
 python package_depchains() {
@@ -859,14 +909,14 @@ python package_depchains() {
        package.
        """
 
-       packages  = bb.data.getVar('PACKAGES', d, 1)
-       postfixes = (bb.data.getVar('DEPCHAIN_POST', d, 1) or '').split()
-       prefixes  = (bb.data.getVar('DEPCHAIN_PRE', d, 1) or '').split()
+       packages  = bb.data.getVar('PACKAGES', d, True)
+       postfixes = (bb.data.getVar('DEPCHAIN_POST', d, True) or '').split()
+       prefixes  = (bb.data.getVar('DEPCHAIN_PRE', d, True) or '').split()
 
        def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
 
                #bb.note('depends for %s is %s' % (base, depends))
-               rreclist = explode_deps(bb.data.getVar('RRECOMMENDS_' + pkg, d, 1) or bb.data.getVar('RRECOMMENDS', d, 1) or "")
+               rreclist = explode_deps(bb.data.getVar('RRECOMMENDS_' + pkg, d, True) or bb.data.getVar('RRECOMMENDS', d, True) or "")
 
                for depend in depends:
                        if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
@@ -887,7 +937,7 @@ python package_depchains() {
        def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
 
                #bb.note('rdepends for %s is %s' % (base, rdepends))
-               rreclist = explode_deps(bb.data.getVar('RRECOMMENDS_' + pkg, d, 1) or bb.data.getVar('RRECOMMENDS', d, 1) or "")
+               rreclist = explode_deps(bb.data.getVar('RRECOMMENDS_' + pkg, d, True) or bb.data.getVar('RRECOMMENDS', d, True) or "")
 
                for depend in rdepends:
                        if depend.endswith('-dev'):
@@ -907,15 +957,15 @@ python package_depchains() {
                        list.append(dep)
 
        depends = []
-       for dep in explode_deps(bb.data.getVar('DEPENDS', d, 1) or ""):
+       for dep in explode_deps(bb.data.getVar('DEPENDS', d, True) or ""):
                add_dep(depends, dep)
 
        rdepends = []
-       for dep in explode_deps(bb.data.getVar('RDEPENDS', d, 1) or ""):
+       for dep in explode_deps(bb.data.getVar('RDEPENDS', d, True) or ""):
                add_dep(rdepends, dep)
 
        for pkg in packages.split():
-               for dep in explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 1) or ""):
+               for dep in explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, True) or ""):
                        add_dep(rdepends, dep)
 
        #bb.note('rdepends is %s' % rdepends)
@@ -948,13 +998,15 @@ python package_depchains() {
                                pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
                        else:
                                rdeps = []
-                               for dep in explode_deps(bb.data.getVar('RDEPENDS_' + base, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or ""):
+                               for dep in explode_deps(bb.data.getVar('RDEPENDS_' + base, d, True) or bb.data.getVar('RDEPENDS', d, True) or ""):
                                        add_dep(rdeps, dep)
                                pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
 }
 
-
-PACKAGEFUNCS ?= "package_do_split_locales \
+PACKAGE_PREPROCESS_FUNCS ?= ""
+PACKAGEFUNCS ?= "perform_packagecopy \
+                ${PACKAGE_PREPROCESS_FUNCS} \
+               package_do_split_locales \
                populate_packages \
                package_do_shlibs \
                package_do_pkgconfig \
@@ -976,7 +1028,7 @@ def package_run_hooks(f, d):
                                bb.parse.parse_py.BBHandler.feeder(line, l, fn, os.path.basename(fn), d)
                                line += 1
                        fp.close()
-                       anonqueue = bb.data.getVar("__anonqueue", d, 1) or []
+                       anonqueue = bb.data.getVar("__anonqueue", d, True) or []
                        body = [x['content'] for x in anonqueue]
                        flag = { 'python' : 1, 'func' : 1 }
                        bb.data.setVar("__anonfunc", "\n".join(body), d)
@@ -995,12 +1047,22 @@ def package_run_hooks(f, d):
                        bb.data.delVar("__anonfunc", d)
 
 python package_do_package () {
-       packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
+       packages = (bb.data.getVar('PACKAGES', d, True) or "").split()
        if len(packages) < 1:
                bb.debug(1, "No packages to build, skipping do_package")
                return
 
-       for f in (bb.data.getVar('PACKAGEFUNCS', d, 1) or '').split():
+       workdir = bb.data.getVar('WORKDIR', d, True)
+       outdir = bb.data.getVar('DEPLOY_DIR', d, True)
+       dest = bb.data.getVar('D', d, True)
+       dvar = bb.data.getVar('PKGD', d, True)
+       pn = bb.data.getVar('PN', d, True)
+
+       if not workdir or not outdir or not dest or not dvar or not pn or not packages:
+               bb.error("WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package")
+               return
+
+       for f in (bb.data.getVar('PACKAGEFUNCS', d, True) or '').split():
                bb.build.exec_func(f, d)
                package_run_hooks(f, d)
 }