blob: e71daafe9461df6b8b2a9f935b06a2865220c1f0 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# Packaging process
3#
4# Executive summary: This class iterates over the functions listed in PACKAGEFUNCS
5# Taking D and splitting it up into the packages listed in PACKAGES, placing the
6# resulting output in PKGDEST.
7#
8# There are the following default steps but PACKAGEFUNCS can be extended:
9#
Andrew Geisslerc9f78652020-09-18 14:11:35 -050010# a) package_convert_pr_autoinc - convert AUTOINC in PKGV to ${PRSERV_PV_AUTOINC}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011#
12# b) perform_packagecopy - Copy D into PKGD
13#
14# c) package_do_split_locales - Split out the locale files, updates FILES and PACKAGES
15#
16# d) split_and_strip_files - split the files into runtime and debug and strip them.
17# Debug files include debug info split, and associated sources that end up in -dbg packages
18#
19# e) fixup_perms - Fix up permissions in the package before we split it.
20#
21# f) populate_packages - Split the files in PKGD into separate packages in PKGDEST/<pkgname>
22# Also triggers the binary stripping code to put files in -dbg packages.
23#
24# g) package_do_filedeps - Collect perfile run-time dependency metadata
25# The data is stores in FILER{PROVIDES,DEPENDS}_file_pkg variables with
26# a list of affected files in FILER{PROVIDES,DEPENDS}FLIST_pkg
27#
28# h) package_do_shlibs - Look at the shared libraries generated and autotmatically add any
Brad Bishop316dfdd2018-06-25 12:45:53 -040029# dependencies found. Also stores the package name so anyone else using this library
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030# knows which package to depend on.
31#
32# i) package_do_pkgconfig - Keep track of which packages need and provide which .pc files
33#
34# j) read_shlibdeps - Reads the stored shlibs information into the metadata
35#
36# k) package_depchains - Adds automatic dependencies to -dbg and -dev packages
37#
38# l) emit_pkgdata - saves the packaging data into PKGDATA_DIR for use in later
39# packaging steps
40
41inherit packagedata
Patrick Williamsc124f4f2015-09-15 14:41:29 -050042inherit chrpath
Brad Bishop96ff1982019-08-19 13:50:42 -040043inherit package_pkgdata
Patrick Williamsc124f4f2015-09-15 14:41:29 -050044inherit insane
45
46PKGD = "${WORKDIR}/package"
47PKGDEST = "${WORKDIR}/packages-split"
48
49LOCALE_SECTION ?= ''
50
51ALL_MULTILIB_PACKAGE_ARCHS = "${@all_multilib_tune_values(d, 'PACKAGE_ARCHS')}"
52
53# rpm is used for the per-file dependency identification
Brad Bishop316dfdd2018-06-25 12:45:53 -040054# dwarfsrcfiles is used to determine the list of debug source files
55PACKAGE_DEPENDS += "rpm-native dwarfsrcfiles-native"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056
Brad Bishop6e60e8b2018-02-01 10:27:11 -050057
58# If your postinstall can execute at rootfs creation time rather than on
59# target but depends on a native/cross tool in order to execute, you need to
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080060# list that tool in PACKAGE_WRITE_DEPS. Target package dependencies belong
Brad Bishop6e60e8b2018-02-01 10:27:11 -050061# in the package dependencies as normal, this is just for native/cross support
62# tools at rootfs build time.
63PACKAGE_WRITE_DEPS ??= ""
64
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065def legitimize_package_name(s):
66 """
67 Make sure package names are legitimate strings
68 """
69 import re
70
71 def fixutf(m):
72 cp = m.group(1)
73 if cp:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060074 return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075
76 # Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
Brad Bishop19323692019-04-05 15:28:33 -040077 s = re.sub(r'<U([0-9A-Fa-f]{1,4})>', fixutf, s)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078
79 # Remaining package name validity fixes
80 return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
81
82def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None, allow_links=False, summary=None):
83 """
84 Used in .bb files to split up dynamically generated subpackages of a
85 given package, usually plugins or modules.
86
87 Arguments:
88 root -- the path in which to search
89 file_regex -- regular expression to match searched files. Use
90 parentheses () to mark the part of this expression
91 that should be used to derive the module name (to be
92 substituted where %s is used in other function
93 arguments as noted below)
94 output_pattern -- pattern to use for the package names. Must include %s.
95 description -- description to set for each package. Must include %s.
96 postinst -- postinstall script to use for all packages (as a
97 string)
98 recursive -- True to perform a recursive search - default False
99 hook -- a hook function to be called for every match. The
100 function will be called with the following arguments
101 (in the order listed):
102 f: full path to the file/directory match
103 pkg: the package name
104 file_regex: as above
105 output_pattern: as above
106 modulename: the module name derived using file_regex
107 extra_depends -- extra runtime dependencies (RDEPENDS) to be set for
108 all packages. The default value of None causes a
109 dependency on the main package (${PN}) - if you do
110 not want this, pass '' for this parameter.
111 aux_files_pattern -- extra item(s) to be added to FILES for each
112 package. Can be a single string item or a list of
113 strings for multiple items. Must include %s.
114 postrm -- postrm script to use for all packages (as a string)
115 allow_dirs -- True allow directories to be matched - default False
116 prepend -- if True, prepend created packages to PACKAGES instead
117 of the default False which appends them
118 match_path -- match file_regex on the whole relative path to the
119 root rather than just the file name
120 aux_files_pattern_verbatim -- extra item(s) to be added to FILES for
121 each package, using the actual derived module name
122 rather than converting it to something legal for a
123 package name. Can be a single string item or a list
124 of strings for multiple items. Must include %s.
125 allow_links -- True to allow symlinks to be matched - default False
126 summary -- Summary to set for each package. Must include %s;
127 defaults to description if not set.
128
129 """
130
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500131 dvar = d.getVar('PKGD')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500132 root = d.expand(root)
133 output_pattern = d.expand(output_pattern)
134 extra_depends = d.expand(extra_depends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135
136 # If the root directory doesn't exist, don't error out later but silently do
137 # no splitting.
138 if not os.path.exists(dvar + root):
139 return []
140
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500141 ml = d.getVar("MLPREFIX")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 if ml:
143 if not output_pattern.startswith(ml):
144 output_pattern = ml + output_pattern
145
146 newdeps = []
147 for dep in (extra_depends or "").split():
148 if dep.startswith(ml):
149 newdeps.append(dep)
150 else:
151 newdeps.append(ml + dep)
152 if newdeps:
153 extra_depends = " ".join(newdeps)
154
155
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500156 packages = d.getVar('PACKAGES').split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600157 split_packages = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158
159 if postinst:
160 postinst = '#!/bin/sh\n' + postinst + '\n'
161 if postrm:
162 postrm = '#!/bin/sh\n' + postrm + '\n'
163 if not recursive:
164 objs = os.listdir(dvar + root)
165 else:
166 objs = []
167 for walkroot, dirs, files in os.walk(dvar + root):
168 for file in files:
169 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
170 if relpath:
171 objs.append(relpath)
172
173 if extra_depends == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500174 extra_depends = d.getVar("PN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500175
176 if not summary:
177 summary = description
178
179 for o in sorted(objs):
180 import re, stat
181 if match_path:
182 m = re.match(file_regex, o)
183 else:
184 m = re.match(file_regex, os.path.basename(o))
185
186 if not m:
187 continue
188 f = os.path.join(dvar + root, o)
189 mode = os.lstat(f).st_mode
190 if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))):
191 continue
192 on = legitimize_package_name(m.group(1))
193 pkg = output_pattern % on
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600194 split_packages.add(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 if not pkg in packages:
196 if prepend:
197 packages = [pkg] + packages
198 else:
199 packages.append(pkg)
Patrick Williams213cb262021-08-07 19:21:33 -0500200 oldfiles = d.getVar('FILES:' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500201 newfile = os.path.join(root, o)
202 # These names will be passed through glob() so if the filename actually
203 # contains * or ? (rare, but possible) we need to handle that specially
204 newfile = newfile.replace('*', '[*]')
205 newfile = newfile.replace('?', '[?]')
206 if not oldfiles:
207 the_files = [newfile]
208 if aux_files_pattern:
209 if type(aux_files_pattern) is list:
210 for fp in aux_files_pattern:
211 the_files.append(fp % on)
212 else:
213 the_files.append(aux_files_pattern % on)
214 if aux_files_pattern_verbatim:
215 if type(aux_files_pattern_verbatim) is list:
216 for fp in aux_files_pattern_verbatim:
217 the_files.append(fp % m.group(1))
218 else:
219 the_files.append(aux_files_pattern_verbatim % m.group(1))
Patrick Williams213cb262021-08-07 19:21:33 -0500220 d.setVar('FILES:' + pkg, " ".join(the_files))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500221 else:
Patrick Williams213cb262021-08-07 19:21:33 -0500222 d.setVar('FILES:' + pkg, oldfiles + " " + newfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500223 if extra_depends != '':
Patrick Williams213cb262021-08-07 19:21:33 -0500224 d.appendVar('RDEPENDS:' + pkg, ' ' + extra_depends)
225 if not d.getVar('DESCRIPTION:' + pkg):
226 d.setVar('DESCRIPTION:' + pkg, description % on)
227 if not d.getVar('SUMMARY:' + pkg):
228 d.setVar('SUMMARY:' + pkg, summary % on)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229 if postinst:
Patrick Williams213cb262021-08-07 19:21:33 -0500230 d.setVar('pkg_postinst:' + pkg, postinst)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500231 if postrm:
Patrick Williams213cb262021-08-07 19:21:33 -0500232 d.setVar('pkg_postrm:' + pkg, postrm)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 if callable(hook):
234 hook(f, pkg, file_regex, output_pattern, m.group(1))
235
236 d.setVar('PACKAGES', ' '.join(packages))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600237 return list(split_packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238
239PACKAGE_DEPENDS += "file-native"
240
241python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500242 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500243 deps = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500244 for dep in (d.getVar('PACKAGE_DEPENDS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500245 deps += " %s:do_populate_sysroot" % dep
Andrew Geissler82c905d2020-04-13 13:39:40 -0500246 if d.getVar('PACKAGE_MINIDEBUGINFO') == '1':
247 deps += ' xz-native:do_populate_sysroot'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500248 d.appendVarFlag('do_package', 'depends', deps)
249
250 # shlibs requires any DEPENDS to have already packaged for the *.list files
251 d.appendVarFlag('do_package', 'deptask', " do_packagedata")
252}
253
254# Get a list of files from file vars by searching files under current working directory
255# The list contains symlinks, directories and normal files.
256def files_from_filevars(filevars):
257 import os,glob
258 cpath = oe.cachedpath.CachedPath()
259 files = []
260 for f in filevars:
261 if os.path.isabs(f):
262 f = '.' + f
263 if not f.startswith("./"):
264 f = './' + f
265 globbed = glob.glob(f)
266 if globbed:
267 if [ f ] != globbed:
268 files += globbed
269 continue
270 files.append(f)
271
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600272 symlink_paths = []
273 for ind, f in enumerate(files):
274 # Handle directory symlinks. Truncate path to the lowest level symlink
275 parent = ''
276 for dirname in f.split('/')[:-1]:
277 parent = os.path.join(parent, dirname)
278 if dirname == '.':
279 continue
280 if cpath.islink(parent):
281 bb.warn("FILES contains file '%s' which resides under a "
282 "directory symlink. Please fix the recipe and use the "
283 "real path for the file." % f[1:])
284 symlink_paths.append(f)
285 files[ind] = parent
286 f = parent
287 break
288
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500289 if not cpath.islink(f):
290 if cpath.isdir(f):
291 newfiles = [ os.path.join(f,x) for x in os.listdir(f) ]
292 if newfiles:
293 files += newfiles
294
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600295 return files, symlink_paths
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500296
297# Called in package_<rpm,ipk,deb>.bbclass to get the correct list of configuration files
298def get_conffiles(pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500299 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500300 root = os.path.join(pkgdest, pkg)
301 cwd = os.getcwd()
302 os.chdir(root)
303
Patrick Williams213cb262021-08-07 19:21:33 -0500304 conffiles = d.getVar('CONFFILES:%s' % pkg);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500305 if conffiles == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500306 conffiles = d.getVar('CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500307 if conffiles == None:
308 conffiles = ""
309 conffiles = conffiles.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600310 conf_orig_list = files_from_filevars(conffiles)[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311
312 # Remove links and directories from conf_orig_list to get conf_list which only contains normal files
313 conf_list = []
314 for f in conf_orig_list:
315 if os.path.isdir(f):
316 continue
317 if os.path.islink(f):
318 continue
319 if not os.path.exists(f):
320 continue
321 conf_list.append(f)
322
323 # Remove the leading './'
324 for i in range(0, len(conf_list)):
325 conf_list[i] = conf_list[i][1:]
326
327 os.chdir(cwd)
328 return conf_list
329
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500330def checkbuildpath(file, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500331 tmpdir = d.getVar('TMPDIR')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500332 with open(file) as f:
333 file_content = f.read()
334 if tmpdir in file_content:
335 return True
336
337 return False
338
Brad Bishop316dfdd2018-06-25 12:45:53 -0400339def parse_debugsources_from_dwarfsrcfiles_output(dwarfsrcfiles_output):
340 debugfiles = {}
341
342 for line in dwarfsrcfiles_output.splitlines():
343 if line.startswith("\t"):
344 debugfiles[os.path.normpath(line.split()[0])] = ""
345
346 return debugfiles.keys()
347
Brad Bishop19323692019-04-05 15:28:33 -0400348def source_info(file, d, fatal=True):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800349 import subprocess
350
351 cmd = ["dwarfsrcfiles", file]
352 try:
353 output = subprocess.check_output(cmd, universal_newlines=True, stderr=subprocess.STDOUT)
354 retval = 0
355 except subprocess.CalledProcessError as exc:
356 output = exc.output
357 retval = exc.returncode
358
Brad Bishop316dfdd2018-06-25 12:45:53 -0400359 # 255 means a specific file wasn't fully parsed to get the debug file list, which is not a fatal failure
360 if retval != 0 and retval != 255:
361 msg = "dwarfsrcfiles failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else "")
362 if fatal:
363 bb.fatal(msg)
364 bb.note(msg)
365
366 debugsources = parse_debugsources_from_dwarfsrcfiles_output(output)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400367
Brad Bishop19323692019-04-05 15:28:33 -0400368 return list(debugsources)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400369
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000370def splitdebuginfo(file, dvar, dv, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500371 # Function to split a single file into two components, one is the stripped
372 # target system binary, the other contains any debugging information. The
373 # two files are linked to reference each other.
374 #
Brad Bishop19323692019-04-05 15:28:33 -0400375 # return a mapping of files:debugsources
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376
377 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800378 import subprocess
379
380 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000381 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(src) + dv["append"]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800382 debugfile = dvar + dest
Brad Bishop19323692019-04-05 15:28:33 -0400383 sources = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800384
385 # Split the file...
386 bb.utils.mkdirhier(os.path.dirname(debugfile))
387 #bb.note("Split %s -> %s" % (file, debugfile))
388 # Only store off the hard link reference if we successfully split!
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500389
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500390 dvar = d.getVar('PKGD')
391 objcopy = d.getVar("OBJCOPY")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500392
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500393 newmode = None
394 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
395 origmode = os.stat(file)[stat.ST_MODE]
396 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
397 os.chmod(file, newmode)
398
399 # We need to extract the debug src information here...
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000400 if dv["srcdir"]:
Brad Bishop19323692019-04-05 15:28:33 -0400401 sources = source_info(file, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500402
403 bb.utils.mkdirhier(os.path.dirname(debugfile))
404
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800405 subprocess.check_output([objcopy, '--only-keep-debug', file, debugfile], stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406
407 # Set the debuglink to have the view of the file path on the target
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800408 subprocess.check_output([objcopy, '--add-gnu-debuglink', debugfile, file], stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500409
410 if newmode:
411 os.chmod(file, origmode)
412
Brad Bishop19323692019-04-05 15:28:33 -0400413 return (file, sources)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500414
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000415def splitstaticdebuginfo(file, dvar, dv, d):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500416 # Unlike the function above, there is no way to split a static library
417 # two components. So to get similar results we will copy the unmodified
418 # static library (containing the debug symbols) into a new directory.
419 # We will then strip (preserving symbols) the static library in the
420 # typical location.
421 #
422 # return a mapping of files:debugsources
423
424 import stat
425 import shutil
426
427 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000428 dest = dv["staticlibdir"] + os.path.dirname(src) + dv["staticdir"] + "/" + os.path.basename(src) + dv["staticappend"]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500429 debugfile = dvar + dest
430 sources = []
431
432 # Copy the file...
433 bb.utils.mkdirhier(os.path.dirname(debugfile))
434 #bb.note("Copy %s -> %s" % (file, debugfile))
435
436 dvar = d.getVar('PKGD')
437
438 newmode = None
439 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
440 origmode = os.stat(file)[stat.ST_MODE]
441 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
442 os.chmod(file, newmode)
443
444 # We need to extract the debug src information here...
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000445 if dv["srcdir"]:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500446 sources = source_info(file, d)
447
448 bb.utils.mkdirhier(os.path.dirname(debugfile))
449
450 # Copy the unmodified item to the debug directory
451 shutil.copy2(file, debugfile)
452
453 if newmode:
454 os.chmod(file, origmode)
455
456 return (file, sources)
457
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000458def inject_minidebuginfo(file, dvar, dv, d):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500459 # Extract just the symbols from debuginfo into minidebuginfo,
460 # compress it with xz and inject it back into the binary in a .gnu_debugdata section.
461 # https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
462
463 import subprocess
464
465 readelf = d.getVar('READELF')
466 nm = d.getVar('NM')
467 objcopy = d.getVar('OBJCOPY')
468
469 minidebuginfodir = d.expand('${WORKDIR}/minidebuginfo')
470
471 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000472 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(src) + dv["append"]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500473 debugfile = dvar + dest
474 minidebugfile = minidebuginfodir + src + '.minidebug'
475 bb.utils.mkdirhier(os.path.dirname(minidebugfile))
476
477 # If we didn't produce debuginfo for any reason, we can't produce minidebuginfo either
478 # so skip it.
479 if not os.path.exists(debugfile):
480 bb.debug(1, 'ELF file {} has no debuginfo, skipping minidebuginfo injection'.format(file))
481 return
482
483 # Find non-allocated PROGBITS, NOTE, and NOBITS sections in the debuginfo.
484 # We will exclude all of these from minidebuginfo to save space.
485 remove_section_names = []
486 for line in subprocess.check_output([readelf, '-W', '-S', debugfile], universal_newlines=True).splitlines():
487 fields = line.split()
488 if len(fields) < 8:
489 continue
490 name = fields[0]
491 type = fields[1]
492 flags = fields[7]
493 # .debug_ sections will be removed by objcopy -S so no need to explicitly remove them
494 if name.startswith('.debug_'):
495 continue
496 if 'A' not in flags and type in ['PROGBITS', 'NOTE', 'NOBITS']:
497 remove_section_names.append(name)
498
499 # List dynamic symbols in the binary. We can exclude these from minidebuginfo
500 # because they are always present in the binary.
501 dynsyms = set()
502 for line in subprocess.check_output([nm, '-D', file, '--format=posix', '--defined-only'], universal_newlines=True).splitlines():
503 dynsyms.add(line.split()[0])
504
505 # Find all function symbols from debuginfo which aren't in the dynamic symbols table.
506 # These are the ones we want to keep in minidebuginfo.
507 keep_symbols_file = minidebugfile + '.symlist'
508 found_any_symbols = False
509 with open(keep_symbols_file, 'w') as f:
510 for line in subprocess.check_output([nm, debugfile, '--format=sysv', '--defined-only'], universal_newlines=True).splitlines():
511 fields = line.split('|')
512 if len(fields) < 7:
513 continue
514 name = fields[0].strip()
515 type = fields[3].strip()
516 if type == 'FUNC' and name not in dynsyms:
517 f.write('{}\n'.format(name))
518 found_any_symbols = True
519
520 if not found_any_symbols:
521 bb.debug(1, 'ELF file {} contains no symbols, skipping minidebuginfo injection'.format(file))
522 return
523
524 bb.utils.remove(minidebugfile)
525 bb.utils.remove(minidebugfile + '.xz')
526
527 subprocess.check_call([objcopy, '-S'] +
528 ['--remove-section={}'.format(s) for s in remove_section_names] +
529 ['--keep-symbols={}'.format(keep_symbols_file), debugfile, minidebugfile])
530
531 subprocess.check_call(['xz', '--keep', minidebugfile])
532
533 subprocess.check_call([objcopy, '--add-section', '.gnu_debugdata={}.xz'.format(minidebugfile), file])
534
Brad Bishop19323692019-04-05 15:28:33 -0400535def copydebugsources(debugsrcdir, sources, d):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400536 # The debug src information written out to sourcefile is further processed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500537 # and copied to the destination here.
538
539 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800540 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500541
Brad Bishop19323692019-04-05 15:28:33 -0400542 if debugsrcdir and sources:
543 sourcefile = d.expand("${WORKDIR}/debugsources.list")
544 bb.utils.remove(sourcefile)
545
546 # filenames are null-separated - this is an artefact of the previous use
547 # of rpm's debugedit, which was writing them out that way, and the code elsewhere
548 # is still assuming that.
549 debuglistoutput = '\0'.join(sources) + '\0'
550 with open(sourcefile, 'a') as sf:
551 sf.write(debuglistoutput)
552
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500553 dvar = d.getVar('PKGD')
554 strip = d.getVar("STRIP")
555 objcopy = d.getVar("OBJCOPY")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500556 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557 workparentdir = os.path.dirname(os.path.dirname(workdir))
558 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
559
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500560 # If build path exists in sourcefile, it means toolchain did not use
561 # -fdebug-prefix-map to compile
562 if checkbuildpath(sourcefile, d):
563 localsrc_prefix = workparentdir + "/"
564 else:
565 localsrc_prefix = "/usr/src/debug/"
566
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500567 nosuchdir = []
568 basepath = dvar
569 for p in debugsrcdir.split("/"):
570 basepath = basepath + "/" + p
571 if not cpath.exists(basepath):
572 nosuchdir.append(basepath)
573 bb.utils.mkdirhier(basepath)
574 cpath.updatecache(basepath)
575
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500576 # Ignore files from the recipe sysroots (target and native)
577 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500578 # We need to ignore files that are not actually ours
579 # we do this by only paying attention to items from this package
580 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500581 # Remove prefix in the source paths
582 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500583 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
584
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500585 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800586 try:
587 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
588 except subprocess.CalledProcessError:
589 # Can "fail" if internal headers/transient sources are attempted
590 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500591
592 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
593 # Work around this by manually finding and copying any symbolic links that made it through.
Brad Bishop19323692019-04-05 15:28:33 -0400594 cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s')" % \
595 (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800596 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500597
598 # The copy by cpio may have resulted in some empty directories! Remove these
599 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800600 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500601
602 # Also remove debugsrcdir if its empty
603 for p in nosuchdir[::-1]:
604 if os.path.exists(p) and not os.listdir(p):
605 os.rmdir(p)
606
607#
608# Package data handling routines
609#
610
Andrew Geissler82c905d2020-04-13 13:39:40 -0500611def get_package_mapping (pkg, basepkg, d, depversions=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500612 import oe.packagedata
613
614 data = oe.packagedata.read_subpkgdata(pkg, d)
Patrick Williams213cb262021-08-07 19:21:33 -0500615 key = "PKG:%s" % pkg
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500616
617 if key in data:
Andrew Geissler595f6302022-01-24 19:11:47 +0000618 if bb.data.inherits_class('allarch', d) and bb.data.inherits_class('packagegroup', d) and pkg != data[key]:
619 bb.error("An allarch packagegroup shouldn't depend on packages which are dynamically renamed (%s to %s)" % (pkg, data[key]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500620 # Have to avoid undoing the write_extra_pkgs(global_variants...)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800621 if bb.data.inherits_class('allarch', d) and not d.getVar('MULTILIB_VARIANTS') \
622 and data[key] == basepkg:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623 return pkg
Andrew Geissler82c905d2020-04-13 13:39:40 -0500624 if depversions == []:
625 # Avoid returning a mapping if the renamed package rprovides its original name
Patrick Williams213cb262021-08-07 19:21:33 -0500626 rprovkey = "RPROVIDES:%s" % pkg
Andrew Geissler82c905d2020-04-13 13:39:40 -0500627 if rprovkey in data:
628 if pkg in bb.utils.explode_dep_versions2(data[rprovkey]):
629 bb.note("%s rprovides %s, not replacing the latter" % (data[key], pkg))
630 return pkg
631 # Do map to rewritten package name
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500632 return data[key]
633
634 return pkg
635
636def get_package_additional_metadata (pkg_type, d):
637 base_key = "PACKAGE_ADD_METADATA"
638 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
639 if d.getVar(key, False) is None:
640 continue
641 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500642 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500643 d.setVarFlag(key, "separator", "\\n")
644 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
645 return "\n".join(metadata_fields).strip()
646
647def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500648 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500649
650 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500651 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Andrew Geissler82c905d2020-04-13 13:39:40 -0500652 for depend, depversions in deps.items():
653 new_depend = get_package_mapping(depend, pkg, d, depversions)
654 if depend != new_depend:
655 bb.note("package name mapping done: %s -> %s" % (depend, new_depend))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500656 new_depends[new_depend] = deps[depend]
657
658 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
659
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500660 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500661
662#
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500663# Used by do_packagedata (and possibly other routines post do_package)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664#
665
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500666package_get_auto_pr[vardepsexclude] = "BB_TASKDEPDATA"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667python package_get_auto_pr() {
668 import oe.prservice
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500669
670 def get_do_package_hash(pn):
671 if d.getVar("BB_RUNTASK") != "do_package":
672 taskdepdata = d.getVar("BB_TASKDEPDATA", False)
673 for dep in taskdepdata:
674 if taskdepdata[dep][1] == "do_package" and taskdepdata[dep][0] == pn:
675 return taskdepdata[dep][6]
676 return None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500677
678 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500679 pn = d.getVar('PN')
680 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500681 if not (host is None):
682 d.setVar("PRSERV_HOST", host)
683
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500684 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500685
686 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500687 if not d.getVar('PRSERV_HOST'):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500688 d.setVar("PRSERV_PV_AUTOINC", "0")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500689 return
690
691 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500692 pv = d.getVar("PV")
693 version = d.getVar("PRAUTOINX")
694 pkgarch = d.getVar("PACKAGE_ARCH")
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500695 checksum = get_do_package_hash(pn)
696
697 # If do_package isn't in the dependencies, we can't get the checksum...
698 if not checksum:
699 bb.warn('Task %s requested do_package unihash, but it was not available.' % d.getVar('BB_RUNTASK'))
700 #taskdepdata = d.getVar("BB_TASKDEPDATA", False)
701 #for dep in taskdepdata:
702 # bb.warn('%s:%s = %s' % (taskdepdata[dep][0], taskdepdata[dep][1], taskdepdata[dep][6]))
703 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500704
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500705 if d.getVar('PRSERV_LOCKDOWN'):
706 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500707 if auto_pr is None:
708 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
709 d.setVar('PRAUTO',str(auto_pr))
710 return
711
712 try:
Andrew Geisslerd159c7f2021-09-02 21:05:58 -0500713 conn = oe.prservice.prserv_make_conn(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500714 if conn is not None:
715 if "AUTOINC" in pkgv:
716 srcpv = bb.fetch2.get_srcrev(d)
717 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
718 value = conn.getPR(base_ver, pkgarch, srcpv)
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500719 d.setVar("PRSERV_PV_AUTOINC", str(value))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500720
721 auto_pr = conn.getPR(version, pkgarch, checksum)
Andrew Geisslerd159c7f2021-09-02 21:05:58 -0500722 conn.close()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500723 except Exception as e:
724 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
725 if auto_pr is None:
726 bb.fatal("Can NOT get PRAUTO from remote PR service")
727 d.setVar('PRAUTO',str(auto_pr))
728}
729
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500730#
731# Package functions suitable for inclusion in PACKAGEFUNCS
732#
733
734python package_convert_pr_autoinc() {
735 pkgv = d.getVar("PKGV")
736
737 # Adjust pkgv as necessary...
738 if 'AUTOINC' in pkgv:
739 d.setVar("PKGV", pkgv.replace("AUTOINC", "${PRSERV_PV_AUTOINC}"))
740
741 # Change PRSERV_PV_AUTOINC and EXTENDPRAUTO usage to special values
742 d.setVar('PRSERV_PV_AUTOINC', '@PRSERV_PV_AUTOINC@')
743 d.setVar('EXTENDPRAUTO', '@EXTENDPRAUTO@')
744}
745
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500746LOCALEBASEPN ??= "${PN}"
747
748python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500749 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750 bb.debug(1, "package requested not splitting locales")
751 return
752
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500753 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500754
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500755 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500756 if not datadir:
757 bb.note("datadir not defined")
758 return
759
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500760 dvar = d.getVar('PKGD')
761 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500762
763 if pn + '-locale' in packages:
764 packages.remove(pn + '-locale')
765
766 localedir = os.path.join(dvar + datadir, 'locale')
767
768 if not cpath.isdir(localedir):
769 bb.debug(1, "No locale files in this package")
770 return
771
772 locales = os.listdir(localedir)
773
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500774 summary = d.getVar('SUMMARY') or pn
775 description = d.getVar('DESCRIPTION') or ""
776 locale_section = d.getVar('LOCALE_SECTION')
777 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500778 for l in sorted(locales):
779 ln = legitimize_package_name(l)
780 pkg = pn + '-locale-' + ln
781 packages.append(pkg)
Patrick Williams213cb262021-08-07 19:21:33 -0500782 d.setVar('FILES:' + pkg, os.path.join(datadir, 'locale', l))
783 d.setVar('RRECOMMENDS:' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
784 d.setVar('RPROVIDES:' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
785 d.setVar('SUMMARY:' + pkg, '%s - %s translations' % (summary, l))
786 d.setVar('DESCRIPTION:' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500787 if locale_section:
Patrick Williams213cb262021-08-07 19:21:33 -0500788 d.setVar('SECTION:' + pkg, locale_section)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500789
790 d.setVar('PACKAGES', ' '.join(packages))
791
792 # Disabled by RP 18/06/07
793 # Wildcards aren't supported in debian
794 # They break with ipkg since glibc-locale* will mean that
795 # glibc-localedata-translit* won't install as a dependency
796 # for some other package which breaks meta-toolchain
797 # Probably breaks since virtual-locale- isn't provided anywhere
Patrick Williams213cb262021-08-07 19:21:33 -0500798 #rdep = (d.getVar('RDEPENDS:%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500799 #rdep.append('%s-locale*' % pn)
Patrick Williams213cb262021-08-07 19:21:33 -0500800 #d.setVar('RDEPENDS:%s' % pn, ' '.join(rdep))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500801}
802
803python perform_packagecopy () {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800804 import subprocess
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600805 import shutil
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800806
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500807 dest = d.getVar('D')
808 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500809
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600810 # Remove ${D}/sysroot-only if present
811 sysroot_only = os.path.join(dest, 'sysroot-only')
812 if cpath.exists(sysroot_only) and cpath.isdir(sysroot_only):
813 shutil.rmtree(sysroot_only)
814
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500815 # Start by package population by taking a copy of the installed
816 # files to operate on
817 # Preserve sparse files and hard links
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800818 cmd = 'tar -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar)
819 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500820
821 # replace RPATHs for the nativesdk binaries, to make them relocatable
822 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
823 rpath_replace (dvar, d)
824}
825perform_packagecopy[cleandirs] = "${PKGD}"
826perform_packagecopy[dirs] = "${PKGD}"
827
828# We generate a master list of directories to process, we start by
829# seeding this list with reasonable defaults, then load from
830# the fs-perms.txt files
831python fixup_perms () {
832 import pwd, grp
833
834 # init using a string with the same format as a line as documented in
835 # the fs-perms.txt file
836 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
837 # <path> link <link target>
838 #
839 # __str__ can be used to print out an entry in the input format
840 #
841 # if fs_perms_entry.path is None:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400842 # an error occurred
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500843 # if fs_perms_entry.link, you can retrieve:
844 # fs_perms_entry.path = path
845 # fs_perms_entry.link = target of link
846 # if not fs_perms_entry.link, you can retrieve:
847 # fs_perms_entry.path = path
848 # fs_perms_entry.mode = expected dir mode or None
849 # fs_perms_entry.uid = expected uid or -1
850 # fs_perms_entry.gid = expected gid or -1
851 # fs_perms_entry.walk = 'true' or something else
852 # fs_perms_entry.fmode = expected file mode or None
853 # fs_perms_entry.fuid = expected file uid or -1
854 # fs_perms_entry_fgid = expected file gid or -1
855 class fs_perms_entry():
856 def __init__(self, line):
857 lsplit = line.split()
858 if len(lsplit) == 3 and lsplit[1].lower() == "link":
859 self._setlink(lsplit[0], lsplit[2])
860 elif len(lsplit) == 8:
861 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
862 else:
863 msg = "Fixup Perms: invalid config line %s" % line
Andrew Geisslereff27472021-10-29 15:35:00 -0500864 oe.qa.handle_error("perm-config", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500865 self.path = None
866 self.link = None
867
868 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
869 self.path = os.path.normpath(path)
870 self.link = None
871 self.mode = self._procmode(mode)
872 self.uid = self._procuid(uid)
873 self.gid = self._procgid(gid)
874 self.walk = walk.lower()
875 self.fmode = self._procmode(fmode)
876 self.fuid = self._procuid(fuid)
877 self.fgid = self._procgid(fgid)
878
879 def _setlink(self, path, link):
880 self.path = os.path.normpath(path)
881 self.link = link
882
883 def _procmode(self, mode):
884 if not mode or (mode and mode == "-"):
885 return None
886 else:
887 return int(mode,8)
888
889 # Note uid/gid -1 has special significance in os.lchown
890 def _procuid(self, uid):
891 if uid is None or uid == "-":
892 return -1
893 elif uid.isdigit():
894 return int(uid)
895 else:
896 return pwd.getpwnam(uid).pw_uid
897
898 def _procgid(self, gid):
899 if gid is None or gid == "-":
900 return -1
901 elif gid.isdigit():
902 return int(gid)
903 else:
904 return grp.getgrnam(gid).gr_gid
905
906 # Use for debugging the entries
907 def __str__(self):
908 if self.link:
909 return "%s link %s" % (self.path, self.link)
910 else:
911 mode = "-"
912 if self.mode:
913 mode = "0%o" % self.mode
914 fmode = "-"
915 if self.fmode:
916 fmode = "0%o" % self.fmode
917 uid = self._mapugid(self.uid)
918 gid = self._mapugid(self.gid)
919 fuid = self._mapugid(self.fuid)
920 fgid = self._mapugid(self.fgid)
921 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
922
923 def _mapugid(self, id):
924 if id is None or id == -1:
925 return "-"
926 else:
927 return "%d" % id
928
929 # Fix the permission, owner and group of path
930 def fix_perms(path, mode, uid, gid, dir):
931 if mode and not os.path.islink(path):
932 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
933 os.chmod(path, mode)
934 # -1 is a special value that means don't change the uid/gid
935 # if they are BOTH -1, don't bother to lchown
936 if not (uid == -1 and gid == -1):
937 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
938 os.lchown(path, uid, gid)
939
940 # Return a list of configuration files based on either the default
941 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
942 # paths are resolved via BBPATH
943 def get_fs_perms_list(d):
944 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500945 bbpath = d.getVar('BBPATH')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500946 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500947 for conf_file in fs_perms_tables.split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800948 confpath = bb.utils.which(bbpath, conf_file)
949 if confpath:
950 str += " %s" % bb.utils.which(bbpath, conf_file)
951 else:
952 bb.warn("cannot find %s specified in FILESYSTEM_PERMS_TABLES" % conf_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500953 return str
954
955
956
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500957 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500958
959 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500960 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500961
962 # By default all of the standard directories specified in
963 # bitbake.conf will get 0755 root:root.
964 target_path_vars = [ 'base_prefix',
965 'prefix',
966 'exec_prefix',
967 'base_bindir',
968 'base_sbindir',
969 'base_libdir',
970 'datadir',
971 'sysconfdir',
972 'servicedir',
973 'sharedstatedir',
974 'localstatedir',
975 'infodir',
976 'mandir',
977 'docdir',
978 'bindir',
979 'sbindir',
980 'libexecdir',
981 'libdir',
982 'includedir',
983 'oldincludedir' ]
984
985 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500986 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500987 if dir == "":
988 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500989 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500990
991 # Now we actually load from the configuration files
992 for conf in get_fs_perms_list(d).split():
Brad Bishop64c979e2019-11-04 13:55:29 -0500993 if not os.path.exists(conf):
994 continue
995 with open(conf) as f:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500996 for line in f:
997 if line.startswith('#'):
998 continue
999 lsplit = line.split()
1000 if len(lsplit) == 0:
1001 continue
1002 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
1003 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
Andrew Geisslereff27472021-10-29 15:35:00 -05001004 oe.qa.handle_error("perm-line", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001005 continue
1006 entry = fs_perms_entry(d.expand(line))
1007 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001008 if entry.link:
1009 fs_link_table[entry.path] = entry
1010 if entry.path in fs_perms_table:
1011 fs_perms_table.pop(entry.path)
1012 else:
1013 fs_perms_table[entry.path] = entry
1014 if entry.path in fs_link_table:
1015 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001016
1017 # Debug -- list out in-memory table
1018 #for dir in fs_perms_table:
1019 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001020 #for link in fs_link_table:
1021 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001022
1023 # We process links first, so we can go back and fixup directory ownership
1024 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001025 # Process in sorted order so /run gets created before /run/lock, etc.
1026 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
1027 link = entry.link
1028 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001029 origin = dvar + dir
1030 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
1031 continue
1032
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001033 if link[0] == "/":
1034 target = dvar + link
1035 ptarget = link
1036 else:
1037 target = os.path.join(os.path.dirname(origin), link)
1038 ptarget = os.path.join(os.path.dirname(dir), link)
1039 if os.path.exists(target):
1040 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
Andrew Geisslereff27472021-10-29 15:35:00 -05001041 oe.qa.handle_error("perm-link", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001042 continue
1043
1044 # Create path to move directory to, move it, and then setup the symlink
1045 bb.utils.mkdirhier(os.path.dirname(target))
1046 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
Andrew Geisslerc926e172021-05-07 16:11:35 -05001047 bb.utils.rename(origin, target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001048 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
1049 os.symlink(link, origin)
1050
1051 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001052 origin = dvar + dir
1053 if not (cpath.exists(origin) and cpath.isdir(origin)):
1054 continue
1055
1056 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
1057
1058 if fs_perms_table[dir].walk == 'true':
1059 for root, dirs, files in os.walk(origin):
1060 for dr in dirs:
1061 each_dir = os.path.join(root, dr)
1062 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
1063 for f in files:
1064 each_file = os.path.join(root, f)
1065 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
1066}
1067
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001068def package_debug_vars(d):
1069 # We default to '.debug' style
1070 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
1071 # Single debug-file-directory style debug info
1072 debug_vars = {
1073 "append": ".debug",
1074 "staticappend": "",
1075 "dir": "",
1076 "staticdir": "",
1077 "libdir": "/usr/lib/debug",
1078 "staticlibdir": "/usr/lib/debug-static",
1079 "srcdir": "/usr/src/debug",
1080 }
1081 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
1082 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
1083 debug_vars = {
1084 "append": "",
1085 "staticappend": "",
1086 "dir": "/.debug",
1087 "staticdir": "/.debug-static",
1088 "libdir": "",
1089 "staticlibdir": "",
1090 "srcdir": "",
1091 }
1092 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
1093 debug_vars = {
1094 "append": "",
1095 "staticappend": "",
1096 "dir": "/.debug",
1097 "staticdir": "/.debug-static",
1098 "libdir": "",
1099 "staticlibdir": "",
1100 "srcdir": "/usr/src/debug",
1101 }
1102 else:
1103 # Original OE-core, a.k.a. ".debug", style debug info
1104 debug_vars = {
1105 "append": "",
1106 "staticappend": "",
1107 "dir": "/.debug",
1108 "staticdir": "/.debug-static",
1109 "libdir": "",
1110 "staticlibdir": "",
1111 "srcdir": "/usr/src/debug",
1112 }
1113
1114 return debug_vars
1115
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001116python split_and_strip_files () {
1117 import stat, errno
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001118 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001119
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001120 dvar = d.getVar('PKGD')
1121 pn = d.getVar('PN')
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001122 hostos = d.getVar('HOST_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001123
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001124 oldcwd = os.getcwd()
1125 os.chdir(dvar)
1126
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001127 dv = package_debug_vars(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001128
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001129 #
1130 # First lets figure out all of the files we may have to process ... do this only once!
1131 #
1132 elffiles = {}
1133 symlinks = {}
Brad Bishop316dfdd2018-06-25 12:45:53 -04001134 staticlibs = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001135 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001136 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
1137 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
Brad Bishop316dfdd2018-06-25 12:45:53 -04001138 skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001139 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
1140 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001141 checkelf = {}
1142 checkelflinks = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001143 for root, dirs, files in cpath.walk(dvar):
1144 for f in files:
1145 file = os.path.join(root, f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001146
1147 # Skip debug files
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001148 if dv["append"] and file.endswith(dv["append"]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001149 continue
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001150 if dv["dir"] and dv["dir"] in os.path.dirname(file[len(dvar):]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001151 continue
1152
Brad Bishop316dfdd2018-06-25 12:45:53 -04001153 if file in skipfiles:
1154 continue
1155
Andrew Geissler82c905d2020-04-13 13:39:40 -05001156 if oe.package.is_static_lib(file):
1157 staticlibs.append(file)
1158 continue
1159
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001160 try:
1161 ltarget = cpath.realpath(file, dvar, False)
1162 s = cpath.lstat(ltarget)
1163 except OSError as e:
1164 (err, strerror) = e.args
1165 if err != errno.ENOENT:
1166 raise
1167 # Skip broken symlinks
1168 continue
1169 if not s:
1170 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -04001171 # Check its an executable
Andrew Geissler595f6302022-01-24 19:11:47 +00001172 if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) \
1173 or (s[stat.ST_MODE] & stat.S_IXOTH) \
1174 or ((file.startswith(libdir) or file.startswith(baselibdir)) \
1175 and (".so" in f or ".node" in f)) \
1176 or (f.startswith('vmlinux') or ".ko" in f):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001177
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001178 if cpath.islink(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001179 checkelflinks[file] = ltarget
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001180 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001181 # Use a reference of device ID and inode number to identify files
1182 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
1183 checkelf[file] = (file, file_reference)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001184
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001185 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d)
1186 results_map = {}
1187 for (ltarget, elf_file) in results:
1188 results_map[ltarget] = elf_file
1189 for file in checkelflinks:
1190 ltarget = checkelflinks[file]
1191 # If it's a symlink, and points to an ELF file, we capture the readlink target
1192 if results_map[ltarget]:
1193 target = os.readlink(file)
1194 #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget]))
1195 symlinks[file] = target
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001196
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001197 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d)
Brad Bishop15ae2502019-06-18 21:44:24 -04001198
1199 # Sort results by file path. This ensures that the files are always
1200 # processed in the same order, which is important to make sure builds
1201 # are reproducible when dealing with hardlinks
1202 results.sort(key=lambda x: x[0])
1203
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001204 for (file, elf_file) in results:
1205 # It's a file (or hardlink), not a link
1206 # ...but is it ELF, and is it already stripped?
1207 if elf_file & 1:
1208 if elf_file & 2:
Patrick Williams213cb262021-08-07 19:21:33 -05001209 if 'already-stripped' in (d.getVar('INSANE_SKIP:' + pn) or "").split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001210 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1211 else:
1212 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
Andrew Geisslereff27472021-10-29 15:35:00 -05001213 oe.qa.handle_error("already-stripped", msg, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001214 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001215
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001216 # At this point we have an unstripped elf file. We need to:
1217 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1218 # b) Only strip any hardlinked file once (no races)
1219 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1220
1221 # Use a reference of device ID and inode number to identify files
1222 file_reference = checkelf[file][1]
1223 if file_reference in inodes:
1224 os.unlink(file)
1225 os.link(inodes[file_reference][0], file)
1226 inodes[file_reference].append(file)
1227 else:
1228 inodes[file_reference] = [file]
1229 # break hardlink
1230 bb.utils.break_hardlinks(file)
1231 elffiles[file] = elf_file
1232 # Modified the file so clear the cache
1233 cpath.updatecache(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001234
Andrew Geissler5199d832021-09-24 16:47:35 -05001235 def strip_pkgd_prefix(f):
1236 nonlocal dvar
1237
1238 if f.startswith(dvar):
1239 return f[len(dvar):]
1240
1241 return f
1242
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001243 #
1244 # First lets process debug splitting
1245 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001246 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001247 results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, dv, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001248
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001249 if dv["srcdir"] and not hostos.startswith("mingw"):
Andrew Geissler82c905d2020-04-13 13:39:40 -05001250 if (d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001251 results = oe.utils.multiprocess_launch(splitstaticdebuginfo, staticlibs, d, extraargs=(dvar, dv, d))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001252 else:
1253 for file in staticlibs:
1254 results.append( (file,source_info(file, d)) )
Brad Bishop19323692019-04-05 15:28:33 -04001255
Andrew Geissler5199d832021-09-24 16:47:35 -05001256 d.setVar("PKGDEBUGSOURCES", {strip_pkgd_prefix(f): sorted(s) for f, s in results})
1257
Brad Bishop19323692019-04-05 15:28:33 -04001258 sources = set()
1259 for r in results:
1260 sources.update(r[1])
Brad Bishop316dfdd2018-06-25 12:45:53 -04001261
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001262 # Hardlink our debug symbols to the other hardlink copies
1263 for ref in inodes:
1264 if len(inodes[ref]) == 1:
1265 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001266
1267 target = inodes[ref][0][len(dvar):]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001268 for file in inodes[ref][1:]:
1269 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001270 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(target) + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001271 fpath = dvar + dest
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001272 ftarget = dvar + dv["libdir"] + os.path.dirname(target) + dv["dir"] + "/" + os.path.basename(target) + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001273 bb.utils.mkdirhier(os.path.dirname(fpath))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001274 # Only one hardlink of separated debug info file in each directory
1275 if not os.access(fpath, os.R_OK):
1276 #bb.note("Link %s -> %s" % (fpath, ftarget))
1277 os.link(ftarget, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001278
1279 # Create symlinks for all cases we were able to split symbols
1280 for file in symlinks:
1281 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001282 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(src) + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001283 fpath = dvar + dest
1284 # Skip it if the target doesn't exist
1285 try:
1286 s = os.stat(fpath)
1287 except OSError as e:
1288 (err, strerror) = e.args
1289 if err != errno.ENOENT:
1290 raise
1291 continue
1292
1293 ltarget = symlinks[file]
1294 lpath = os.path.dirname(ltarget)
1295 lbase = os.path.basename(ltarget)
1296 ftarget = ""
1297 if lpath and lpath != ".":
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001298 ftarget += lpath + dv["dir"] + "/"
1299 ftarget += lbase + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001300 if lpath.startswith(".."):
1301 ftarget = os.path.join("..", ftarget)
1302 bb.utils.mkdirhier(os.path.dirname(fpath))
1303 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1304 os.symlink(ftarget, fpath)
1305
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001306 # Process the dv["srcdir"] if requested...
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001307 # This copies and places the referenced sources for later debugging...
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001308 copydebugsources(dv["srcdir"], sources, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001309 #
1310 # End of debug splitting
1311 #
1312
1313 #
1314 # Now lets go back over things and strip them
1315 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001316 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1317 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001318 sfiles = []
1319 for file in elffiles:
1320 elf_file = int(elffiles[file])
1321 #bb.note("Strip %s" % file)
1322 sfiles.append((file, elf_file, strip))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001323 if (d.getVar('PACKAGE_STRIP_STATIC') == '1' or d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'):
1324 for f in staticlibs:
1325 sfiles.append((f, 16, strip))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001326
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001327 oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001328
Andrew Geissler82c905d2020-04-13 13:39:40 -05001329 # Build "minidebuginfo" and reinject it back into the stripped binaries
1330 if d.getVar('PACKAGE_MINIDEBUGINFO') == '1':
1331 oe.utils.multiprocess_launch(inject_minidebuginfo, list(elffiles), d,
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001332 extraargs=(dvar, dv, d))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001333
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001334 #
1335 # End of strip
1336 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001337 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001338}
1339
1340python populate_packages () {
1341 import glob, re
1342
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001343 workdir = d.getVar('WORKDIR')
1344 outdir = d.getVar('DEPLOY_DIR')
1345 dvar = d.getVar('PKGD')
Brad Bishop19323692019-04-05 15:28:33 -04001346 packages = d.getVar('PACKAGES').split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001347 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001348
1349 bb.utils.mkdirhier(outdir)
1350 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001351
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001352 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001353
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001354 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1355
Brad Bishop19323692019-04-05 15:28:33 -04001356 # If debug-with-srcpkg mode is enabled then add the source package if it
1357 # doesn't exist and add the source file contents to the source package.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001358 if split_source_package:
1359 src_package_name = ('%s-src' % d.getVar('PN'))
Brad Bishop19323692019-04-05 15:28:33 -04001360 if not src_package_name in packages:
1361 packages.append(src_package_name)
Patrick Williams213cb262021-08-07 19:21:33 -05001362 d.setVar('FILES:%s' % src_package_name, '/usr/src/debug')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001363
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001364 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001365 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001366 package_dict = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001367
Brad Bishop19323692019-04-05 15:28:33 -04001368 for i, pkg in enumerate(packages):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001369 if pkg in package_dict:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001370 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
Andrew Geisslereff27472021-10-29 15:35:00 -05001371 oe.qa.handle_error("packages-list", msg, d)
Brad Bishop19323692019-04-05 15:28:33 -04001372 # Ensure the source package gets the chance to pick up the source files
1373 # before the debug package by ordering it first in PACKAGES. Whether it
1374 # actually picks up any source files is controlled by
1375 # PACKAGE_DEBUG_SPLIT_STYLE.
1376 elif pkg.endswith("-src"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001377 package_dict[pkg] = (10, i)
1378 elif autodebug and pkg.endswith("-dbg"):
1379 package_dict[pkg] = (30, i)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001380 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001381 package_dict[pkg] = (50, i)
Brad Bishop19323692019-04-05 15:28:33 -04001382 packages = sorted(package_dict.keys(), key=package_dict.get)
1383 d.setVar('PACKAGES', ' '.join(packages))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001384 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001385
1386 seen = []
1387
1388 # os.mkdir masks the permissions with umask so we have to unset it first
1389 oldumask = os.umask(0)
1390
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001391 debug = []
1392 for root, dirs, files in cpath.walk(dvar):
1393 dir = root[len(dvar):]
1394 if not dir:
1395 dir = os.sep
1396 for f in (files + dirs):
1397 path = "." + os.path.join(dir, f)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001398 if "/.debug/" in path or "/.debug-static/" in path or path.endswith("/.debug"):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001399 debug.append(path)
1400
Brad Bishop19323692019-04-05 15:28:33 -04001401 for pkg in packages:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001402 root = os.path.join(pkgdest, pkg)
1403 bb.utils.mkdirhier(root)
1404
Patrick Williams213cb262021-08-07 19:21:33 -05001405 filesvar = d.getVar('FILES:%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001406 if "//" in filesvar:
1407 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
Andrew Geisslereff27472021-10-29 15:35:00 -05001408 oe.qa.handle_error("files-invalid", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001409 filesvar.replace("//", "/")
1410
1411 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001412 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001413
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001414 if autodebug and pkg.endswith("-dbg"):
1415 files.extend(debug)
1416
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001417 for file in files:
1418 if (not cpath.islink(file)) and (not cpath.exists(file)):
1419 continue
1420 if file in seen:
1421 continue
1422 seen.append(file)
1423
1424 def mkdir(src, dest, p):
1425 src = os.path.join(src, p)
1426 dest = os.path.join(dest, p)
1427 fstat = cpath.stat(src)
Brad Bishop96ff1982019-08-19 13:50:42 -04001428 os.mkdir(dest)
1429 os.chmod(dest, fstat.st_mode)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001430 os.chown(dest, fstat.st_uid, fstat.st_gid)
1431 if p not in seen:
1432 seen.append(p)
1433 cpath.updatecache(dest)
1434
1435 def mkdir_recurse(src, dest, paths):
1436 if cpath.exists(dest + '/' + paths):
1437 return
1438 while paths.startswith("./"):
1439 paths = paths[2:]
1440 p = "."
1441 for c in paths.split("/"):
1442 p = os.path.join(p, c)
1443 if not cpath.exists(os.path.join(dest, p)):
1444 mkdir(src, dest, p)
1445
1446 if cpath.isdir(file) and not cpath.islink(file):
1447 mkdir_recurse(dvar, root, file)
1448 continue
1449
1450 mkdir_recurse(dvar, root, os.path.dirname(file))
1451 fpath = os.path.join(root,file)
1452 if not cpath.islink(file):
1453 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001454 continue
1455 ret = bb.utils.copyfile(file, fpath)
1456 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001457 bb.fatal("File population failed")
1458
1459 # Check if symlink paths exist
1460 for file in symlink_paths:
1461 if not os.path.exists(os.path.join(root,file)):
1462 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1463 "parent directory structure does not exist. One of "
1464 "its parent directories is a symlink whose target "
1465 "directory is not included in the package." %
1466 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001467
1468 os.umask(oldumask)
1469 os.chdir(workdir)
1470
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001471 # Handle excluding packages with incompatible licenses
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001472 package_list = []
Brad Bishop19323692019-04-05 15:28:33 -04001473 for pkg in packages:
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001474 licenses = d.getVar('_exclude_incompatible-' + pkg)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001475 if licenses:
1476 msg = "Excluding %s from packaging as it has incompatible license(s): %s" % (pkg, licenses)
Andrew Geisslereff27472021-10-29 15:35:00 -05001477 oe.qa.handle_error("incompatible-license", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001478 else:
1479 package_list.append(pkg)
1480 d.setVar('PACKAGES', ' '.join(package_list))
1481
1482 unshipped = []
1483 for root, dirs, files in cpath.walk(dvar):
1484 dir = root[len(dvar):]
1485 if not dir:
1486 dir = os.sep
1487 for f in (files + dirs):
1488 path = os.path.join(dir, f)
1489 if ('.' + path) not in seen:
1490 unshipped.append(path)
1491
1492 if unshipped != []:
1493 msg = pn + ": Files/directories were installed but not shipped in any package:"
Patrick Williams213cb262021-08-07 19:21:33 -05001494 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP:' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001495 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1496 else:
1497 for f in unshipped:
1498 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001499 msg = msg + "\nPlease set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install.\n"
1500 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Andrew Geisslereff27472021-10-29 15:35:00 -05001501 oe.qa.handle_error("installed-vs-shipped", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001502}
1503populate_packages[dirs] = "${D}"
1504
1505python package_fixsymlinks () {
1506 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001507 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001508 packages = d.getVar("PACKAGES", False).split()
1509
1510 dangling_links = {}
1511 pkg_files = {}
1512 for pkg in packages:
1513 dangling_links[pkg] = []
1514 pkg_files[pkg] = []
1515 inst_root = os.path.join(pkgdest, pkg)
1516 for path in pkgfiles[pkg]:
1517 rpath = path[len(inst_root):]
1518 pkg_files[pkg].append(rpath)
1519 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1520 if not cpath.lexists(rtarget):
1521 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1522
1523 newrdepends = {}
1524 for pkg in dangling_links:
1525 for l in dangling_links[pkg]:
1526 found = False
1527 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1528 for p in packages:
1529 if l in pkg_files[p]:
1530 found = True
1531 bb.debug(1, "target found in %s" % p)
1532 if p == pkg:
1533 break
1534 if pkg not in newrdepends:
1535 newrdepends[pkg] = []
1536 newrdepends[pkg].append(p)
1537 break
1538 if found == False:
1539 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1540
1541 for pkg in newrdepends:
Patrick Williams213cb262021-08-07 19:21:33 -05001542 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001543 for p in newrdepends[pkg]:
1544 if p not in rdepends:
1545 rdepends[p] = []
Patrick Williams213cb262021-08-07 19:21:33 -05001546 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001547}
1548
1549
1550python package_package_name_hook() {
1551 """
1552 A package_name_hook function can be used to rewrite the package names by
1553 changing PKG. For an example, see debian.bbclass.
1554 """
1555 pass
1556}
1557
1558EXPORT_FUNCTIONS package_name_hook
1559
1560
1561PKGDESTWORK = "${WORKDIR}/pkgdata"
1562
Andrew Geissler1e34c2d2020-05-29 16:02:59 -05001563PKGDATA_VARS = "PN PE PV PR PKGE PKGV PKGR LICENSE DESCRIPTION SUMMARY RDEPENDS RPROVIDES RRECOMMENDS RSUGGESTS RREPLACES RCONFLICTS SECTION PKG ALLOW_EMPTY FILES CONFFILES FILES_INFO PACKAGE_ADD_METADATA pkg_postinst pkg_postrm pkg_preinst pkg_prerm"
Brad Bishop15ae2502019-06-18 21:44:24 -04001564
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001565python emit_pkgdata() {
1566 from glob import glob
1567 import json
Andrew Geissler5199d832021-09-24 16:47:35 -05001568 import bb.compress.zstd
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001569
Brad Bishop316dfdd2018-06-25 12:45:53 -04001570 def process_postinst_on_target(pkg, mlprefix):
Patrick Williams213cb262021-08-07 19:21:33 -05001571 pkgval = d.getVar('PKG:%s' % pkg)
Brad Bishop96ff1982019-08-19 13:50:42 -04001572 if pkgval is None:
1573 pkgval = pkg
1574
Brad Bishop316dfdd2018-06-25 12:45:53 -04001575 defer_fragment = """
1576if [ -n "$D" ]; then
1577 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1578 exit 0
1579fi
Brad Bishop96ff1982019-08-19 13:50:42 -04001580""" % (pkgval, mlprefix)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001581
Patrick Williams213cb262021-08-07 19:21:33 -05001582 postinst = d.getVar('pkg_postinst:%s' % pkg)
1583 postinst_ontarget = d.getVar('pkg_postinst_ontarget:%s' % pkg)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001584
1585 if postinst_ontarget:
1586 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1587 if not postinst:
1588 postinst = '#!/bin/sh\n'
1589 postinst += defer_fragment
1590 postinst += postinst_ontarget
Patrick Williams213cb262021-08-07 19:21:33 -05001591 d.setVar('pkg_postinst:%s' % pkg, postinst)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001592
1593 def add_set_e_to_scriptlets(pkg):
1594 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
Patrick Williams213cb262021-08-07 19:21:33 -05001595 scriptlet = d.getVar('%s:%s' % (scriptlet_name, pkg))
Brad Bishop316dfdd2018-06-25 12:45:53 -04001596 if scriptlet:
1597 scriptlet_split = scriptlet.split('\n')
1598 if scriptlet_split[0].startswith("#!"):
1599 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1600 else:
1601 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
Patrick Williams213cb262021-08-07 19:21:33 -05001602 d.setVar('%s:%s' % (scriptlet_name, pkg), scriptlet)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001603
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001604 def write_if_exists(f, pkg, var):
1605 def encode(str):
1606 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001607 c = codecs.getencoder("unicode_escape")
1608 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001609
Patrick Williams213cb262021-08-07 19:21:33 -05001610 val = d.getVar('%s:%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001611 if val:
Patrick Williams213cb262021-08-07 19:21:33 -05001612 f.write('%s:%s: %s\n' % (var, pkg, encode(val)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001613 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001614 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001615 if val:
1616 f.write('%s: %s\n' % (var, encode(val)))
1617 return val
1618
1619 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1620 for variant in variants:
1621 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1622 fd.write("PACKAGES: %s\n" % ' '.join(
1623 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1624
1625 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1626 for variant in variants:
1627 for pkg in packages.split():
1628 ml_pkg = "%s-%s" % (variant, pkg)
1629 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1630 with open(subdata_file, 'w') as fd:
Patrick Williams213cb262021-08-07 19:21:33 -05001631 fd.write("PKG:%s: %s" % (ml_pkg, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001632
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001633 packages = d.getVar('PACKAGES')
1634 pkgdest = d.getVar('PKGDEST')
1635 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001636
Brad Bishop64c979e2019-11-04 13:55:29 -05001637 data_file = pkgdatadir + d.expand("/${PN}")
1638 with open(data_file, 'w') as fd:
1639 fd.write("PACKAGES: %s\n" % packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001640
Andrew Geissler5199d832021-09-24 16:47:35 -05001641 pkgdebugsource = d.getVar("PKGDEBUGSOURCES") or []
1642
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001643 pn = d.getVar('PN')
1644 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1645 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001646
1647 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1648 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1649
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001650 if bb.data.inherits_class('allarch', d) and not variants \
1651 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001652 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1653
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001654 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001655
1656 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05001657 pkgval = d.getVar('PKG:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001658 if pkgval is None:
1659 pkgval = pkg
Patrick Williams213cb262021-08-07 19:21:33 -05001660 d.setVar('PKG:%s' % pkg, pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001661
Andrew Geissler5199d832021-09-24 16:47:35 -05001662 extended_data = {
1663 "files_info": {}
1664 }
1665
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001666 pkgdestpkg = os.path.join(pkgdest, pkg)
1667 files = {}
Andrew Geissler5199d832021-09-24 16:47:35 -05001668 files_extra = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001669 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001670 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001671 for f in pkgfiles[pkg]:
Andrew Geissler5199d832021-09-24 16:47:35 -05001672 fpath = os.sep + os.path.relpath(f, pkgdestpkg)
1673
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001674 fstat = os.lstat(f)
Andrew Geissler5199d832021-09-24 16:47:35 -05001675 files[fpath] = fstat.st_size
1676
1677 extended_data["files_info"].setdefault(fpath, {})
1678 extended_data["files_info"][fpath]['size'] = fstat.st_size
1679
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001680 if fstat.st_ino not in seen:
1681 seen.add(fstat.st_ino)
1682 total_size += fstat.st_size
Andrew Geissler5199d832021-09-24 16:47:35 -05001683
1684 if fpath in pkgdebugsource:
1685 extended_data["files_info"][fpath]['debugsrc'] = pkgdebugsource[fpath]
1686 del pkgdebugsource[fpath]
1687
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001688 d.setVar('FILES_INFO:' + pkg , json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001689
Brad Bishop316dfdd2018-06-25 12:45:53 -04001690 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1691 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001692
Brad Bishop15ae2502019-06-18 21:44:24 -04001693 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1694 with open(subdata_file, 'w') as sf:
1695 for var in (d.getVar('PKGDATA_VARS') or "").split():
1696 val = write_if_exists(sf, pkg, var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001697
Brad Bishop15ae2502019-06-18 21:44:24 -04001698 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
Andrew Geissler5199d832021-09-24 16:47:35 -05001699 for dfile in sorted((d.getVar('FILERPROVIDESFLIST:' + pkg) or "").split()):
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001700 write_if_exists(sf, pkg, 'FILERPROVIDES:' + dfile)
Brad Bishop15ae2502019-06-18 21:44:24 -04001701
1702 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Andrew Geissler5199d832021-09-24 16:47:35 -05001703 for dfile in sorted((d.getVar('FILERDEPENDSFLIST:' + pkg) or "").split()):
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001704 write_if_exists(sf, pkg, 'FILERDEPENDS:' + dfile)
Brad Bishop15ae2502019-06-18 21:44:24 -04001705
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001706 sf.write('%s:%s: %d\n' % ('PKGSIZE', pkg, total_size))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001707
Andrew Geissler5199d832021-09-24 16:47:35 -05001708 subdata_extended_file = pkgdatadir + "/extended/%s.json.zstd" % pkg
1709 num_threads = int(d.getVar("BB_NUMBER_THREADS"))
1710 with bb.compress.zstd.open(subdata_extended_file, "wt", encoding="utf-8", num_threads=num_threads) as f:
1711 json.dump(extended_data, f, sort_keys=True, separators=(",", ":"))
1712
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001713 # Symlinks needed for rprovides lookup
Patrick Williams213cb262021-08-07 19:21:33 -05001714 rprov = d.getVar('RPROVIDES:%s' % pkg) or d.getVar('RPROVIDES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001715 if rprov:
Andrew Geisslerc9f78652020-09-18 14:11:35 -05001716 for p in bb.utils.explode_deps(rprov):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001717 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1718 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1719 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1720
Patrick Williams213cb262021-08-07 19:21:33 -05001721 allow_empty = d.getVar('ALLOW_EMPTY:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001722 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001723 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001724 root = "%s/%s" % (pkgdest, pkg)
1725 os.chdir(root)
1726 g = glob('*')
1727 if g or allow_empty == "1":
1728 # Symlinks needed for reverse lookups (from the final package name)
1729 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1730 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1731
1732 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1733 open(packagedfile, 'w').close()
1734
1735 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1736 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1737
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001738 if bb.data.inherits_class('allarch', d) and not variants \
1739 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001740 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1741
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001742}
Andrew Geissler5199d832021-09-24 16:47:35 -05001743emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides ${PKGDESTWORK}/extended"
1744emit_pkgdata[vardepsexclude] = "BB_NUMBER_THREADS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001745
1746ldconfig_postinst_fragment() {
1747if [ x"$D" = "x" ]; then
1748 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1749fi
1750}
1751
Andrew Geissler90fd73c2021-03-05 15:25:55 -06001752RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps --define '__font_provides %{nil}'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001753
1754# Collect perfile run-time dependency metadata
1755# Output:
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001756# FILERPROVIDESFLIST:pkg - list of all files w/ deps
1757# FILERPROVIDES:filepath:pkg - per file dep
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001758#
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001759# FILERDEPENDSFLIST:pkg - list of all files w/ deps
1760# FILERDEPENDS:filepath:pkg - per file dep
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001761
1762python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001763 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001764 return
1765
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001766 pkgdest = d.getVar('PKGDEST')
1767 packages = d.getVar('PACKAGES')
1768 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001769
1770 def chunks(files, n):
1771 return [files[i:i+n] for i in range(0, len(files), n)]
1772
1773 pkglist = []
1774 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05001775 if d.getVar('SKIP_FILEDEPS:' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001776 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001777 if pkg.endswith('-dbg') or pkg.endswith('-doc') or pkg.find('-locale-') != -1 or pkg.find('-localedata-') != -1 or pkg.find('-gconv-') != -1 or pkg.find('-charmap-') != -1 or pkg.startswith('kernel-module-') or pkg.endswith('-src'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001778 continue
1779 for files in chunks(pkgfiles[pkg], 100):
1780 pkglist.append((pkg, files, rpmdeps, pkgdest))
1781
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001782 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001783
1784 provides_files = {}
1785 requires_files = {}
1786
1787 for result in processed:
1788 (pkg, provides, requires) = result
1789
1790 if pkg not in provides_files:
1791 provides_files[pkg] = []
1792 if pkg not in requires_files:
1793 requires_files[pkg] = []
1794
Brad Bishop19323692019-04-05 15:28:33 -04001795 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001796 provides_files[pkg].append(file)
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001797 key = "FILERPROVIDES:" + file + ":" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001798 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001799
Brad Bishop19323692019-04-05 15:28:33 -04001800 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001801 requires_files[pkg].append(file)
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001802 key = "FILERDEPENDS:" + file + ":" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001803 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001804
1805 for pkg in requires_files:
Andrew Geissler5199d832021-09-24 16:47:35 -05001806 d.setVar("FILERDEPENDSFLIST:" + pkg, " ".join(sorted(requires_files[pkg])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001807 for pkg in provides_files:
Andrew Geissler5199d832021-09-24 16:47:35 -05001808 d.setVar("FILERPROVIDESFLIST:" + pkg, " ".join(sorted(provides_files[pkg])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001809}
1810
Brad Bishop96ff1982019-08-19 13:50:42 -04001811SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001812SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1813
1814python package_do_shlibs() {
Brad Bishop00e122a2019-10-05 11:10:57 -04001815 import itertools
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001816 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001817 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001818
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001819 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001820 if exclude_shlibs:
1821 bb.note("not generating shlibs")
1822 return
1823
Brad Bishop19323692019-04-05 15:28:33 -04001824 lib_re = re.compile(r"^.*\.so")
1825 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001826
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001827 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001828
1829 shlib_pkgs = []
1830 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1831 if exclusion_list:
1832 for pkg in packages.split():
1833 if pkg not in exclusion_list.split():
1834 shlib_pkgs.append(pkg)
1835 else:
1836 bb.note("not generating shlibs for %s" % pkg)
1837 else:
1838 shlib_pkgs = packages.split()
1839
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001840 hostos = d.getVar('HOST_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001841
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001842 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001843
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001844 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001845 if not ver:
1846 msg = "PKGV not defined"
Andrew Geisslereff27472021-10-29 15:35:00 -05001847 oe.qa.handle_error("pkgv-undefined", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001848 return
1849
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001850 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001851
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001852 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001853
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001854 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001855 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001856 needed = set()
1857 sonames = set()
1858 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001859 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001860 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001861 fd = os.popen(cmd)
1862 lines = fd.readlines()
1863 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001864 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001865 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001866 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001867 if m:
1868 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001869 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001870 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001871 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001872 if m:
1873 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001874 if dep not in needed:
1875 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001876 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001877 if m:
1878 this_soname = m.group(1)
1879 prov = (this_soname, ldir, pkgver)
1880 if not prov in sonames:
1881 # if library is private (only used by package) then do not build shlib for it
Brad Bishop79641f22019-09-10 07:20:22 -04001882 import fnmatch
1883 if not private_libs or len([i for i in private_libs if fnmatch.fnmatch(this_soname, i)]) == 0:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001884 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001885 if libdir_re.match(os.path.dirname(file)):
1886 needs_ldconfig = True
Andrew Geissler595f6302022-01-24 19:11:47 +00001887 if needs_ldconfig and snap_symlinks and (os.path.basename(file) != this_soname):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001888 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001889 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001890
1891 def darwin_so(file, needed, sonames, renames, pkgver):
1892 if not os.path.exists(file):
1893 return
1894 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1895
1896 def get_combinations(base):
1897 #
1898 # Given a base library name, find all combinations of this split by "." and "-"
1899 #
1900 combos = []
1901 options = base.split(".")
1902 for i in range(1, len(options) + 1):
1903 combos.append(".".join(options[0:i]))
1904 options = base.split("-")
1905 for i in range(1, len(options) + 1):
1906 combos.append("-".join(options[0:i]))
1907 return combos
1908
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001909 if (file.endswith('.dylib') or file.endswith('.so')) and not pkg.endswith('-dev') and not pkg.endswith('-dbg') and not pkg.endswith('-src'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001910 # Drop suffix
1911 name = os.path.basename(file).rsplit(".",1)[0]
1912 # Find all combinations
1913 combos = get_combinations(name)
1914 for combo in combos:
1915 if not combo in sonames:
1916 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001917 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001918 if file.endswith('.dylib') or file.endswith('.so'):
1919 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001920 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001921 out, err = p.communicate()
1922 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001923 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001924 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001925 l = l.strip()
1926 if l.startswith('path '):
1927 rpath.append(l.split()[1])
1928
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001929 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001930 out, err = p.communicate()
1931 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001932 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001933 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001934 l = l.strip()
1935 if not l or l.endswith(":"):
1936 continue
1937 if "is not an object file" in l:
1938 continue
1939 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1940 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001941 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001942
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001943 def mingw_dll(file, needed, sonames, renames, pkgver):
1944 if not os.path.exists(file):
1945 return
1946
1947 if file.endswith(".dll"):
1948 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001949 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001950
1951 if (file.endswith(".dll") or file.endswith(".exe")):
1952 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001953 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001954 out, err = p.communicate()
1955 # process the output, grabbing all .dll names
1956 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001957 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001958 dllname = m.group(1)
1959 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001960 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001961
1962 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001963 snap_symlinks = True
1964 else:
1965 snap_symlinks = False
1966
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001967 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001968
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001969 shlib_provider = oe.package.read_shlib_providers(d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001970
1971 for pkg in shlib_pkgs:
Patrick Williams213cb262021-08-07 19:21:33 -05001972 private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001973 private_libs = private_libs.split()
1974 needs_ldconfig = False
1975 bb.debug(2, "calculating shlib provides for %s" % pkg)
1976
Patrick Williams213cb262021-08-07 19:21:33 -05001977 pkgver = d.getVar('PKGV:' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001978 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001979 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001980 if not pkgver:
1981 pkgver = ver
1982
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001983 needed[pkg] = set()
1984 sonames = set()
1985 renames = []
1986 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001987 for file in pkgfiles[pkg]:
1988 soname = None
1989 if cpath.islink(file):
1990 continue
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001991 if hostos == "darwin" or hostos == "darwin8":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001992 darwin_so(file, needed, sonames, renames, pkgver)
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001993 elif hostos.startswith("mingw"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001994 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001995 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001996 linuxlist.append(file)
1997
1998 if linuxlist:
1999 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
2000 for r in results:
2001 ldconfig = r[0]
2002 needed[pkg] |= r[1]
2003 sonames |= r[2]
2004 renames.extend(r[3])
2005 needs_ldconfig = needs_ldconfig or ldconfig
2006
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002007 for (old, new) in renames:
2008 bb.note("Renaming %s to %s" % (old, new))
Andrew Geisslerc926e172021-05-07 16:11:35 -05002009 bb.utils.rename(old, new)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002010 pkgfiles[pkg].remove(old)
Brad Bishop64c979e2019-11-04 13:55:29 -05002011
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002012 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
2013 if len(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05002014 with open(shlibs_file, 'w') as fd:
Andrew Geissler635e0e42020-08-21 15:58:33 -05002015 for s in sorted(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05002016 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
2017 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
2018 if old_pkg != pkg:
2019 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))
2020 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
2021 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
2022 if s[0] not in shlib_provider:
2023 shlib_provider[s[0]] = {}
2024 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
Brad Bishop1d80a2e2019-11-15 16:35:03 -05002025 if needs_ldconfig:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002026 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Patrick Williams213cb262021-08-07 19:21:33 -05002027 postinst = d.getVar('pkg_postinst:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002028 if not postinst:
2029 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002030 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williams213cb262021-08-07 19:21:33 -05002031 d.setVar('pkg_postinst:%s' % pkg, postinst)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002032 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
2033
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002034 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002035 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002036 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002037 for e in assumed_libs.split():
2038 l, dep_pkg = e.split(":")
2039 lib_ver = None
2040 dep_pkg = dep_pkg.rsplit("_", 1)
2041 if len(dep_pkg) == 2:
2042 lib_ver = dep_pkg[1]
2043 dep_pkg = dep_pkg[0]
2044 if l not in shlib_provider:
2045 shlib_provider[l] = {}
2046 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
2047
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002048 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002049
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002050 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002051 bb.debug(2, "calculating shlib requirements for %s" % pkg)
2052
Patrick Williams213cb262021-08-07 19:21:33 -05002053 private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Brad Bishop316dfdd2018-06-25 12:45:53 -04002054 private_libs = private_libs.split()
2055
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002056 deps = list()
2057 for n in needed[pkg]:
2058 # if n is in private libraries, don't try to search provider for it
2059 # this could cause problem in case some abc.bb provides private
2060 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
2061 # but skipping it is still better alternative than providing own
2062 # version and then adding runtime dependency for the same system library
Brad Bishop79641f22019-09-10 07:20:22 -04002063 import fnmatch
2064 if private_libs and len([i for i in private_libs if fnmatch.fnmatch(n[0], i)]) > 0:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002065 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
2066 continue
2067 if n[0] in shlib_provider.keys():
Brad Bishop00e122a2019-10-05 11:10:57 -04002068 shlib_provider_map = shlib_provider[n[0]]
2069 matches = set()
2070 for p in itertools.chain(list(n[2]), sorted(shlib_provider_map.keys()), libsearchpath):
2071 if p in shlib_provider_map:
2072 matches.add(p)
2073 if len(matches) > 1:
2074 matchpkgs = ', '.join([shlib_provider_map[match][0] for match in matches])
2075 bb.error("%s: Multiple shlib providers for %s: %s (used by files: %s)" % (pkg, n[0], matchpkgs, n[1]))
2076 elif len(matches) == 1:
2077 (dep_pkg, ver_needed) = shlib_provider_map[matches.pop()]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002078
2079 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
2080
2081 if dep_pkg == pkg:
2082 continue
2083
2084 if ver_needed:
2085 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
2086 else:
2087 dep = dep_pkg
2088 if not dep in deps:
2089 deps.append(dep)
2090 continue
2091 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
2092
2093 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
2094 if os.path.exists(deps_file):
2095 os.remove(deps_file)
Brad Bishop64c979e2019-11-04 13:55:29 -05002096 if deps:
2097 with open(deps_file, 'w') as fd:
2098 for dep in sorted(deps):
2099 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002100}
2101
2102python package_do_pkgconfig () {
2103 import re
2104
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002105 packages = d.getVar('PACKAGES')
2106 workdir = d.getVar('WORKDIR')
2107 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002108
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002109 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
2110 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002111
Brad Bishop19323692019-04-05 15:28:33 -04002112 pc_re = re.compile(r'(.*)\.pc$')
2113 var_re = re.compile(r'(.*)=(.*)')
2114 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002115
2116 pkgconfig_provided = {}
2117 pkgconfig_needed = {}
2118 for pkg in packages.split():
2119 pkgconfig_provided[pkg] = []
2120 pkgconfig_needed[pkg] = []
Patrick Williams93c203f2021-10-06 16:15:23 -05002121 for file in sorted(pkgfiles[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002122 m = pc_re.match(file)
2123 if m:
2124 pd = bb.data.init()
2125 name = m.group(1)
Patrick Williams93c203f2021-10-06 16:15:23 -05002126 pkgconfig_provided[pkg].append(os.path.basename(name))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002127 if not os.access(file, os.R_OK):
2128 continue
Brad Bishop64c979e2019-11-04 13:55:29 -05002129 with open(file, 'r') as f:
2130 lines = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002131 for l in lines:
2132 m = var_re.match(l)
2133 if m:
2134 name = m.group(1)
2135 val = m.group(2)
2136 pd.setVar(name, pd.expand(val))
2137 continue
2138 m = field_re.match(l)
2139 if m:
2140 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002141 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002142 if hdr == 'Requires':
2143 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
2144
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002145 for pkg in packages.split():
2146 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
2147 if pkgconfig_provided[pkg] != []:
Brad Bishop64c979e2019-11-04 13:55:29 -05002148 with open(pkgs_file, 'w') as f:
Patrick Williams93c203f2021-10-06 16:15:23 -05002149 for p in sorted(pkgconfig_provided[pkg]):
Brad Bishop64c979e2019-11-04 13:55:29 -05002150 f.write('%s\n' % p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002151
2152 # Go from least to most specific since the last one found wins
2153 for dir in reversed(shlibs_dirs):
2154 if not os.path.exists(dir):
2155 continue
Brad Bishop08902b02019-08-20 09:16:51 -04002156 for file in sorted(os.listdir(dir)):
Brad Bishop19323692019-04-05 15:28:33 -04002157 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002158 if m:
2159 pkg = m.group(1)
Brad Bishop64c979e2019-11-04 13:55:29 -05002160 with open(os.path.join(dir, file)) as fd:
2161 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002162 pkgconfig_provided[pkg] = []
2163 for l in lines:
2164 pkgconfig_provided[pkg].append(l.rstrip())
2165
2166 for pkg in packages.split():
2167 deps = []
2168 for n in pkgconfig_needed[pkg]:
2169 found = False
2170 for k in pkgconfig_provided.keys():
2171 if n in pkgconfig_provided[k]:
2172 if k != pkg and not (k in deps):
2173 deps.append(k)
2174 found = True
2175 if found == False:
2176 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
2177 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
2178 if len(deps):
Brad Bishop64c979e2019-11-04 13:55:29 -05002179 with open(deps_file, 'w') as fd:
2180 for dep in deps:
2181 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002182}
2183
2184def read_libdep_files(d):
2185 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002186 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002187 for pkg in packages:
2188 pkglibdeps[pkg] = {}
2189 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
2190 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
2191 if os.access(depsfile, os.R_OK):
Brad Bishop64c979e2019-11-04 13:55:29 -05002192 with open(depsfile) as fd:
2193 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002194 for l in lines:
2195 l.rstrip()
2196 deps = bb.utils.explode_dep_versions2(l)
2197 for dep in deps:
2198 if not dep in pkglibdeps[pkg]:
2199 pkglibdeps[pkg][dep] = deps[dep]
2200 return pkglibdeps
2201
2202python read_shlibdeps () {
2203 pkglibdeps = read_libdep_files(d)
2204
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002205 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002206 for pkg in packages:
Patrick Williams213cb262021-08-07 19:21:33 -05002207 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04002208 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002209 # Add the dep if it's not already there, or if no comparison is set
2210 if dep not in rdepends:
2211 rdepends[dep] = []
2212 for v in pkglibdeps[pkg][dep]:
2213 if v not in rdepends[dep]:
2214 rdepends[dep].append(v)
Patrick Williams213cb262021-08-07 19:21:33 -05002215 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002216}
2217
2218python package_depchains() {
2219 """
2220 For a given set of prefix and postfix modifiers, make those packages
2221 RRECOMMENDS on the corresponding packages for its RDEPENDS.
2222
2223 Example: If package A depends upon package B, and A's .bb emits an
2224 A-dev package, this would make A-dev Recommends: B-dev.
2225
2226 If only one of a given suffix is specified, it will take the RRECOMMENDS
2227 based on the RDEPENDS of *all* other packages. If more than one of a given
2228 suffix is specified, its will only use the RDEPENDS of the single parent
2229 package.
2230 """
2231
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002232 packages = d.getVar('PACKAGES')
2233 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2234 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002235
2236 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2237
2238 #bb.note('depends for %s is %s' % (base, depends))
Patrick Williams213cb262021-08-07 19:21:33 -05002239 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002240
Brad Bishop19323692019-04-05 15:28:33 -04002241 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002242 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2243 #bb.note("Skipping %s" % depend)
2244 continue
2245 if depend.endswith('-dev'):
2246 depend = depend[:-4]
2247 if depend.endswith('-dbg'):
2248 depend = depend[:-4]
2249 pkgname = getname(depend, suffix)
2250 #bb.note("Adding %s for %s" % (pkgname, depend))
2251 if pkgname not in rreclist and pkgname != pkg:
2252 rreclist[pkgname] = []
2253
Patrick Williams213cb262021-08-07 19:21:33 -05002254 #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist)))
2255 d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002256
2257 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2258
2259 #bb.note('rdepends for %s is %s' % (base, rdepends))
Patrick Williams213cb262021-08-07 19:21:33 -05002260 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002261
Brad Bishop19323692019-04-05 15:28:33 -04002262 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002263 if depend.find('virtual-locale-') != -1:
2264 #bb.note("Skipping %s" % depend)
2265 continue
2266 if depend.endswith('-dev'):
2267 depend = depend[:-4]
2268 if depend.endswith('-dbg'):
2269 depend = depend[:-4]
2270 pkgname = getname(depend, suffix)
2271 #bb.note("Adding %s for %s" % (pkgname, depend))
2272 if pkgname not in rreclist and pkgname != pkg:
2273 rreclist[pkgname] = []
2274
Patrick Williams213cb262021-08-07 19:21:33 -05002275 #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist)))
2276 d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002277
2278 def add_dep(list, dep):
2279 if dep not in list:
2280 list.append(dep)
2281
2282 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002283 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002284 add_dep(depends, dep)
2285
2286 rdepends = []
2287 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05002288 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002289 add_dep(rdepends, dep)
2290
2291 #bb.note('rdepends is %s' % rdepends)
2292
2293 def post_getname(name, suffix):
2294 return '%s%s' % (name, suffix)
2295 def pre_getname(name, suffix):
2296 return '%s%s' % (suffix, name)
2297
2298 pkgs = {}
2299 for pkg in packages.split():
2300 for postfix in postfixes:
2301 if pkg.endswith(postfix):
2302 if not postfix in pkgs:
2303 pkgs[postfix] = {}
2304 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2305
2306 for prefix in prefixes:
2307 if pkg.startswith(prefix):
2308 if not prefix in pkgs:
2309 pkgs[prefix] = {}
2310 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2311
2312 if "-dbg" in pkgs:
2313 pkglibdeps = read_libdep_files(d)
2314 pkglibdeplist = []
2315 for pkg in pkglibdeps:
2316 for k in pkglibdeps[pkg]:
2317 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002318 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002319
2320 for suffix in pkgs:
2321 for pkg in pkgs[suffix]:
Patrick Williams213cb262021-08-07 19:21:33 -05002322 if d.getVarFlag('RRECOMMENDS:' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002323 continue
2324 (base, func) = pkgs[suffix][pkg]
2325 if suffix == "-dev":
2326 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2327 elif suffix == "-dbg":
2328 if not dbgdefaultdeps:
2329 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2330 continue
2331 if len(pkgs[suffix]) == 1:
2332 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2333 else:
2334 rdeps = []
Patrick Williams213cb262021-08-07 19:21:33 -05002335 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002336 add_dep(rdeps, dep)
2337 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2338}
2339
2340# Since bitbake can't determine which variables are accessed during package
2341# iteration, we need to list them here:
Andrew Geissler1e34c2d2020-05-29 16:02:59 -05002342PACKAGEVARS = "FILES RDEPENDS RRECOMMENDS SUMMARY DESCRIPTION RSUGGESTS RPROVIDES RCONFLICTS PKG ALLOW_EMPTY pkg_postinst pkg_postrm pkg_postinst_ontarget INITSCRIPT_NAME INITSCRIPT_PARAMS DEBIAN_NOAUTONAME ALTERNATIVE PKGE PKGV PKGR USERADD_PARAM GROUPADD_PARAM CONFFILES SYSTEMD_SERVICE LICENSE SECTION pkg_preinst pkg_prerm RREPLACES GROUPMEMS_PARAM SYSTEMD_AUTO_ENABLE SKIP_FILEDEPS PRIVATE_LIBS PACKAGE_ADD_METADATA"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002343
Andrew Geissler82c905d2020-04-13 13:39:40 -05002344def gen_packagevar(d, pkgvars="PACKAGEVARS"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002345 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002346 pkgs = (d.getVar("PACKAGES") or "").split()
Andrew Geissler82c905d2020-04-13 13:39:40 -05002347 vars = (d.getVar(pkgvars) or "").split()
2348 for v in vars:
2349 ret.append(v)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002350 for p in pkgs:
2351 for v in vars:
Patrick Williams213cb262021-08-07 19:21:33 -05002352 ret.append(v + ":" + p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002353
2354 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2355 # affected recipes.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002356 ret.append('_exclude_incompatible-%s' % p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002357 return " ".join(ret)
2358
2359PACKAGE_PREPROCESS_FUNCS ?= ""
2360# Functions for setting up PKGD
2361PACKAGEBUILDPKGD ?= " \
Brad Bishop96ff1982019-08-19 13:50:42 -04002362 package_prepare_pkgdata \
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002363 perform_packagecopy \
2364 ${PACKAGE_PREPROCESS_FUNCS} \
2365 split_and_strip_files \
2366 fixup_perms \
2367 "
2368# Functions which split PKGD up into separate packages
2369PACKAGESPLITFUNCS ?= " \
2370 package_do_split_locales \
2371 populate_packages"
2372# Functions which process metadata based on split packages
2373PACKAGEFUNCS += " \
2374 package_fixsymlinks \
2375 package_name_hook \
2376 package_do_filedeps \
2377 package_do_shlibs \
2378 package_do_pkgconfig \
2379 read_shlibdeps \
2380 package_depchains \
2381 emit_pkgdata"
2382
2383python do_package () {
2384 # Change the following version to cause sstate to invalidate the package
2385 # cache. This is useful if an item this class depends on changes in a
2386 # way that the output of this class changes. rpmdeps is a good example
2387 # as any change to rpmdeps requires this to be rerun.
Andrew Geissler6ce62a22020-11-30 19:58:47 -06002388 # PACKAGE_BBCLASS_VERSION = "4"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002389
2390 # Init cachedpath
2391 global cpath
2392 cpath = oe.cachedpath.CachedPath()
2393
2394 ###########################################################################
2395 # Sanity test the setup
2396 ###########################################################################
2397
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002398 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002399 if len(packages) < 1:
2400 bb.debug(1, "No packages to build, skipping do_package")
2401 return
2402
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002403 workdir = d.getVar('WORKDIR')
2404 outdir = d.getVar('DEPLOY_DIR')
2405 dest = d.getVar('D')
2406 dvar = d.getVar('PKGD')
2407 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002408
2409 if not workdir or not outdir or not dest or not dvar or not pn:
2410 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
Andrew Geisslereff27472021-10-29 15:35:00 -05002411 oe.qa.handle_error("var-undefined", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002412 return
2413
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002414 bb.build.exec_func("package_convert_pr_autoinc", d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002415
2416 ###########################################################################
2417 # Optimisations
2418 ###########################################################################
2419
2420 # Continually expanding complex expressions is inefficient, particularly
2421 # when we write to the datastore and invalidate the expansion cache. This
2422 # code pre-expands some frequently used variables
2423
2424 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002425 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002426
2427 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2428 expandVar(x, d)
2429
2430 ###########################################################################
2431 # Setup PKGD (from D)
2432 ###########################################################################
2433
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002434 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002435 bb.build.exec_func(f, d)
2436
2437 ###########################################################################
2438 # Split up PKGD into PKGDEST
2439 ###########################################################################
2440
2441 cpath = oe.cachedpath.CachedPath()
2442
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002443 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002444 bb.build.exec_func(f, d)
2445
2446 ###########################################################################
2447 # Process PKGDEST
2448 ###########################################################################
2449
2450 # Build global list of files in each split package
2451 global pkgfiles
2452 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002453 packages = d.getVar('PACKAGES').split()
2454 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002455 for pkg in packages:
2456 pkgfiles[pkg] = []
2457 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2458 for file in files:
2459 pkgfiles[pkg].append(walkroot + os.sep + file)
2460
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002461 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002462 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002463
Andrew Geisslereff27472021-10-29 15:35:00 -05002464 oe.qa.exit_if_errors(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002465}
2466
Andrew Geissler9aee5002022-03-30 16:27:02 +00002467do_package[dirs] = "${SHLIBSWORKDIR} ${D}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002468do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2469addtask package after do_install
2470
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002471SSTATETASKS += "do_package"
2472do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2473do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002474do_package_setscene[dirs] = "${STAGING_DIR}"
2475
2476python do_package_setscene () {
2477 sstate_setscene(d)
2478}
2479addtask do_package_setscene
2480
Brad Bishopc68388fc2019-08-26 01:33:31 -04002481# Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both
2482# do_package_setscene and do_packagedata_setscene leading to races
2483python do_packagedata () {
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002484 bb.build.exec_func("package_get_auto_pr", d)
2485
Brad Bishopc68388fc2019-08-26 01:33:31 -04002486 src = d.expand("${PKGDESTWORK}")
2487 dest = d.expand("${WORKDIR}/pkgdata-pdata-input")
2488 oe.path.copyhardlinktree(src, dest)
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002489
2490 bb.build.exec_func("packagedata_translate_pr_autoinc", d)
2491}
Andrew Geisslerd1e89492021-02-12 15:35:20 -06002492do_packagedata[cleandirs] += "${WORKDIR}/pkgdata-pdata-input"
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002493
2494# Translate the EXTENDPRAUTO and AUTOINC to the final values
2495packagedata_translate_pr_autoinc() {
2496 find ${WORKDIR}/pkgdata-pdata-input -type f | xargs --no-run-if-empty \
2497 sed -e 's,@PRSERV_PV_AUTOINC@,${PRSERV_PV_AUTOINC},g' \
2498 -e 's,@EXTENDPRAUTO@,${EXTENDPRAUTO},g' -i
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002499}
2500
2501addtask packagedata before do_build after do_package
2502
2503SSTATETASKS += "do_packagedata"
Brad Bishopc68388fc2019-08-26 01:33:31 -04002504do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002505do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002506do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002507
2508python do_packagedata_setscene () {
2509 sstate_setscene(d)
2510}
2511addtask do_packagedata_setscene
2512
2513#
2514# Helper functions for the package writing classes
2515#
2516
2517def mapping_rename_hook(d):
2518 """
2519 Rewrite variables to account for package renaming in things
2520 like debian.bbclass or manual PKG variable name changes
2521 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002522 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002523 runtime_mapping_rename("RDEPENDS", pkg, d)
2524 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2525 runtime_mapping_rename("RSUGGESTS", pkg, d)