diff options
| -rw-r--r-- | meta/classes/chrpath.bbclass | 89 | ||||
| -rw-r--r-- | meta/classes/relocatable.bbclass | 91 |
2 files changed, 91 insertions, 89 deletions
diff --git a/meta/classes/chrpath.bbclass b/meta/classes/chrpath.bbclass new file mode 100644 index 0000000000..10b5ca0180 --- /dev/null +++ b/meta/classes/chrpath.bbclass | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | CHRPATH_BIN ?= "chrpath" | ||
| 2 | PREPROCESS_RELOCATE_DIRS ?= "" | ||
| 3 | |||
| 4 | def process_dir (directory, d): | ||
| 5 | import subprocess as sub | ||
| 6 | import stat | ||
| 7 | |||
| 8 | cmd = d.expand('${CHRPATH_BIN}') | ||
| 9 | tmpdir = d.getVar('TMPDIR') | ||
| 10 | basedir = d.expand('${base_prefix}') | ||
| 11 | |||
| 12 | #bb.debug("Checking %s for binaries to process" % directory) | ||
| 13 | if not os.path.exists(directory): | ||
| 14 | return | ||
| 15 | |||
| 16 | dirs = os.listdir(directory) | ||
| 17 | for file in dirs: | ||
| 18 | fpath = directory + "/" + file | ||
| 19 | fpath = os.path.normpath(fpath) | ||
| 20 | if os.path.islink(fpath): | ||
| 21 | # Skip symlinks | ||
| 22 | continue | ||
| 23 | |||
| 24 | if os.path.isdir(fpath): | ||
| 25 | process_dir(fpath, d) | ||
| 26 | else: | ||
| 27 | #bb.note("Testing %s for relocatability" % fpath) | ||
| 28 | |||
| 29 | # We need read and write permissions for chrpath, if we don't have | ||
| 30 | # them then set them temporarily. Take a copy of the files | ||
| 31 | # permissions so that we can restore them afterwards. | ||
| 32 | perms = os.stat(fpath)[stat.ST_MODE] | ||
| 33 | if os.access(fpath, os.W_OK|os.R_OK): | ||
| 34 | perms = None | ||
| 35 | else: | ||
| 36 | # Temporarily make the file writeable so we can chrpath it | ||
| 37 | os.chmod(fpath, perms|stat.S_IRWXU) | ||
| 38 | |||
| 39 | p = sub.Popen([cmd, '-l', fpath],stdout=sub.PIPE,stderr=sub.PIPE) | ||
| 40 | err, out = p.communicate() | ||
| 41 | # If returned succesfully, process stderr for results | ||
| 42 | if p.returncode != 0: | ||
| 43 | continue | ||
| 44 | |||
| 45 | # Throw away everything other than the rpath list | ||
| 46 | curr_rpath = err.partition("RPATH=")[2] | ||
| 47 | #bb.note("Current rpath for %s is %s" % (fpath, curr_rpath.strip())) | ||
| 48 | rpaths = curr_rpath.split(":") | ||
| 49 | new_rpaths = [] | ||
| 50 | for rpath in rpaths: | ||
| 51 | # If rpath is already dynamic continue | ||
| 52 | if rpath.find("$ORIGIN") != -1: | ||
| 53 | continue | ||
| 54 | # If the rpath shares a root with base_prefix determine a new dynamic rpath from the | ||
| 55 | # base_prefix shared root | ||
| 56 | if rpath.find(basedir) != -1: | ||
| 57 | depth = fpath.partition(basedir)[2].count('/') | ||
| 58 | libpath = rpath.partition(basedir)[2].strip() | ||
| 59 | # otherwise (i.e. cross packages) determine a shared root based on the TMPDIR | ||
| 60 | # NOTE: This will not work reliably for cross packages, particularly in the case | ||
| 61 | # where your TMPDIR is a short path (i.e. /usr/poky) as chrpath cannot insert an | ||
| 62 | # rpath longer than that which is already set. | ||
| 63 | else: | ||
| 64 | depth = fpath.rpartition(tmpdir)[2].count('/') | ||
| 65 | libpath = rpath.partition(tmpdir)[2].strip() | ||
| 66 | |||
| 67 | base = "$ORIGIN" | ||
| 68 | while depth > 1: | ||
| 69 | base += "/.." | ||
| 70 | depth-=1 | ||
| 71 | new_rpaths.append("%s%s" % (base, libpath)) | ||
| 72 | |||
| 73 | # if we have modified some rpaths call chrpath to update the binary | ||
| 74 | if len(new_rpaths): | ||
| 75 | args = ":".join(new_rpaths) | ||
| 76 | #bb.note("Setting rpath for %s to %s" %(fpath, args)) | ||
| 77 | sub.call([cmd, '-r', args, fpath]) | ||
| 78 | |||
| 79 | if perms: | ||
| 80 | os.chmod(fpath, perms) | ||
| 81 | |||
| 82 | def rpath_replace (path, d): | ||
| 83 | bindirs = d.expand("${bindir} ${sbindir} ${base_sbindir} ${base_bindir} ${libdir} ${base_libdir} ${libexecdir} ${PREPROCESS_RELOCATE_DIRS}").split() | ||
| 84 | |||
| 85 | for bindir in bindirs: | ||
| 86 | #bb.note ("Processing directory " + bindir) | ||
| 87 | directory = path + "/" + bindir | ||
| 88 | process_dir (directory, d) | ||
| 89 | |||
diff --git a/meta/classes/relocatable.bbclass b/meta/classes/relocatable.bbclass index 072f533f4f..4ca9981f44 100644 --- a/meta/classes/relocatable.bbclass +++ b/meta/classes/relocatable.bbclass | |||
| @@ -1,93 +1,6 @@ | |||
| 1 | SYSROOT_PREPROCESS_FUNCS += "relocatable_binaries_preprocess" | 1 | inherit chrpath |
| 2 | |||
| 3 | CHRPATH_BIN ?= "chrpath" | ||
| 4 | PREPROCESS_RELOCATE_DIRS ?= "" | ||
| 5 | |||
| 6 | def process_dir (directory, d): | ||
| 7 | import subprocess as sub | ||
| 8 | import stat | ||
| 9 | |||
| 10 | cmd = d.expand('${CHRPATH_BIN}') | ||
| 11 | tmpdir = d.getVar('TMPDIR') | ||
| 12 | basedir = d.expand('${base_prefix}') | ||
| 13 | |||
| 14 | #bb.debug("Checking %s for binaries to process" % directory) | ||
| 15 | if not os.path.exists(directory): | ||
| 16 | return | ||
| 17 | |||
| 18 | dirs = os.listdir(directory) | ||
| 19 | for file in dirs: | ||
| 20 | fpath = directory + "/" + file | ||
| 21 | fpath = os.path.normpath(fpath) | ||
| 22 | if os.path.islink(fpath): | ||
| 23 | # Skip symlinks | ||
| 24 | continue | ||
| 25 | |||
| 26 | if os.path.isdir(fpath): | ||
| 27 | process_dir(fpath, d) | ||
| 28 | else: | ||
| 29 | #bb.note("Testing %s for relocatability" % fpath) | ||
| 30 | |||
| 31 | # We need read and write permissions for chrpath, if we don't have | ||
| 32 | # them then set them temporarily. Take a copy of the files | ||
| 33 | # permissions so that we can restore them afterwards. | ||
| 34 | perms = os.stat(fpath)[stat.ST_MODE] | ||
| 35 | if os.access(fpath, os.W_OK|os.R_OK): | ||
| 36 | perms = None | ||
| 37 | else: | ||
| 38 | # Temporarily make the file writeable so we can chrpath it | ||
| 39 | os.chmod(fpath, perms|stat.S_IRWXU) | ||
| 40 | 2 | ||
| 41 | p = sub.Popen([cmd, '-l', fpath],stdout=sub.PIPE,stderr=sub.PIPE) | 3 | SYSROOT_PREPROCESS_FUNCS += "relocatable_binaries_preprocess" |
| 42 | err, out = p.communicate() | ||
| 43 | # If returned succesfully, process stderr for results | ||
| 44 | if p.returncode != 0: | ||
| 45 | continue | ||
| 46 | |||
| 47 | # Throw away everything other than the rpath list | ||
| 48 | curr_rpath = err.partition("RPATH=")[2] | ||
| 49 | #bb.note("Current rpath for %s is %s" % (fpath, curr_rpath.strip())) | ||
| 50 | rpaths = curr_rpath.split(":") | ||
| 51 | new_rpaths = [] | ||
| 52 | for rpath in rpaths: | ||
| 53 | # If rpath is already dynamic continue | ||
| 54 | if rpath.find("$ORIGIN") != -1: | ||
| 55 | continue | ||
| 56 | # If the rpath shares a root with base_prefix determine a new dynamic rpath from the | ||
| 57 | # base_prefix shared root | ||
| 58 | if rpath.find(basedir) != -1: | ||
| 59 | depth = fpath.partition(basedir)[2].count('/') | ||
| 60 | libpath = rpath.partition(basedir)[2].strip() | ||
| 61 | # otherwise (i.e. cross packages) determine a shared root based on the TMPDIR | ||
| 62 | # NOTE: This will not work reliably for cross packages, particularly in the case | ||
| 63 | # where your TMPDIR is a short path (i.e. /usr/poky) as chrpath cannot insert an | ||
| 64 | # rpath longer than that which is already set. | ||
| 65 | else: | ||
| 66 | depth = fpath.rpartition(tmpdir)[2].count('/') | ||
| 67 | libpath = rpath.partition(tmpdir)[2].strip() | ||
| 68 | |||
| 69 | base = "$ORIGIN" | ||
| 70 | while depth > 1: | ||
| 71 | base += "/.." | ||
| 72 | depth-=1 | ||
| 73 | new_rpaths.append("%s%s" % (base, libpath)) | ||
| 74 | |||
| 75 | # if we have modified some rpaths call chrpath to update the binary | ||
| 76 | if len(new_rpaths): | ||
| 77 | args = ":".join(new_rpaths) | ||
| 78 | #bb.note("Setting rpath for %s to %s" %(fpath, args)) | ||
| 79 | sub.call([cmd, '-r', args, fpath]) | ||
| 80 | |||
| 81 | if perms: | ||
| 82 | os.chmod(fpath, perms) | ||
| 83 | |||
| 84 | def rpath_replace (path, d): | ||
| 85 | bindirs = d.expand("${bindir} ${sbindir} ${base_sbindir} ${base_bindir} ${libdir} ${base_libdir} ${libexecdir} ${PREPROCESS_RELOCATE_DIRS}").split() | ||
| 86 | |||
| 87 | for bindir in bindirs: | ||
| 88 | #bb.note ("Processing directory " + bindir) | ||
| 89 | directory = path + "/" + bindir | ||
| 90 | process_dir (directory, d) | ||
| 91 | 4 | ||
| 92 | python relocatable_binaries_preprocess() { | 5 | python relocatable_binaries_preprocess() { |
| 93 | rpath_replace(d.expand('${SYSROOT_DESTDIR}'), d) | 6 | rpath_replace(d.expand('${SYSROOT_DESTDIR}'), d) |
