blob: 4797e7d65aae9c05a86294555d5be8bd7a3980f3 [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
Brad Bishop6e60e8b2018-02-01 10:27:11 -050021 stripcmd = [strip]
Patrick Williamsc124f4f2015-09-15 14:41:29 -050022
23 # kernel module
24 if elftype & 16:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050025 stripcmd.extend(["--strip-debug", "--remove-section=.comment",
26 "--remove-section=.note", "--preserve-dates"])
Patrick Williamsc124f4f2015-09-15 14:41:29 -050027 # .so and shared library
28 elif ".so" in file and elftype & 8:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050029 stripcmd.extend(["--remove-section=.comment", "--remove-section=.note", "--strip-unneeded"])
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030 # shared or executable:
31 elif elftype & 8 or elftype & 4:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050032 stripcmd.extend(["--remove-section=.comment", "--remove-section=.note"])
Patrick Williamsc124f4f2015-09-15 14:41:29 -050033
Brad Bishop6e60e8b2018-02-01 10:27:11 -050034 stripcmd.append(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050035 bb.debug(1, "runstrip: %s" % stripcmd)
36
37 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050038 output = subprocess.check_output(stripcmd, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050039 except subprocess.CalledProcessError as e:
40 bb.error("runstrip: '%s' strip command failed with %s (%s)" % (stripcmd, e.returncode, e.output))
41
42 if newmode:
43 os.chmod(file, origmode)
44
45 return
46
47
48def file_translate(file):
49 ft = file.replace("@", "@at@")
50 ft = ft.replace(" ", "@space@")
51 ft = ft.replace("\t", "@tab@")
52 ft = ft.replace("[", "@openbrace@")
53 ft = ft.replace("]", "@closebrace@")
54 ft = ft.replace("_", "@underscore@")
55 return ft
56
57def filedeprunner(arg):
58 import re, subprocess, shlex
59
60 (pkg, pkgfiles, rpmdeps, pkgdest) = arg
61 provides = {}
62 requires = {}
63
Brad Bishop6e60e8b2018-02-01 10:27:11 -050064 file_re = re.compile(r'\s+\d+\s(.*)')
65 dep_re = re.compile(r'\s+(\S)\s+(.*)')
66 r = re.compile(r'[<>=]+\s+\S*')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050067
68 def process_deps(pipe, pkg, pkgdest, provides, requires):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050069 file = None
Patrick Williamsc124f4f2015-09-15 14:41:29 -050070 for line in pipe:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050071 line = line.decode("utf-8")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050072
Brad Bishop6e60e8b2018-02-01 10:27:11 -050073 m = file_re.match(line)
74 if m:
75 file = m.group(1)
76 file = file.replace(pkgdest + "/" + pkg, "")
77 file = file_translate(file)
78 continue
79
80 m = dep_re.match(line)
81 if not m or not file:
82 continue
83
84 type, dep = m.groups()
85
86 if type == 'R':
Patrick Williamsc124f4f2015-09-15 14:41:29 -050087 i = requires
Brad Bishop6e60e8b2018-02-01 10:27:11 -050088 elif type == 'P':
Patrick Williamsc124f4f2015-09-15 14:41:29 -050089 i = provides
90 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050091 continue
92
93 if dep.startswith("python("):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050094 continue
95
Brad Bishop6e60e8b2018-02-01 10:27:11 -050096 # Ignore all perl(VMS::...) and perl(Mac::...) dependencies. These
97 # are typically used conditionally from the Perl code, but are
98 # generated as unconditional dependencies.
99 if dep.startswith('perl(VMS::') or dep.startswith('perl(Mac::'):
100 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500101
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500102 # Ignore perl dependencies on .pl files.
103 if dep.startswith('perl(') and dep.endswith('.pl)'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500105
106 # Remove perl versions and perl module versions since they typically
107 # do not make sense when used as package versions.
108 if dep.startswith('perl') and r.search(dep):
109 dep = dep.split()[0]
110
111 # Put parentheses around any version specifications.
112 dep = r.sub(r'(\g<0>)',dep)
113
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500114 if file not in i:
115 i[file] = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500116 i[file].append(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500117
118 return provides, requires
119
120 try:
121 dep_popen = subprocess.Popen(shlex.split(rpmdeps) + pkgfiles, stdout=subprocess.PIPE)
122 provides, requires = process_deps(dep_popen.stdout, pkg, pkgdest, provides, requires)
123 except OSError as e:
124 bb.error("rpmdeps: '%s' command failed, '%s'" % (shlex.split(rpmdeps) + pkgfiles, e))
125 raise e
126
127 return (pkg, provides, requires)
128
129
130def read_shlib_providers(d):
131 import re
132
133 shlib_provider = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500134 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135 list_re = re.compile('^(.*)\.list$')
136 # Go from least to most specific since the last one found wins
137 for dir in reversed(shlibs_dirs):
138 bb.debug(2, "Reading shlib providers in %s" % (dir))
139 if not os.path.exists(dir):
140 continue
141 for file in os.listdir(dir):
142 m = list_re.match(file)
143 if m:
144 dep_pkg = m.group(1)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600145 try:
146 fd = open(os.path.join(dir, file))
147 except IOError:
148 # During a build unrelated shlib files may be deleted, so
149 # handle files disappearing between the listdirs and open.
150 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 lines = fd.readlines()
152 fd.close()
153 for l in lines:
154 s = l.strip().split(":")
155 if s[0] not in shlib_provider:
156 shlib_provider[s[0]] = {}
157 shlib_provider[s[0]][s[1]] = (dep_pkg, s[2])
158 return shlib_provider
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500159
160
161def npm_split_package_dirs(pkgdir):
162 """
163 Work out the packages fetched and unpacked by BitBake's npm fetcher
164 Returns a dict of packagename -> (relpath, package.json) ordered
165 such that it is suitable for use in PACKAGES and FILES
166 """
167 from collections import OrderedDict
168 import json
169 packages = {}
170 for root, dirs, files in os.walk(pkgdir):
171 if os.path.basename(root) == 'node_modules':
172 for dn in dirs:
173 relpth = os.path.relpath(os.path.join(root, dn), pkgdir)
174 pkgitems = ['${PN}']
175 for pathitem in relpth.split('/'):
176 if pathitem == 'node_modules':
177 continue
178 pkgitems.append(pathitem)
179 pkgname = '-'.join(pkgitems).replace('_', '-')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500180 pkgname = pkgname.replace('@', '')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500181 pkgfile = os.path.join(root, dn, 'package.json')
182 data = None
183 if os.path.exists(pkgfile):
184 with open(pkgfile, 'r') as f:
185 data = json.loads(f.read())
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600186 packages[pkgname] = (relpth, data)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500187 # We want the main package for a module sorted *after* its subpackages
188 # (so that it doesn't otherwise steal the files for the subpackage), so
189 # this is a cheap way to do that whilst still having an otherwise
190 # alphabetical sort
191 return OrderedDict((key, packages[key]) for key in sorted(packages, key=lambda pkg: pkg + '~'))