[oe-commits] Joshua Lock : relocatable: Class to post-process packages for relocatability

git version control git at git.openembedded.org
Wed May 5 23:34:45 UTC 2010


Module: openembedded.git
Branch: org.openembedded.dev
Commit: d1a8b276c0f7c2838816071bca797bb56fcccef7
URL:    http://gitweb.openembedded.net/?p=openembedded.git&a=commit;h=d1a8b276c0f7c2838816071bca797bb56fcccef7

Author: Joshua Lock <josh at linux.intel.com>
Date:   Wed Mar 31 11:41:58 2010 +0100

relocatable: Class to post-process packages for relocatability

This class helps make packages relocatable by post-processing the binaries and
using chrpath to set the RPATH relative to $ORIGIN.

Patch also enables this post-processing for native packages and adds chrpath to
the required utilties.

Based on ideas from a patch from Tom Rini <tom_rini at mentor.com>

Signed-off-by: Joshua Lock <josh at linux.intel.com>

---

 classes/cross.bbclass       |    3 ++
 classes/native.bbclass      |    3 ++
 classes/relocatable.bbclass |   79 +++++++++++++++++++++++++++++++++++++++++++
 classes/sanity.bbclass      |    2 +-
 4 files changed, 86 insertions(+), 1 deletions(-)

diff --git a/classes/cross.bbclass b/classes/cross.bbclass
index 6037d69..57b6e60 100644
--- a/classes/cross.bbclass
+++ b/classes/cross.bbclass
@@ -1,3 +1,6 @@
+# Disabled for now since the relocation paths are too long
+#inherit relocatable
+
 # Cross packages are built indirectly via dependency,
 # no need for them to be a direct target of 'world'
 EXCLUDE_FROM_WORLD = "1"
diff --git a/classes/native.bbclass b/classes/native.bbclass
index 6698b61..0381e83 100644
--- a/classes/native.bbclass
+++ b/classes/native.bbclass
@@ -1,3 +1,6 @@
+# We want native packages to be relocatable
+inherit relocatable
+
 # Native packages are built indirectly via dependency,
 # no need for them to be a direct target of 'world'
 EXCLUDE_FROM_WORLD = "1"
diff --git a/classes/relocatable.bbclass b/classes/relocatable.bbclass
new file mode 100644
index 0000000..25eb99e
--- /dev/null
+++ b/classes/relocatable.bbclass
@@ -0,0 +1,79 @@
+SYSROOT_PREPROCESS_FUNCS += "relocatable_binaries_preprocess"
+
+CHRPATH_BIN ?= "chrpath"
+PREPROCESS_RELOCATE_DIRS ?= ""
+
+def process_dir (directory, d):
+    import subprocess as sub
+
+    cmd = bb.data.expand('${CHRPATH_BIN}', d)
+    tmpdir = bb.data.getVar('TMPDIR', d)
+    basedir = bb.data.expand('${base_prefix}', d)
+
+    bb.debug("Checking %s for binaries to process" % directory)
+    if not os.path.exists(directory):
+        return
+
+    dirs = os.listdir(directory)
+    for file in dirs:
+        fpath = directory + "/" + file
+        if os.path.islink(fpath):
+            fpath = os.readlink(fpath)
+            if not os.path.isabs(fpath):
+                fpath = os.path.normpath(os.path.join(directory, fpath))
+
+        if os.path.isdir(fpath):
+            process_dir(fpath, d)
+        else:
+            #bb.note("Testing %s for relocatability" % fpath)
+            p = sub.Popen([cmd, '-l', fpath],stdout=sub.PIPE,stderr=sub.PIPE)
+            err, out = p.communicate()
+            # If returned succesfully, process stderr for results
+            if p.returncode != 0:
+                continue
+
+            # Throw away everything other than the rpath list
+            curr_rpath = err.partition("RPATH=")[2]
+            #bb.note("Current rpath for %s is %s" % (fpath, curr_rpath.strip()))
+            rpaths = curr_rpath.split(":")
+            new_rpaths = []
+            for rpath in rpaths:
+                # If rpath is already dynamic continue
+                if rpath.find("$ORIGIN") != -1:
+                    continue
+                # If the rpath shares a root with base_prefix determine a new dynamic rpath from the
+                # base_prefix shared root
+                if rpath.find(basedir) != -1:
+                    depth = fpath.partition(basedir)[2].count('/')
+                    libpath = rpath.partition(basedir)[2].strip()
+                # otherwise (i.e. cross packages) determine a shared root based on the TMPDIR
+                # NOTE: This will not work reliably for cross packages, particularly in the case
+                # where your TMPDIR is a short path (i.e. /usr/poky) as chrpath cannot insert an
+                # rpath longer than that which is already set.
+                else:
+                    depth = fpath.rpartition(tmpdir)[2].count('/')
+                    libpath = rpath.partition(tmpdir)[2].strip()
+
+                base = "$ORIGIN"
+                while depth > 1:
+                    base += "/.."
+                    depth-=1
+                new_rpaths.append("%s%s" % (base, libpath))
+
+            # if we have modified some rpaths call chrpath to update the binary
+            if len(new_rpaths):
+                args = ":".join(new_rpaths)
+                #bb.note("Setting rpath to " + args)
+                sub.call([cmd, '-r', args, fpath])
+
+def rpath_replace (path, d):
+    bindirs = bb.data.expand("${bindir} ${sbindir} ${base_sbindir} ${base_bindir} ${libdir} ${base_libdir} ${PREPROCESS_RELOCATE_DIRS}", d).split()
+
+    for bindir in bindirs:
+        bb.note ("Processing directory " + bindir)
+        directory = path + "/" + bindir
+        process_dir (directory, d)
+
+python relocatable_binaries_preprocess() {
+    rpath_replace(bb.data.expand('${SYSROOT_DESTDIR}', d), d)
+}
diff --git a/classes/sanity.bbclass b/classes/sanity.bbclass
index 2e9151f..0a1e868 100644
--- a/classes/sanity.bbclass
+++ b/classes/sanity.bbclass
@@ -83,7 +83,7 @@ def check_sanity(e):
 	if not check_app_exists('${BUILD_PREFIX}g++', e.data):
 		missing = missing + "C++ Compiler (${BUILD_PREFIX}g++),"
 
-	required_utilities = "patch help2man diffstat texi2html makeinfo cvs svn bzip2 tar gzip gawk md5sum"
+	required_utilities = "patch help2man diffstat texi2html makeinfo cvs svn bzip2 tar gzip gawk md5sum chrpath"
 
 	# If we'll be running qemu, perform some sanity checks
 	if data.getVar('ENABLE_BINARY_LOCALE_GENERATION', e.data, True):





More information about the Openembedded-commits mailing list