blob: 02642f29f039637dfd9ece6bd00d652836509eda [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001def 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 Williamsc0f7c042017-02-23 20:41:17 -060011 import stat, subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012
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
47def 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
56def 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 Williamsc0f7c042017-02-23 20:41:17 -060067 f = line.decode("utf-8").split(" ", 1)[0].strip()
68 line = line.decode("utf-8").split(" ", 1)[1].strip()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069
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
102def 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 Williamsc0f7c042017-02-23 20:41:17 -0600117 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 Williamsc124f4f2015-09-15 14:41:29 -0500123 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 Williamsd8c66bc2016-06-20 12:57:21 -0500131
132
133def 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 Williamsc0f7c042017-02-23 20:41:17 -0600157 packages[pkgname] = (relpth, data)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500158 # 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 + '~'))