diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-11-26 22:14:47 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-11-29 09:52:57 +0000 |
commit | 6fcb96076ca60ef30062fda0ff8308cc840ab07d (patch) | |
tree | 4848a18b376e0d066196ad4cb1486ccc30f31a89 /meta/classes/chrpath.bbclass | |
parent | 572a8eb87489d549fff33d85a3760949730978eb (diff) | |
download | poky-6fcb96076ca60ef30062fda0ff8308cc840ab07d.tar.gz |
chrpath: Improve crazy code
The current code is a little bit overcomplicated, deficient and also
possibly broken.
Issues include:
a) Not maximally optisming rpaths (e.g. a lib in usr/lib might get an
rpath of $ORIGIN/../../usr/lib)
b) The return in the middle of the for loop look suspiciously like
it might break on some binaries
c) The depth function, loops of "../" prepending and so on can
be replaced with a call to os.path.relpath
This patch cleans up the above issues.
Running binaries should result in less "../" resolutions which can't
hurt performance either.
[YOCTO #3989]
(From OE-Core rev: feea54df6768036649ca6c57524e2a1f480ad249)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes/chrpath.bbclass')
-rw-r--r-- | meta/classes/chrpath.bbclass | 54 |
1 files changed, 17 insertions, 37 deletions
diff --git a/meta/classes/chrpath.bbclass b/meta/classes/chrpath.bbclass index 61a24b3f5a..7bdb1b9938 100644 --- a/meta/classes/chrpath.bbclass +++ b/meta/classes/chrpath.bbclass | |||
@@ -1,7 +1,7 @@ | |||
1 | CHRPATH_BIN ?= "chrpath" | 1 | CHRPATH_BIN ?= "chrpath" |
2 | PREPROCESS_RELOCATE_DIRS ?= "" | 2 | PREPROCESS_RELOCATE_DIRS ?= "" |
3 | 3 | ||
4 | def process_file_linux(cmd, fpath, basedir, tmpdir, d): | 4 | def process_file_linux(cmd, fpath, rootdir, baseprefix, tmpdir, d): |
5 | import subprocess as sub | 5 | import subprocess as sub |
6 | 6 | ||
7 | p = sub.Popen([cmd, '-l', fpath],stdout=sub.PIPE,stderr=sub.PIPE) | 7 | p = sub.Popen([cmd, '-l', fpath],stdout=sub.PIPE,stderr=sub.PIPE) |
@@ -15,35 +15,21 @@ def process_file_linux(cmd, fpath, basedir, tmpdir, d): | |||
15 | #bb.note("Current rpath for %s is %s" % (fpath, curr_rpath.strip())) | 15 | #bb.note("Current rpath for %s is %s" % (fpath, curr_rpath.strip())) |
16 | rpaths = curr_rpath.split(":") | 16 | rpaths = curr_rpath.split(":") |
17 | new_rpaths = [] | 17 | new_rpaths = [] |
18 | modified = False | ||
18 | for rpath in rpaths: | 19 | for rpath in rpaths: |
19 | # If rpath is already dynamic copy it to new_rpath and continue | 20 | # If rpath is already dynamic copy it to new_rpath and continue |
20 | if rpath.find("$ORIGIN") != -1: | 21 | if rpath.find("$ORIGIN") != -1: |
21 | new_rpaths.append(rpath.strip()) | 22 | new_rpaths.append(rpath.strip()) |
22 | continue | 23 | continue |
23 | rpath = os.path.normpath(rpath) | 24 | rpath = os.path.normpath(rpath) |
24 | # If the rpath shares a root with base_prefix determine a new dynamic rpath from the | 25 | if baseprefix not in rpath and tmpdir not in rpath: |
25 | # base_prefix shared root | ||
26 | if rpath.find(basedir) != -1: | ||
27 | depth = fpath.partition(basedir)[2].count('/') | ||
28 | libpath = rpath.partition(basedir)[2].strip() | ||
29 | # otherwise (i.e. cross packages) determine a shared root based on the TMPDIR | ||
30 | # NOTE: This will not work reliably for cross packages, particularly in the case | ||
31 | # where your TMPDIR is a short path (i.e. /usr/poky) as chrpath cannot insert an | ||
32 | # rpath longer than that which is already set. | ||
33 | elif rpath.find(tmpdir) != -1: | ||
34 | depth = fpath.rpartition(tmpdir)[2].count('/') | ||
35 | libpath = rpath.partition(tmpdir)[2].strip() | ||
36 | else: | ||
37 | new_rpaths.append(rpath.strip()) | 26 | new_rpaths.append(rpath.strip()) |
38 | return | 27 | continue |
39 | base = "$ORIGIN" | 28 | new_rpaths.append("$ORIGIN/" + os.path.relpath(rpath.strip(), os.path.dirname(fpath.replace(rootdir, "/")))) |
40 | while depth > 1: | 29 | modified = True |
41 | base += "/.." | ||
42 | depth-=1 | ||
43 | new_rpaths.append("%s%s" % (base, libpath)) | ||
44 | 30 | ||
45 | # if we have modified some rpaths call chrpath to update the binary | 31 | # if we have modified some rpaths call chrpath to update the binary |
46 | if len(new_rpaths): | 32 | if modified: |
47 | args = ":".join(new_rpaths) | 33 | args = ":".join(new_rpaths) |
48 | #bb.note("Setting rpath for %s to %s" %(fpath, args)) | 34 | #bb.note("Setting rpath for %s to %s" %(fpath, args)) |
49 | p = sub.Popen([cmd, '-r', args, fpath],stdout=sub.PIPE,stderr=sub.PIPE) | 35 | p = sub.Popen([cmd, '-r', args, fpath],stdout=sub.PIPE,stderr=sub.PIPE) |
@@ -52,7 +38,7 @@ def process_file_linux(cmd, fpath, basedir, tmpdir, d): | |||
52 | bb.error("%s: chrpath command failed with exit code %d:\n%s%s" % (d.getVar('PN', True), p.returncode, out, err)) | 38 | bb.error("%s: chrpath command failed with exit code %d:\n%s%s" % (d.getVar('PN', True), p.returncode, out, err)) |
53 | raise bb.build.FuncFailed | 39 | raise bb.build.FuncFailed |
54 | 40 | ||
55 | def process_file_darwin(cmd, fpath, basedir, tmpdir, d): | 41 | def process_file_darwin(cmd, fpath, rootdir, baseprefix, tmpdir, d): |
56 | import subprocess as sub | 42 | import subprocess as sub |
57 | 43 | ||
58 | p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-L', fpath],stdout=sub.PIPE,stderr=sub.PIPE) | 44 | p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-L', fpath],stdout=sub.PIPE,stderr=sub.PIPE) |
@@ -64,26 +50,20 @@ def process_file_darwin(cmd, fpath, basedir, tmpdir, d): | |||
64 | if "(compatibility" not in l: | 50 | if "(compatibility" not in l: |
65 | continue | 51 | continue |
66 | rpath = l.partition("(compatibility")[0].strip() | 52 | rpath = l.partition("(compatibility")[0].strip() |
67 | if rpath.find(basedir) != -1: | 53 | if baseprefix not in rpath: |
68 | depth = fpath.partition(basedir)[2].count('/') | ||
69 | libpath = rpath.partition(basedir)[2].strip() | ||
70 | else: | ||
71 | continue | 54 | continue |
72 | 55 | ||
73 | base = "@loader_path" | 56 | newpath = "@loader_path/" + os.path.relpath(rpath, os.path.dirname(fpath.replace(rootdir, "/"))) |
74 | while depth > 1: | 57 | bb.warn("%s %s %s %s" % (fpath, rpath, newpath, rootdir)) |
75 | base += "/.." | 58 | p = sub.Popen([d.expand("${HOST_PREFIX}install_name_tool"), '-change', rpath, newpath, fpath],stdout=sub.PIPE,stderr=sub.PIPE) |
76 | depth-=1 | ||
77 | base = base + libpath | ||
78 | p = sub.Popen([d.expand("${HOST_PREFIX}install_name_tool"), '-change', rpath, base, fpath],stdout=sub.PIPE,stderr=sub.PIPE) | ||
79 | err, out = p.communicate() | 59 | err, out = p.communicate() |
80 | 60 | ||
81 | def process_dir (directory, d): | 61 | def process_dir (rootdir, directory, d): |
82 | import stat | 62 | import stat |
83 | 63 | ||
84 | cmd = d.expand('${CHRPATH_BIN}') | 64 | cmd = d.expand('${CHRPATH_BIN}') |
85 | tmpdir = os.path.normpath(d.getVar('TMPDIR')) | 65 | tmpdir = os.path.normpath(d.getVar('TMPDIR')) |
86 | basedir = os.path.normpath(d.expand('${base_prefix}')) | 66 | baseprefix = os.path.normpath(d.expand('${base_prefix}')) |
87 | hostos = d.getVar("HOST_OS", True) | 67 | hostos = d.getVar("HOST_OS", True) |
88 | 68 | ||
89 | #bb.debug("Checking %s for binaries to process" % directory) | 69 | #bb.debug("Checking %s for binaries to process" % directory) |
@@ -107,7 +87,7 @@ def process_dir (directory, d): | |||
107 | continue | 87 | continue |
108 | 88 | ||
109 | if os.path.isdir(fpath): | 89 | if os.path.isdir(fpath): |
110 | process_dir(fpath, d) | 90 | process_dir(rootdir, fpath, d) |
111 | else: | 91 | else: |
112 | #bb.note("Testing %s for relocatability" % fpath) | 92 | #bb.note("Testing %s for relocatability" % fpath) |
113 | 93 | ||
@@ -120,7 +100,7 @@ def process_dir (directory, d): | |||
120 | else: | 100 | else: |
121 | # Temporarily make the file writeable so we can chrpath it | 101 | # Temporarily make the file writeable so we can chrpath it |
122 | os.chmod(fpath, perms|stat.S_IRWXU) | 102 | os.chmod(fpath, perms|stat.S_IRWXU) |
123 | process_file(cmd, fpath, basedir, tmpdir, d) | 103 | process_file(cmd, fpath, rootdir, baseprefix, tmpdir, d) |
124 | 104 | ||
125 | if perms: | 105 | if perms: |
126 | os.chmod(fpath, perms) | 106 | os.chmod(fpath, perms) |
@@ -131,5 +111,5 @@ def rpath_replace (path, d): | |||
131 | for bindir in bindirs: | 111 | for bindir in bindirs: |
132 | #bb.note ("Processing directory " + bindir) | 112 | #bb.note ("Processing directory " + bindir) |
133 | directory = path + "/" + bindir | 113 | directory = path + "/" + bindir |
134 | process_dir (directory, d) | 114 | process_dir (path, directory, d) |
135 | 115 | ||