SYSROOT_PREPROCESS_FUNCS += "relocatable_binaries_preprocess" CHRPATH_BIN ?= "chrpath" PREPROCESS_RELOCATE_DIRS ?= "" def process_dir (directory, d): import subprocess as sub import stat 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 fpath = os.path.normpath(fpath) if os.path.islink(fpath): # Skip symlinks continue if os.path.isdir(fpath): process_dir(fpath, d) else: #bb.note("Testing %s for relocatability" % fpath) # We need read and write permissions for chrpath, if we don't have # them then set them temporarily. Take a copy of the files # permissions so that we can restore them afterwards. perms = os.stat(fpath)[stat.ST_MODE] if os.access(fpath, os.W_OK|os.R_OK): perms = None else: # Temporarily make the file writeable so we can chrpath it os.chmod(fpath, perms|stat.S_IRWXU) 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 for %s to %s" %(fpath, args)) sub.call([cmd, '-r', args, fpath]) if perms: os.chmod(fpath, perms) def rpath_replace (path, d): bindirs = bb.data.expand("${bindir} ${sbindir} ${base_sbindir} ${base_bindir} ${libdir} ${base_libdir} ${libexecdir} ${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) } href='#n11'>11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202