Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | def runstrip(arg): |
| 2 | # Function to strip a single file, called from split_and_strip_files below |
| 3 | # A working 'file' (one which works on the target architecture) |
| 4 | # |
| 5 | # The elftype is a bit pattern (explained in split_and_strip_files) to tell |
| 6 | # us what type of file we're processing... |
| 7 | # 4 - executable |
| 8 | # 8 - shared library |
| 9 | # 16 - kernel module |
| 10 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 11 | import stat, subprocess |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 12 | |
| 13 | (file, elftype, strip) = arg |
| 14 | |
| 15 | newmode = None |
| 16 | if not os.access(file, os.W_OK) or os.access(file, os.R_OK): |
| 17 | origmode = os.stat(file)[stat.ST_MODE] |
| 18 | newmode = origmode | stat.S_IWRITE | stat.S_IREAD |
| 19 | os.chmod(file, newmode) |
| 20 | |
| 21 | extraflags = "" |
| 22 | |
| 23 | # kernel module |
| 24 | if elftype & 16: |
| 25 | extraflags = "--strip-debug --remove-section=.comment --remove-section=.note --preserve-dates" |
| 26 | # .so and shared library |
| 27 | elif ".so" in file and elftype & 8: |
| 28 | extraflags = "--remove-section=.comment --remove-section=.note --strip-unneeded" |
| 29 | # shared or executable: |
| 30 | elif elftype & 8 or elftype & 4: |
| 31 | extraflags = "--remove-section=.comment --remove-section=.note" |
| 32 | |
| 33 | stripcmd = "'%s' %s '%s'" % (strip, extraflags, file) |
| 34 | bb.debug(1, "runstrip: %s" % stripcmd) |
| 35 | |
| 36 | try: |
| 37 | output = subprocess.check_output(stripcmd, stderr=subprocess.STDOUT, shell=True) |
| 38 | except subprocess.CalledProcessError as e: |
| 39 | bb.error("runstrip: '%s' strip command failed with %s (%s)" % (stripcmd, e.returncode, e.output)) |
| 40 | |
| 41 | if newmode: |
| 42 | os.chmod(file, origmode) |
| 43 | |
| 44 | return |
| 45 | |
| 46 | |
| 47 | def file_translate(file): |
| 48 | ft = file.replace("@", "@at@") |
| 49 | ft = ft.replace(" ", "@space@") |
| 50 | ft = ft.replace("\t", "@tab@") |
| 51 | ft = ft.replace("[", "@openbrace@") |
| 52 | ft = ft.replace("]", "@closebrace@") |
| 53 | ft = ft.replace("_", "@underscore@") |
| 54 | return ft |
| 55 | |
| 56 | def filedeprunner(arg): |
| 57 | import re, subprocess, shlex |
| 58 | |
| 59 | (pkg, pkgfiles, rpmdeps, pkgdest) = arg |
| 60 | provides = {} |
| 61 | requires = {} |
| 62 | |
| 63 | r = re.compile(r'[<>=]+ +[^ ]*') |
| 64 | |
| 65 | def process_deps(pipe, pkg, pkgdest, provides, requires): |
| 66 | for line in pipe: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 67 | f = line.decode("utf-8").split(" ", 1)[0].strip() |
| 68 | line = line.decode("utf-8").split(" ", 1)[1].strip() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 69 | |
| 70 | if line.startswith("Requires:"): |
| 71 | i = requires |
| 72 | elif line.startswith("Provides:"): |
| 73 | i = provides |
| 74 | else: |
| 75 | continue |
| 76 | |
| 77 | file = f.replace(pkgdest + "/" + pkg, "") |
| 78 | file = file_translate(file) |
| 79 | value = line.split(":", 1)[1].strip() |
| 80 | value = r.sub(r'(\g<0>)', value) |
| 81 | |
| 82 | if value.startswith("rpmlib("): |
| 83 | continue |
| 84 | if value == "python": |
| 85 | continue |
| 86 | if file not in i: |
| 87 | i[file] = [] |
| 88 | i[file].append(value) |
| 89 | |
| 90 | return provides, requires |
| 91 | |
| 92 | try: |
| 93 | dep_popen = subprocess.Popen(shlex.split(rpmdeps) + pkgfiles, stdout=subprocess.PIPE) |
| 94 | provides, requires = process_deps(dep_popen.stdout, pkg, pkgdest, provides, requires) |
| 95 | except OSError as e: |
| 96 | bb.error("rpmdeps: '%s' command failed, '%s'" % (shlex.split(rpmdeps) + pkgfiles, e)) |
| 97 | raise e |
| 98 | |
| 99 | return (pkg, provides, requires) |
| 100 | |
| 101 | |
| 102 | def read_shlib_providers(d): |
| 103 | import re |
| 104 | |
| 105 | shlib_provider = {} |
| 106 | shlibs_dirs = d.getVar('SHLIBSDIRS', True).split() |
| 107 | list_re = re.compile('^(.*)\.list$') |
| 108 | # Go from least to most specific since the last one found wins |
| 109 | for dir in reversed(shlibs_dirs): |
| 110 | bb.debug(2, "Reading shlib providers in %s" % (dir)) |
| 111 | if not os.path.exists(dir): |
| 112 | continue |
| 113 | for file in os.listdir(dir): |
| 114 | m = list_re.match(file) |
| 115 | if m: |
| 116 | dep_pkg = m.group(1) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 117 | try: |
| 118 | fd = open(os.path.join(dir, file)) |
| 119 | except IOError: |
| 120 | # During a build unrelated shlib files may be deleted, so |
| 121 | # handle files disappearing between the listdirs and open. |
| 122 | continue |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 123 | lines = fd.readlines() |
| 124 | fd.close() |
| 125 | for l in lines: |
| 126 | s = l.strip().split(":") |
| 127 | if s[0] not in shlib_provider: |
| 128 | shlib_provider[s[0]] = {} |
| 129 | shlib_provider[s[0]][s[1]] = (dep_pkg, s[2]) |
| 130 | return shlib_provider |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 131 | |
| 132 | |
| 133 | def npm_split_package_dirs(pkgdir): |
| 134 | """ |
| 135 | Work out the packages fetched and unpacked by BitBake's npm fetcher |
| 136 | Returns a dict of packagename -> (relpath, package.json) ordered |
| 137 | such that it is suitable for use in PACKAGES and FILES |
| 138 | """ |
| 139 | from collections import OrderedDict |
| 140 | import json |
| 141 | packages = {} |
| 142 | for root, dirs, files in os.walk(pkgdir): |
| 143 | if os.path.basename(root) == 'node_modules': |
| 144 | for dn in dirs: |
| 145 | relpth = os.path.relpath(os.path.join(root, dn), pkgdir) |
| 146 | pkgitems = ['${PN}'] |
| 147 | for pathitem in relpth.split('/'): |
| 148 | if pathitem == 'node_modules': |
| 149 | continue |
| 150 | pkgitems.append(pathitem) |
| 151 | pkgname = '-'.join(pkgitems).replace('_', '-') |
| 152 | pkgfile = os.path.join(root, dn, 'package.json') |
| 153 | data = None |
| 154 | if os.path.exists(pkgfile): |
| 155 | with open(pkgfile, 'r') as f: |
| 156 | data = json.loads(f.read()) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 157 | packages[pkgname] = (relpth, data) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 158 | # We want the main package for a module sorted *after* its subpackages |
| 159 | # (so that it doesn't otherwise steal the files for the subpackage), so |
| 160 | # this is a cheap way to do that whilst still having an otherwise |
| 161 | # alphabetical sort |
| 162 | return OrderedDict((key, packages[key]) for key in sorted(packages, key=lambda pkg: pkg + '~')) |