rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame] | 1 | inherit package |
| 2 | |
| 3 | def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d): |
| 4 | # Function to split a single file into two components, one is the stripped |
| 5 | # target system binary, the other contains any debugging information. The |
| 6 | # two files are linked to reference each other. |
| 7 | # |
| 8 | # sourcefile is also generated containing a list of debugsources |
| 9 | |
| 10 | import stat |
| 11 | import subprocess |
| 12 | |
| 13 | src = file[len(dvar):] |
| 14 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend |
| 15 | debugfile = dvar + dest |
| 16 | # Split the file... |
| 17 | bb.utils.mkdirhier(os.path.dirname(debugfile)) |
| 18 | #bb.note("Split %s -> %s" % (file, debugfile)) |
| 19 | # Only store off the hard link reference if we successfully split! |
| 20 | |
| 21 | dvar = d.getVar('PKGD') |
| 22 | objcopy = d.getVar("OBJCOPY") |
| 23 | |
| 24 | # We ignore kernel modules, we don't generate debug info files. |
| 25 | if file.find("/lib/modules/") != -1 and file.endswith(".ko"): |
| 26 | return 1 |
| 27 | |
| 28 | newmode = None |
| 29 | if os.path.exists(file): |
| 30 | if not os.access(file, os.W_OK) or os.access(file, os.R_OK): |
| 31 | origmode = os.stat(file)[stat.ST_MODE] |
| 32 | newmode = origmode | stat.S_IWRITE | stat.S_IREAD |
| 33 | os.chmod(file, newmode) |
| 34 | |
| 35 | # We need to extract the debug src information here... |
| 36 | if debugsrcdir: |
| 37 | append_source_info(file, sourcefile, d) |
| 38 | |
| 39 | bb.utils.mkdirhier(os.path.dirname(debugfile)) |
| 40 | |
| 41 | if os.path.basename(src) != "udevd" and os.path.basename(src) != "init": |
| 42 | subprocess.check_output([objcopy, file, debugfile], stderr=subprocess.STDOUT) |
| 43 | |
| 44 | # Set the debuglink to have the view of the file path on the target |
| 45 | if not cpath.islink(file): |
| 46 | subprocess.check_output([objcopy, '--add-gnu-debuglink', debugfile, file], stderr=subprocess.STDOUT) |
| 47 | |
| 48 | if newmode: |
| 49 | os.chmod(file, origmode) |
| 50 | |
| 51 | return 0 |
| 52 | |
| 53 | python split_and_strip_files () { |
| 54 | import stat, errno |
| 55 | import subprocess |
| 56 | |
| 57 | dvar = d.getVar('PKGD') |
| 58 | pn = d.getVar('PN') |
| 59 | targetos = d.getVar('TARGET_OS') |
| 60 | |
| 61 | oldcwd = os.getcwd() |
| 62 | os.chdir(dvar) |
| 63 | |
| 64 | # We default to '.debug' style |
| 65 | if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory': |
| 66 | # Single debug-file-directory style debug info |
| 67 | debugappend = ".debug" |
| 68 | debugdir = "" |
| 69 | debuglibdir = "/usr/lib/debug" |
| 70 | debugsrcdir = "/usr/src/debug" |
| 71 | elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src': |
| 72 | # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug |
| 73 | debugappend = "" |
| 74 | debugdir = "/.debug" |
| 75 | debuglibdir = "" |
| 76 | debugsrcdir = "" |
| 77 | elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg': |
| 78 | debugappend = "" |
| 79 | debugdir = "/.debug" |
| 80 | debuglibdir = "" |
| 81 | debugsrcdir = "/usr/src/debug" |
| 82 | else: |
| 83 | # Original OE-core, a.k.a. ".debug", style debug info |
| 84 | debugappend = "" |
| 85 | debugdir = "/.debug" |
| 86 | debuglibdir = "" |
| 87 | debugsrcdir = "/usr/src/debug" |
| 88 | |
| 89 | sourcefile = d.expand("${WORKDIR}/debugsources.list") |
| 90 | bb.utils.remove(sourcefile) |
| 91 | |
| 92 | # |
| 93 | # First lets figure out all of the files we may have to process ... do this only once! |
| 94 | # |
| 95 | elffiles = {} |
| 96 | symlinks = {} |
| 97 | kernmods = [] |
| 98 | staticlibs = [] |
| 99 | inodes = {} |
| 100 | libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir")) |
| 101 | baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir")) |
| 102 | skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split() |
| 103 | if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \ |
| 104 | d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'): |
| 105 | checkelf = {} |
| 106 | checkelflinks = {} |
| 107 | for root, dirs, files in cpath.walk(dvar): |
| 108 | for f in files: |
| 109 | file = os.path.join(root, f) |
| 110 | if file.endswith(".ko") and file.find("/lib/modules/") != -1: |
| 111 | kernmods.append(file) |
| 112 | continue |
| 113 | if oe.package.is_static_lib(file): |
| 114 | staticlibs.append(file) |
| 115 | continue |
| 116 | |
| 117 | # Skip debug files |
| 118 | if debugappend and file.endswith(debugappend): |
| 119 | continue |
| 120 | if debugdir and debugdir in os.path.dirname(file[len(dvar):]): |
| 121 | continue |
| 122 | |
| 123 | if file in skipfiles: |
| 124 | continue |
| 125 | |
| 126 | try: |
| 127 | ltarget = cpath.realpath(file, dvar, False) |
| 128 | s = cpath.lstat(ltarget) |
| 129 | except OSError as e: |
| 130 | (err, strerror) = e.args |
| 131 | if err != errno.ENOENT: |
| 132 | raise |
| 133 | # Skip broken symlinks |
| 134 | continue |
| 135 | if not s: |
| 136 | continue |
| 137 | # Check its an executable |
| 138 | if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) or (s[stat.ST_MODE] & stat.S_IXOTH) \ |
| 139 | or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)): |
| 140 | |
| 141 | if cpath.islink(file): |
| 142 | checkelflinks[file] = ltarget |
| 143 | continue |
| 144 | # Use a reference of device ID and inode number to identify files |
| 145 | file_reference = "%d_%d" % (s.st_dev, s.st_ino) |
| 146 | checkelf[file] = (file, file_reference) |
| 147 | |
| 148 | results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d) |
| 149 | results_map = {} |
| 150 | for (ltarget, elf_file) in results: |
| 151 | results_map[ltarget] = elf_file |
| 152 | for file in checkelflinks: |
| 153 | ltarget = checkelflinks[file] |
| 154 | # If it's a symlink, and points to an ELF file, we capture the readlink target |
| 155 | if results_map[ltarget]: |
| 156 | target = os.readlink(file) |
| 157 | #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget])) |
| 158 | symlinks[file] = target |
| 159 | |
| 160 | results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d) |
| 161 | for (file, elf_file) in results: |
| 162 | # It's a file (or hardlink), not a link |
| 163 | # ...but is it ELF, and is it already stripped? |
| 164 | if elf_file & 1: |
| 165 | if elf_file & 2: |
| 166 | if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split(): |
| 167 | bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn)) |
| 168 | else: |
| 169 | msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn) |
| 170 | package_qa_handle_error("already-stripped", msg, d) |
| 171 | continue |
| 172 | |
| 173 | # At this point we have an unstripped elf file. We need to: |
| 174 | # a) Make sure any file we strip is not hardlinked to anything else outside this tree |
| 175 | # b) Only strip any hardlinked file once (no races) |
| 176 | # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks |
| 177 | |
| 178 | # Use a reference of device ID and inode number to identify files |
| 179 | file_reference = checkelf[file][1] |
| 180 | if file_reference in inodes: |
| 181 | os.unlink(file) |
| 182 | os.link(inodes[file_reference][0], file) |
| 183 | inodes[file_reference].append(file) |
| 184 | else: |
| 185 | inodes[file_reference] = [file] |
| 186 | # break hardlink |
| 187 | bb.utils.break_hardlinks(file) |
| 188 | elffiles[file] = elf_file |
| 189 | # Modified the file so clear the cache |
| 190 | cpath.updatecache(file) |
| 191 | |
| 192 | # |
| 193 | # First lets process debug splitting |
| 194 | # |
| 195 | if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'): |
| 196 | oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d)) |
| 197 | |
| 198 | # Add this line to keep link so(like libc.so.6) in dbg-rpm dir. |
| 199 | oe.utils.multiprocess_launch(splitdebuginfo, list(symlinks), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d)) |
| 200 | |
| 201 | if debugsrcdir and not targetos.startswith("mingw"): |
| 202 | for file in staticlibs: |
| 203 | append_source_info(file, sourcefile, d, fatal=False) |
| 204 | |
| 205 | # Hardlink our debug symbols to the other hardlink copies |
| 206 | for ref in inodes: |
| 207 | if len(inodes[ref]) == 1: |
| 208 | continue |
| 209 | |
| 210 | target = inodes[ref][0][len(dvar):] |
| 211 | for file in inodes[ref][1:]: |
| 212 | src = file[len(dvar):] |
| 213 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(target) + debugappend |
| 214 | fpath = dvar + dest |
| 215 | ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend |
| 216 | bb.utils.mkdirhier(os.path.dirname(fpath)) |
| 217 | # Only one hardlink of separated debug info file in each directory |
| 218 | if not os.access(fpath, os.R_OK): |
| 219 | #bb.note("Link %s -> %s" % (fpath, ftarget)) |
| 220 | os.link(ftarget, fpath) |
| 221 | |
| 222 | # Create symlinks for all cases we were able to split symbols |
| 223 | for file in symlinks: |
| 224 | src = file[len(dvar):] |
| 225 | dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend |
| 226 | fpath = dvar + dest |
| 227 | # Skip it if the target doesn't exist |
| 228 | try: |
| 229 | s = os.stat(fpath) |
| 230 | except OSError as e: |
| 231 | (err, strerror) = e.args |
| 232 | if err != errno.ENOENT: |
| 233 | raise |
| 234 | continue |
| 235 | |
| 236 | ltarget = symlinks[file] |
| 237 | lpath = os.path.dirname(ltarget) |
| 238 | lbase = os.path.basename(ltarget) |
| 239 | ftarget = "" |
| 240 | if lpath and lpath != ".": |
| 241 | ftarget += lpath + debugdir + "/" |
| 242 | ftarget += lbase + debugappend |
| 243 | if lpath.startswith(".."): |
| 244 | ftarget = os.path.join("..", ftarget) |
| 245 | bb.utils.mkdirhier(os.path.dirname(fpath)) |
| 246 | #bb.note("Symlink %s -> %s" % (fpath, ftarget)) |
| 247 | if not os.path.exists(fpath): |
| 248 | os.symlink(ftarget, fpath) |
| 249 | |
| 250 | # Process the debugsrcdir if requested... |
| 251 | # This copies and places the referenced sources for later debugging... |
| 252 | copydebugsources(debugsrcdir, d) |
| 253 | # |
| 254 | # End of debug splitting |
| 255 | # |
| 256 | |
| 257 | # |
| 258 | # Now lets go back over things and strip them |
| 259 | # |
| 260 | if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'): |
| 261 | strip = d.getVar("STRIP") |
| 262 | sfiles = [] |
| 263 | for file in elffiles: |
| 264 | elf_file = int(elffiles[file]) |
| 265 | #bb.note("Strip %s" % file) |
| 266 | sfiles.append((file, elf_file, strip)) |
| 267 | for f in kernmods: |
| 268 | sfiles.append((f, 16, strip)) |
| 269 | |
| 270 | oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d) |
| 271 | |
| 272 | # |
| 273 | # End of strip |
| 274 | # |
| 275 | os.chdir(oldcwd) |
| 276 | } |
| 277 | |
| 278 | python package_do_shlibs() { |
| 279 | import re, pipes |
| 280 | import subprocess |
| 281 | |
| 282 | exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False) |
| 283 | if exclude_shlibs: |
| 284 | bb.note("not generating shlibs") |
| 285 | return |
| 286 | |
| 287 | lib_re = re.compile("^.*\.so") |
| 288 | libdir_re = re.compile(".*/%s$" % d.getVar('baselib')) |
| 289 | |
| 290 | packages = d.getVar('PACKAGES') |
| 291 | |
| 292 | shlib_pkgs = [] |
| 293 | exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS") |
| 294 | if exclusion_list: |
| 295 | for pkg in packages.split(): |
| 296 | if pkg not in exclusion_list.split(): |
| 297 | shlib_pkgs.append(pkg) |
| 298 | else: |
| 299 | bb.note("not generating shlibs for %s" % pkg) |
| 300 | else: |
| 301 | shlib_pkgs = packages.split() |
| 302 | |
| 303 | targetos = d.getVar('TARGET_OS') |
| 304 | |
| 305 | workdir = d.getVar('WORKDIR') |
| 306 | |
| 307 | ver = d.getVar('PKGV') |
| 308 | if not ver: |
| 309 | msg = "PKGV not defined" |
| 310 | package_qa_handle_error("pkgv-undefined", msg, d) |
| 311 | return |
| 312 | |
| 313 | pkgdest = d.getVar('PKGDEST') |
| 314 | |
| 315 | shlibswork_dir = d.getVar('SHLIBSWORKDIR') |
| 316 | |
| 317 | def linux_so(file, pkg, pkgver, d): |
| 318 | needs_ldconfig = False |
| 319 | needed = set() |
| 320 | sonames = set() |
| 321 | renames = [] |
| 322 | if "-dbg" in pkg: |
| 323 | return (needs_ldconfig, needed, sonames, renames) |
| 324 | |
| 325 | ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '') |
| 326 | cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null" |
| 327 | fd = os.popen(cmd) |
| 328 | lines = fd.readlines() |
| 329 | fd.close() |
| 330 | rpath = tuple() |
| 331 | for l in lines: |
| 332 | m = re.match("\s+RPATH\s+([^\s]*)", l) |
| 333 | if m: |
| 334 | rpaths = m.group(1).replace("$ORIGIN", ldir).split(":") |
| 335 | rpath = tuple(map(os.path.normpath, rpaths)) |
| 336 | for l in lines: |
| 337 | m = re.match("\s+NEEDED\s+([^\s]*)", l) |
| 338 | if m: |
| 339 | dep = m.group(1) |
| 340 | if dep not in needed: |
| 341 | needed.add((dep, file, rpath)) |
| 342 | m = re.match("\s+SONAME\s+([^\s]*)", l) |
| 343 | if m: |
| 344 | this_soname = m.group(1) |
| 345 | prov = (this_soname, ldir, pkgver) |
| 346 | if not prov in sonames: |
| 347 | # if library is private (only used by package) then do not build shlib for it |
| 348 | if not private_libs or this_soname not in private_libs: |
| 349 | sonames.add(prov) |
| 350 | if libdir_re.match(os.path.dirname(file)): |
| 351 | needs_ldconfig = True |
| 352 | if snap_symlinks and (os.path.basename(file) != this_soname): |
| 353 | renames.append((file, os.path.join(os.path.dirname(file), this_soname))) |
| 354 | return (needs_ldconfig, needed, sonames, renames) |
| 355 | |
| 356 | def darwin_so(file, needed, sonames, renames, pkgver): |
| 357 | if not os.path.exists(file): |
| 358 | return |
| 359 | ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '') |
| 360 | |
| 361 | def get_combinations(base): |
| 362 | # |
| 363 | # Given a base library name, find all combinations of this split by "." and "-" |
| 364 | # |
| 365 | combos = [] |
| 366 | options = base.split(".") |
| 367 | for i in range(1, len(options) + 1): |
| 368 | combos.append(".".join(options[0:i])) |
| 369 | options = base.split("-") |
| 370 | for i in range(1, len(options) + 1): |
| 371 | combos.append("-".join(options[0:i])) |
| 372 | return combos |
| 373 | |
| 374 | if (file.endswith('.dylib') or file.endswith('.so')) and not pkg.endswith('-dev') and not pkg.endswith('-dbg') and not pkg.endswith('-src'): |
| 375 | # Drop suffix |
| 376 | name = os.path.basename(file).rsplit(".",1)[0] |
| 377 | # Find all combinations |
| 378 | combos = get_combinations(name) |
| 379 | for combo in combos: |
| 380 | if not combo in sonames: |
| 381 | prov = (combo, ldir, pkgver) |
| 382 | sonames.add(prov) |
| 383 | if file.endswith('.dylib') or file.endswith('.so'): |
| 384 | rpath = [] |
| 385 | p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 386 | out, err = p.communicate() |
| 387 | # If returned successfully, process stdout for results |
| 388 | if p.returncode == 0: |
| 389 | for l in out.split("\n"): |
| 390 | l = l.strip() |
| 391 | if l.startswith('path '): |
| 392 | rpath.append(l.split()[1]) |
| 393 | |
| 394 | p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 395 | out, err = p.communicate() |
| 396 | # If returned successfully, process stdout for results |
| 397 | if p.returncode == 0: |
| 398 | for l in out.split("\n"): |
| 399 | l = l.strip() |
| 400 | if not l or l.endswith(":"): |
| 401 | continue |
| 402 | if "is not an object file" in l: |
| 403 | continue |
| 404 | name = os.path.basename(l.split()[0]).rsplit(".", 1)[0] |
| 405 | if name and name not in needed[pkg]: |
| 406 | needed[pkg].add((name, file, tuple())) |
| 407 | |
| 408 | def mingw_dll(file, needed, sonames, renames, pkgver): |
| 409 | if not os.path.exists(file): |
| 410 | return |
| 411 | |
| 412 | if file.endswith(".dll"): |
| 413 | # assume all dlls are shared objects provided by the package |
| 414 | sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver)) |
| 415 | |
| 416 | if (file.endswith(".dll") or file.endswith(".exe")): |
| 417 | # use objdump to search for "DLL Name: .*\.dll" |
| 418 | p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 419 | out, err = p.communicate() |
| 420 | # process the output, grabbing all .dll names |
| 421 | if p.returncode == 0: |
| 422 | for m in re.finditer("DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE): |
| 423 | dllname = m.group(1) |
| 424 | if dllname: |
| 425 | needed[pkg].add((dllname, file, tuple())) |
| 426 | |
| 427 | if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1": |
| 428 | snap_symlinks = True |
| 429 | else: |
| 430 | snap_symlinks = False |
| 431 | |
| 432 | use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d) |
| 433 | |
| 434 | needed = {} |
| 435 | |
| 436 | # Take shared lock since we're only reading, not writing |
| 437 | lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True) |
| 438 | shlib_provider = oe.package.read_shlib_providers(d) |
| 439 | bb.utils.unlockfile(lf) |
| 440 | |
| 441 | for pkg in shlib_pkgs: |
| 442 | private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or "" |
| 443 | private_libs = private_libs.split() |
| 444 | needs_ldconfig = False |
| 445 | bb.debug(2, "calculating shlib provides for %s" % pkg) |
| 446 | |
| 447 | pkgver = d.getVar('PKGV_' + pkg) |
| 448 | if not pkgver: |
| 449 | pkgver = d.getVar('PV_' + pkg) |
| 450 | if not pkgver: |
| 451 | pkgver = ver |
| 452 | |
| 453 | needed[pkg] = set() |
| 454 | sonames = set() |
| 455 | renames = [] |
| 456 | linuxlist = [] |
| 457 | for file in pkgfiles[pkg]: |
| 458 | soname = None |
| 459 | if cpath.islink(file): |
| 460 | continue |
| 461 | if targetos == "darwin" or targetos == "darwin8": |
| 462 | darwin_so(file, needed, sonames, renames, pkgver) |
| 463 | elif targetos.startswith("mingw"): |
| 464 | mingw_dll(file, needed, sonames, renames, pkgver) |
| 465 | elif os.access(file, os.X_OK) or lib_re.match(file): |
| 466 | linuxlist.append(file) |
| 467 | |
| 468 | if linuxlist: |
| 469 | results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d)) |
| 470 | for r in results: |
| 471 | ldconfig = r[0] |
| 472 | needed[pkg] |= r[1] |
| 473 | sonames |= r[2] |
| 474 | renames.extend(r[3]) |
| 475 | needs_ldconfig = needs_ldconfig or ldconfig |
| 476 | |
| 477 | for (old, new) in renames: |
| 478 | bb.note("Renaming %s to %s" % (old, new)) |
| 479 | os.rename(old, new) |
| 480 | pkgfiles[pkg].remove(old) |
| 481 | |
| 482 | shlibs_file = os.path.join(shlibswork_dir, pkg + ".list") |
| 483 | if len(sonames): |
| 484 | fd = open(shlibs_file, 'w') |
| 485 | for s in sonames: |
| 486 | if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]: |
| 487 | (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]] |
| 488 | if old_pkg != pkg: |
| 489 | bb.warn('%s-%s was registered as shlib provider for %s, changing it to %s-%s because it was built later' % (old_pkg, old_pkgver, s[0], pkg, pkgver)) |
| 490 | bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0])) |
| 491 | fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n') |
| 492 | if s[0] not in shlib_provider: |
| 493 | shlib_provider[s[0]] = {} |
| 494 | shlib_provider[s[0]][s[1]] = (pkg, pkgver) |
| 495 | fd.close() |
| 496 | if needs_ldconfig and use_ldconfig: |
| 497 | bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg) |
| 498 | postinst = d.getVar('pkg_postinst_%s' % pkg) |
| 499 | if not postinst: |
| 500 | postinst = '#!/bin/sh\n' |
| 501 | postinst += d.getVar('ldconfig_postinst_fragment') |
| 502 | d.setVar('pkg_postinst_%s' % pkg, postinst) |
| 503 | bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames)) |
| 504 | |
| 505 | assumed_libs = d.getVar('ASSUME_SHLIBS') |
| 506 | if assumed_libs: |
| 507 | libdir = d.getVar("libdir") |
| 508 | for e in assumed_libs.split(): |
| 509 | l, dep_pkg = e.split(":") |
| 510 | lib_ver = None |
| 511 | dep_pkg = dep_pkg.rsplit("_", 1) |
| 512 | if len(dep_pkg) == 2: |
| 513 | lib_ver = dep_pkg[1] |
| 514 | dep_pkg = dep_pkg[0] |
| 515 | if l not in shlib_provider: |
| 516 | shlib_provider[l] = {} |
| 517 | shlib_provider[l][libdir] = (dep_pkg, lib_ver) |
| 518 | |
| 519 | libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')] |
| 520 | |
| 521 | for pkg in shlib_pkgs: |
| 522 | bb.debug(2, "calculating shlib requirements for %s" % pkg) |
| 523 | |
| 524 | private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or "" |
| 525 | private_libs = private_libs.split() |
| 526 | |
| 527 | deps = list() |
| 528 | for n in needed[pkg]: |
| 529 | # if n is in private libraries, don't try to search provider for it |
| 530 | # this could cause problem in case some abc.bb provides private |
| 531 | # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1 |
| 532 | # but skipping it is still better alternative than providing own |
| 533 | # version and then adding runtime dependency for the same system library |
| 534 | if private_libs and n[0] in private_libs: |
| 535 | bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0])) |
| 536 | continue |
| 537 | if n[0] in shlib_provider.keys(): |
| 538 | shlib_provider_path = [] |
| 539 | for k in shlib_provider[n[0]].keys(): |
| 540 | shlib_provider_path.append(k) |
| 541 | match = None |
| 542 | for p in list(n[2]) + shlib_provider_path + libsearchpath: |
| 543 | if p in shlib_provider[n[0]]: |
| 544 | match = p |
| 545 | break |
| 546 | if match: |
| 547 | (dep_pkg, ver_needed) = shlib_provider[n[0]][match] |
| 548 | |
| 549 | bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1])) |
| 550 | |
| 551 | if dep_pkg == pkg: |
| 552 | continue |
| 553 | |
| 554 | if ver_needed: |
| 555 | dep = "%s (>= %s)" % (dep_pkg, ver_needed) |
| 556 | else: |
| 557 | dep = dep_pkg |
| 558 | if not dep in deps: |
| 559 | deps.append(dep) |
| 560 | continue |
| 561 | bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1])) |
| 562 | |
| 563 | deps_file = os.path.join(pkgdest, pkg + ".shlibdeps") |
| 564 | if os.path.exists(deps_file): |
| 565 | os.remove(deps_file) |
| 566 | if len(deps): |
| 567 | fd = open(deps_file, 'w') |
| 568 | for dep in deps: |
| 569 | fd.write(dep + '\n') |
| 570 | fd.close() |
| 571 | } |
| 572 | PACKAGEBUILDPKGD := " \ |
| 573 | perform_packagecopy \ |
| 574 | ${PACKAGE_PREPROCESS_FUNCS} \ |
| 575 | split_and_strip_files \ |
| 576 | fixup_perms \ |
| 577 | " |