blob: 62050a18b8d32697ede27e6ced1564b5def0df4a [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
Andrew Geissler82c905d2020-04-13 13:39:40 -0500425
426 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000427 dest = dv["staticlibdir"] + os.path.dirname(src) + dv["staticdir"] + "/" + os.path.basename(src) + dv["staticappend"]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500428 debugfile = dvar + dest
429 sources = []
430
431 # Copy the file...
432 bb.utils.mkdirhier(os.path.dirname(debugfile))
433 #bb.note("Copy %s -> %s" % (file, debugfile))
434
435 dvar = d.getVar('PKGD')
436
437 newmode = None
438 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
439 origmode = os.stat(file)[stat.ST_MODE]
440 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
441 os.chmod(file, newmode)
442
443 # We need to extract the debug src information here...
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000444 if dv["srcdir"]:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500445 sources = source_info(file, d)
446
447 bb.utils.mkdirhier(os.path.dirname(debugfile))
448
449 # Copy the unmodified item to the debug directory
450 shutil.copy2(file, debugfile)
451
452 if newmode:
453 os.chmod(file, origmode)
454
455 return (file, sources)
456
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000457def inject_minidebuginfo(file, dvar, dv, d):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500458 # Extract just the symbols from debuginfo into minidebuginfo,
459 # compress it with xz and inject it back into the binary in a .gnu_debugdata section.
460 # https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
461
462 import subprocess
463
464 readelf = d.getVar('READELF')
465 nm = d.getVar('NM')
466 objcopy = d.getVar('OBJCOPY')
467
468 minidebuginfodir = d.expand('${WORKDIR}/minidebuginfo')
469
470 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000471 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(src) + dv["append"]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500472 debugfile = dvar + dest
473 minidebugfile = minidebuginfodir + src + '.minidebug'
474 bb.utils.mkdirhier(os.path.dirname(minidebugfile))
475
476 # If we didn't produce debuginfo for any reason, we can't produce minidebuginfo either
477 # so skip it.
478 if not os.path.exists(debugfile):
479 bb.debug(1, 'ELF file {} has no debuginfo, skipping minidebuginfo injection'.format(file))
480 return
481
482 # Find non-allocated PROGBITS, NOTE, and NOBITS sections in the debuginfo.
483 # We will exclude all of these from minidebuginfo to save space.
484 remove_section_names = []
485 for line in subprocess.check_output([readelf, '-W', '-S', debugfile], universal_newlines=True).splitlines():
486 fields = line.split()
487 if len(fields) < 8:
488 continue
489 name = fields[0]
490 type = fields[1]
491 flags = fields[7]
492 # .debug_ sections will be removed by objcopy -S so no need to explicitly remove them
493 if name.startswith('.debug_'):
494 continue
495 if 'A' not in flags and type in ['PROGBITS', 'NOTE', 'NOBITS']:
496 remove_section_names.append(name)
497
498 # List dynamic symbols in the binary. We can exclude these from minidebuginfo
499 # because they are always present in the binary.
500 dynsyms = set()
501 for line in subprocess.check_output([nm, '-D', file, '--format=posix', '--defined-only'], universal_newlines=True).splitlines():
502 dynsyms.add(line.split()[0])
503
504 # Find all function symbols from debuginfo which aren't in the dynamic symbols table.
505 # These are the ones we want to keep in minidebuginfo.
506 keep_symbols_file = minidebugfile + '.symlist'
507 found_any_symbols = False
508 with open(keep_symbols_file, 'w') as f:
509 for line in subprocess.check_output([nm, debugfile, '--format=sysv', '--defined-only'], universal_newlines=True).splitlines():
510 fields = line.split('|')
511 if len(fields) < 7:
512 continue
513 name = fields[0].strip()
514 type = fields[3].strip()
515 if type == 'FUNC' and name not in dynsyms:
516 f.write('{}\n'.format(name))
517 found_any_symbols = True
518
519 if not found_any_symbols:
520 bb.debug(1, 'ELF file {} contains no symbols, skipping minidebuginfo injection'.format(file))
521 return
522
523 bb.utils.remove(minidebugfile)
524 bb.utils.remove(minidebugfile + '.xz')
525
526 subprocess.check_call([objcopy, '-S'] +
527 ['--remove-section={}'.format(s) for s in remove_section_names] +
528 ['--keep-symbols={}'.format(keep_symbols_file), debugfile, minidebugfile])
529
530 subprocess.check_call(['xz', '--keep', minidebugfile])
531
532 subprocess.check_call([objcopy, '--add-section', '.gnu_debugdata={}.xz'.format(minidebugfile), file])
533
Brad Bishop19323692019-04-05 15:28:33 -0400534def copydebugsources(debugsrcdir, sources, d):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400535 # The debug src information written out to sourcefile is further processed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500536 # and copied to the destination here.
537
538 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800539 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500540
Brad Bishop19323692019-04-05 15:28:33 -0400541 if debugsrcdir and sources:
542 sourcefile = d.expand("${WORKDIR}/debugsources.list")
543 bb.utils.remove(sourcefile)
544
545 # filenames are null-separated - this is an artefact of the previous use
546 # of rpm's debugedit, which was writing them out that way, and the code elsewhere
547 # is still assuming that.
548 debuglistoutput = '\0'.join(sources) + '\0'
549 with open(sourcefile, 'a') as sf:
550 sf.write(debuglistoutput)
551
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500552 dvar = d.getVar('PKGD')
553 strip = d.getVar("STRIP")
554 objcopy = d.getVar("OBJCOPY")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500555 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556 workparentdir = os.path.dirname(os.path.dirname(workdir))
557 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
558
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500559 # If build path exists in sourcefile, it means toolchain did not use
560 # -fdebug-prefix-map to compile
561 if checkbuildpath(sourcefile, d):
562 localsrc_prefix = workparentdir + "/"
563 else:
564 localsrc_prefix = "/usr/src/debug/"
565
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500566 nosuchdir = []
567 basepath = dvar
568 for p in debugsrcdir.split("/"):
569 basepath = basepath + "/" + p
570 if not cpath.exists(basepath):
571 nosuchdir.append(basepath)
572 bb.utils.mkdirhier(basepath)
573 cpath.updatecache(basepath)
574
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500575 # Ignore files from the recipe sysroots (target and native)
576 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500577 # We need to ignore files that are not actually ours
578 # we do this by only paying attention to items from this package
579 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500580 # Remove prefix in the source paths
581 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500582 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
583
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500584 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800585 try:
586 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
587 except subprocess.CalledProcessError:
588 # Can "fail" if internal headers/transient sources are attempted
589 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500590
591 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
592 # Work around this by manually finding and copying any symbolic links that made it through.
Brad Bishop19323692019-04-05 15:28:33 -0400593 cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s')" % \
594 (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800595 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500596
597 # The copy by cpio may have resulted in some empty directories! Remove these
598 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800599 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500600
601 # Also remove debugsrcdir if its empty
602 for p in nosuchdir[::-1]:
603 if os.path.exists(p) and not os.listdir(p):
604 os.rmdir(p)
605
606#
607# Package data handling routines
608#
609
Andrew Geissler82c905d2020-04-13 13:39:40 -0500610def get_package_mapping (pkg, basepkg, d, depversions=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500611 import oe.packagedata
612
613 data = oe.packagedata.read_subpkgdata(pkg, d)
Patrick Williams213cb262021-08-07 19:21:33 -0500614 key = "PKG:%s" % pkg
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500615
616 if key in data:
Andrew Geissler595f6302022-01-24 19:11:47 +0000617 if bb.data.inherits_class('allarch', d) and bb.data.inherits_class('packagegroup', d) and pkg != data[key]:
618 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 -0500619 # Have to avoid undoing the write_extra_pkgs(global_variants...)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800620 if bb.data.inherits_class('allarch', d) and not d.getVar('MULTILIB_VARIANTS') \
621 and data[key] == basepkg:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500622 return pkg
Andrew Geissler82c905d2020-04-13 13:39:40 -0500623 if depversions == []:
624 # Avoid returning a mapping if the renamed package rprovides its original name
Patrick Williams213cb262021-08-07 19:21:33 -0500625 rprovkey = "RPROVIDES:%s" % pkg
Andrew Geissler82c905d2020-04-13 13:39:40 -0500626 if rprovkey in data:
627 if pkg in bb.utils.explode_dep_versions2(data[rprovkey]):
628 bb.note("%s rprovides %s, not replacing the latter" % (data[key], pkg))
629 return pkg
630 # Do map to rewritten package name
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500631 return data[key]
632
633 return pkg
634
635def get_package_additional_metadata (pkg_type, d):
636 base_key = "PACKAGE_ADD_METADATA"
637 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
638 if d.getVar(key, False) is None:
639 continue
640 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500641 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500642 d.setVarFlag(key, "separator", "\\n")
643 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
644 return "\n".join(metadata_fields).strip()
645
646def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500647 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500648
649 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500650 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Andrew Geissler82c905d2020-04-13 13:39:40 -0500651 for depend, depversions in deps.items():
652 new_depend = get_package_mapping(depend, pkg, d, depversions)
653 if depend != new_depend:
654 bb.note("package name mapping done: %s -> %s" % (depend, new_depend))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500655 new_depends[new_depend] = deps[depend]
656
657 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
658
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500659 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500660
661#
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500662# Used by do_packagedata (and possibly other routines post do_package)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500663#
664
Andrew Geisslerd5838332022-05-27 11:33:10 -0500665PRSERV_ACTIVE = "${@bool(d.getVar("PRSERV_HOST"))}"
666PRSERV_ACTIVE[vardepvalue] = "${PRSERV_ACTIVE}"
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500667package_get_auto_pr[vardepsexclude] = "BB_TASKDEPDATA"
Andrew Geisslerd5838332022-05-27 11:33:10 -0500668package_get_auto_pr[vardeps] += "PRSERV_ACTIVE"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500669python package_get_auto_pr() {
670 import oe.prservice
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500671
672 def get_do_package_hash(pn):
673 if d.getVar("BB_RUNTASK") != "do_package":
674 taskdepdata = d.getVar("BB_TASKDEPDATA", False)
675 for dep in taskdepdata:
676 if taskdepdata[dep][1] == "do_package" and taskdepdata[dep][0] == pn:
677 return taskdepdata[dep][6]
678 return None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500679
680 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500681 pn = d.getVar('PN')
682 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500683 if not (host is None):
684 d.setVar("PRSERV_HOST", host)
685
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500686 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500687
688 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500689 if not d.getVar('PRSERV_HOST'):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500690 d.setVar("PRSERV_PV_AUTOINC", "0")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500691 return
692
693 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500694 pv = d.getVar("PV")
695 version = d.getVar("PRAUTOINX")
696 pkgarch = d.getVar("PACKAGE_ARCH")
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500697 checksum = get_do_package_hash(pn)
698
699 # If do_package isn't in the dependencies, we can't get the checksum...
700 if not checksum:
701 bb.warn('Task %s requested do_package unihash, but it was not available.' % d.getVar('BB_RUNTASK'))
702 #taskdepdata = d.getVar("BB_TASKDEPDATA", False)
703 #for dep in taskdepdata:
704 # bb.warn('%s:%s = %s' % (taskdepdata[dep][0], taskdepdata[dep][1], taskdepdata[dep][6]))
705 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500706
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500707 if d.getVar('PRSERV_LOCKDOWN'):
708 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500709 if auto_pr is None:
710 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
711 d.setVar('PRAUTO',str(auto_pr))
712 return
713
714 try:
Andrew Geisslerd159c7f2021-09-02 21:05:58 -0500715 conn = oe.prservice.prserv_make_conn(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500716 if conn is not None:
717 if "AUTOINC" in pkgv:
718 srcpv = bb.fetch2.get_srcrev(d)
719 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
720 value = conn.getPR(base_ver, pkgarch, srcpv)
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500721 d.setVar("PRSERV_PV_AUTOINC", str(value))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500722
723 auto_pr = conn.getPR(version, pkgarch, checksum)
Andrew Geisslerd159c7f2021-09-02 21:05:58 -0500724 conn.close()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500725 except Exception as e:
726 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
727 if auto_pr is None:
728 bb.fatal("Can NOT get PRAUTO from remote PR service")
729 d.setVar('PRAUTO',str(auto_pr))
730}
731
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500732#
733# Package functions suitable for inclusion in PACKAGEFUNCS
734#
735
736python package_convert_pr_autoinc() {
737 pkgv = d.getVar("PKGV")
738
739 # Adjust pkgv as necessary...
740 if 'AUTOINC' in pkgv:
741 d.setVar("PKGV", pkgv.replace("AUTOINC", "${PRSERV_PV_AUTOINC}"))
742
743 # Change PRSERV_PV_AUTOINC and EXTENDPRAUTO usage to special values
744 d.setVar('PRSERV_PV_AUTOINC', '@PRSERV_PV_AUTOINC@')
745 d.setVar('EXTENDPRAUTO', '@EXTENDPRAUTO@')
746}
747
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500748LOCALEBASEPN ??= "${PN}"
749
750python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500751 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500752 bb.debug(1, "package requested not splitting locales")
753 return
754
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500755 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500756
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500757 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500758 if not datadir:
759 bb.note("datadir not defined")
760 return
761
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500762 dvar = d.getVar('PKGD')
763 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500764
765 if pn + '-locale' in packages:
766 packages.remove(pn + '-locale')
767
768 localedir = os.path.join(dvar + datadir, 'locale')
769
770 if not cpath.isdir(localedir):
771 bb.debug(1, "No locale files in this package")
772 return
773
774 locales = os.listdir(localedir)
775
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500776 summary = d.getVar('SUMMARY') or pn
777 description = d.getVar('DESCRIPTION') or ""
778 locale_section = d.getVar('LOCALE_SECTION')
779 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500780 for l in sorted(locales):
781 ln = legitimize_package_name(l)
782 pkg = pn + '-locale-' + ln
783 packages.append(pkg)
Patrick Williams213cb262021-08-07 19:21:33 -0500784 d.setVar('FILES:' + pkg, os.path.join(datadir, 'locale', l))
785 d.setVar('RRECOMMENDS:' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
786 d.setVar('RPROVIDES:' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
787 d.setVar('SUMMARY:' + pkg, '%s - %s translations' % (summary, l))
788 d.setVar('DESCRIPTION:' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500789 if locale_section:
Patrick Williams213cb262021-08-07 19:21:33 -0500790 d.setVar('SECTION:' + pkg, locale_section)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500791
792 d.setVar('PACKAGES', ' '.join(packages))
793
794 # Disabled by RP 18/06/07
795 # Wildcards aren't supported in debian
796 # They break with ipkg since glibc-locale* will mean that
797 # glibc-localedata-translit* won't install as a dependency
798 # for some other package which breaks meta-toolchain
799 # Probably breaks since virtual-locale- isn't provided anywhere
Patrick Williams213cb262021-08-07 19:21:33 -0500800 #rdep = (d.getVar('RDEPENDS:%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500801 #rdep.append('%s-locale*' % pn)
Patrick Williams213cb262021-08-07 19:21:33 -0500802 #d.setVar('RDEPENDS:%s' % pn, ' '.join(rdep))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500803}
804
805python perform_packagecopy () {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800806 import subprocess
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600807 import shutil
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800808
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500809 dest = d.getVar('D')
810 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500811
812 # Start by package population by taking a copy of the installed
813 # files to operate on
814 # Preserve sparse files and hard links
Patrick Williams03907ee2022-05-01 06:28:52 -0500815 cmd = 'tar --exclude=./sysroot-only -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800816 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500817
818 # replace RPATHs for the nativesdk binaries, to make them relocatable
819 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
820 rpath_replace (dvar, d)
821}
822perform_packagecopy[cleandirs] = "${PKGD}"
823perform_packagecopy[dirs] = "${PKGD}"
824
825# We generate a master list of directories to process, we start by
826# seeding this list with reasonable defaults, then load from
827# the fs-perms.txt files
828python fixup_perms () {
829 import pwd, grp
830
831 # init using a string with the same format as a line as documented in
832 # the fs-perms.txt file
833 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
834 # <path> link <link target>
835 #
836 # __str__ can be used to print out an entry in the input format
837 #
838 # if fs_perms_entry.path is None:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400839 # an error occurred
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500840 # if fs_perms_entry.link, you can retrieve:
841 # fs_perms_entry.path = path
842 # fs_perms_entry.link = target of link
843 # if not fs_perms_entry.link, you can retrieve:
844 # fs_perms_entry.path = path
845 # fs_perms_entry.mode = expected dir mode or None
846 # fs_perms_entry.uid = expected uid or -1
847 # fs_perms_entry.gid = expected gid or -1
848 # fs_perms_entry.walk = 'true' or something else
849 # fs_perms_entry.fmode = expected file mode or None
850 # fs_perms_entry.fuid = expected file uid or -1
851 # fs_perms_entry_fgid = expected file gid or -1
852 class fs_perms_entry():
853 def __init__(self, line):
854 lsplit = line.split()
855 if len(lsplit) == 3 and lsplit[1].lower() == "link":
856 self._setlink(lsplit[0], lsplit[2])
857 elif len(lsplit) == 8:
858 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
859 else:
860 msg = "Fixup Perms: invalid config line %s" % line
Andrew Geisslereff27472021-10-29 15:35:00 -0500861 oe.qa.handle_error("perm-config", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500862 self.path = None
863 self.link = None
864
865 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
866 self.path = os.path.normpath(path)
867 self.link = None
868 self.mode = self._procmode(mode)
869 self.uid = self._procuid(uid)
870 self.gid = self._procgid(gid)
871 self.walk = walk.lower()
872 self.fmode = self._procmode(fmode)
873 self.fuid = self._procuid(fuid)
874 self.fgid = self._procgid(fgid)
875
876 def _setlink(self, path, link):
877 self.path = os.path.normpath(path)
878 self.link = link
879
880 def _procmode(self, mode):
881 if not mode or (mode and mode == "-"):
882 return None
883 else:
884 return int(mode,8)
885
886 # Note uid/gid -1 has special significance in os.lchown
887 def _procuid(self, uid):
888 if uid is None or uid == "-":
889 return -1
890 elif uid.isdigit():
891 return int(uid)
892 else:
893 return pwd.getpwnam(uid).pw_uid
894
895 def _procgid(self, gid):
896 if gid is None or gid == "-":
897 return -1
898 elif gid.isdigit():
899 return int(gid)
900 else:
901 return grp.getgrnam(gid).gr_gid
902
903 # Use for debugging the entries
904 def __str__(self):
905 if self.link:
906 return "%s link %s" % (self.path, self.link)
907 else:
908 mode = "-"
909 if self.mode:
910 mode = "0%o" % self.mode
911 fmode = "-"
912 if self.fmode:
913 fmode = "0%o" % self.fmode
914 uid = self._mapugid(self.uid)
915 gid = self._mapugid(self.gid)
916 fuid = self._mapugid(self.fuid)
917 fgid = self._mapugid(self.fgid)
918 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
919
920 def _mapugid(self, id):
921 if id is None or id == -1:
922 return "-"
923 else:
924 return "%d" % id
925
926 # Fix the permission, owner and group of path
927 def fix_perms(path, mode, uid, gid, dir):
928 if mode and not os.path.islink(path):
929 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
930 os.chmod(path, mode)
931 # -1 is a special value that means don't change the uid/gid
932 # if they are BOTH -1, don't bother to lchown
933 if not (uid == -1 and gid == -1):
934 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
935 os.lchown(path, uid, gid)
936
937 # Return a list of configuration files based on either the default
938 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
939 # paths are resolved via BBPATH
940 def get_fs_perms_list(d):
941 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500942 bbpath = d.getVar('BBPATH')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500943 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500944 for conf_file in fs_perms_tables.split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800945 confpath = bb.utils.which(bbpath, conf_file)
946 if confpath:
947 str += " %s" % bb.utils.which(bbpath, conf_file)
948 else:
949 bb.warn("cannot find %s specified in FILESYSTEM_PERMS_TABLES" % conf_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500950 return str
951
952
953
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500954 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500955
956 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500957 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500958
959 # By default all of the standard directories specified in
960 # bitbake.conf will get 0755 root:root.
961 target_path_vars = [ 'base_prefix',
962 'prefix',
963 'exec_prefix',
964 'base_bindir',
965 'base_sbindir',
966 'base_libdir',
967 'datadir',
968 'sysconfdir',
969 'servicedir',
970 'sharedstatedir',
971 'localstatedir',
972 'infodir',
973 'mandir',
974 'docdir',
975 'bindir',
976 'sbindir',
977 'libexecdir',
978 'libdir',
979 'includedir',
980 'oldincludedir' ]
981
982 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500983 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500984 if dir == "":
985 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500986 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500987
988 # Now we actually load from the configuration files
989 for conf in get_fs_perms_list(d).split():
Brad Bishop64c979e2019-11-04 13:55:29 -0500990 if not os.path.exists(conf):
991 continue
992 with open(conf) as f:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500993 for line in f:
994 if line.startswith('#'):
995 continue
996 lsplit = line.split()
997 if len(lsplit) == 0:
998 continue
999 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
1000 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
Andrew Geisslereff27472021-10-29 15:35:00 -05001001 oe.qa.handle_error("perm-line", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001002 continue
1003 entry = fs_perms_entry(d.expand(line))
1004 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001005 if entry.link:
1006 fs_link_table[entry.path] = entry
1007 if entry.path in fs_perms_table:
1008 fs_perms_table.pop(entry.path)
1009 else:
1010 fs_perms_table[entry.path] = entry
1011 if entry.path in fs_link_table:
1012 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001013
1014 # Debug -- list out in-memory table
1015 #for dir in fs_perms_table:
1016 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001017 #for link in fs_link_table:
1018 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001019
1020 # We process links first, so we can go back and fixup directory ownership
1021 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001022 # Process in sorted order so /run gets created before /run/lock, etc.
1023 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
1024 link = entry.link
1025 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001026 origin = dvar + dir
1027 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
1028 continue
1029
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001030 if link[0] == "/":
1031 target = dvar + link
1032 ptarget = link
1033 else:
1034 target = os.path.join(os.path.dirname(origin), link)
1035 ptarget = os.path.join(os.path.dirname(dir), link)
1036 if os.path.exists(target):
1037 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
Andrew Geisslereff27472021-10-29 15:35:00 -05001038 oe.qa.handle_error("perm-link", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001039 continue
1040
1041 # Create path to move directory to, move it, and then setup the symlink
1042 bb.utils.mkdirhier(os.path.dirname(target))
1043 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
Andrew Geisslerc926e172021-05-07 16:11:35 -05001044 bb.utils.rename(origin, target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001045 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
1046 os.symlink(link, origin)
1047
1048 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001049 origin = dvar + dir
1050 if not (cpath.exists(origin) and cpath.isdir(origin)):
1051 continue
1052
1053 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
1054
1055 if fs_perms_table[dir].walk == 'true':
1056 for root, dirs, files in os.walk(origin):
1057 for dr in dirs:
1058 each_dir = os.path.join(root, dr)
1059 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
1060 for f in files:
1061 each_file = os.path.join(root, f)
1062 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
1063}
1064
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001065def package_debug_vars(d):
1066 # We default to '.debug' style
1067 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
1068 # Single debug-file-directory style debug info
1069 debug_vars = {
1070 "append": ".debug",
1071 "staticappend": "",
1072 "dir": "",
1073 "staticdir": "",
1074 "libdir": "/usr/lib/debug",
1075 "staticlibdir": "/usr/lib/debug-static",
1076 "srcdir": "/usr/src/debug",
1077 }
1078 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
1079 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
1080 debug_vars = {
1081 "append": "",
1082 "staticappend": "",
1083 "dir": "/.debug",
1084 "staticdir": "/.debug-static",
1085 "libdir": "",
1086 "staticlibdir": "",
1087 "srcdir": "",
1088 }
1089 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
1090 debug_vars = {
1091 "append": "",
1092 "staticappend": "",
1093 "dir": "/.debug",
1094 "staticdir": "/.debug-static",
1095 "libdir": "",
1096 "staticlibdir": "",
1097 "srcdir": "/usr/src/debug",
1098 }
1099 else:
1100 # Original OE-core, a.k.a. ".debug", style debug info
1101 debug_vars = {
1102 "append": "",
1103 "staticappend": "",
1104 "dir": "/.debug",
1105 "staticdir": "/.debug-static",
1106 "libdir": "",
1107 "staticlibdir": "",
1108 "srcdir": "/usr/src/debug",
1109 }
1110
1111 return debug_vars
1112
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001113python split_and_strip_files () {
1114 import stat, errno
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001115 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001116
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001117 dvar = d.getVar('PKGD')
1118 pn = d.getVar('PN')
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001119 hostos = d.getVar('HOST_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001120
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001121 oldcwd = os.getcwd()
1122 os.chdir(dvar)
1123
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001124 dv = package_debug_vars(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001125
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001126 #
1127 # First lets figure out all of the files we may have to process ... do this only once!
1128 #
1129 elffiles = {}
1130 symlinks = {}
Brad Bishop316dfdd2018-06-25 12:45:53 -04001131 staticlibs = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001132 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001133 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
1134 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
Brad Bishop316dfdd2018-06-25 12:45:53 -04001135 skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001136 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
1137 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001138 checkelf = {}
1139 checkelflinks = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001140 for root, dirs, files in cpath.walk(dvar):
1141 for f in files:
1142 file = os.path.join(root, f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001143
1144 # Skip debug files
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001145 if dv["append"] and file.endswith(dv["append"]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001146 continue
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001147 if dv["dir"] and dv["dir"] in os.path.dirname(file[len(dvar):]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001148 continue
1149
Brad Bishop316dfdd2018-06-25 12:45:53 -04001150 if file in skipfiles:
1151 continue
1152
Andrew Geissler82c905d2020-04-13 13:39:40 -05001153 if oe.package.is_static_lib(file):
1154 staticlibs.append(file)
1155 continue
1156
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001157 try:
1158 ltarget = cpath.realpath(file, dvar, False)
1159 s = cpath.lstat(ltarget)
1160 except OSError as e:
1161 (err, strerror) = e.args
1162 if err != errno.ENOENT:
1163 raise
1164 # Skip broken symlinks
1165 continue
1166 if not s:
1167 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -04001168 # Check its an executable
Andrew Geissler595f6302022-01-24 19:11:47 +00001169 if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) \
1170 or (s[stat.ST_MODE] & stat.S_IXOTH) \
1171 or ((file.startswith(libdir) or file.startswith(baselibdir)) \
1172 and (".so" in f or ".node" in f)) \
1173 or (f.startswith('vmlinux') or ".ko" in f):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001174
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001175 if cpath.islink(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001176 checkelflinks[file] = ltarget
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001177 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001178 # Use a reference of device ID and inode number to identify files
1179 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
1180 checkelf[file] = (file, file_reference)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001181
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001182 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d)
1183 results_map = {}
1184 for (ltarget, elf_file) in results:
1185 results_map[ltarget] = elf_file
1186 for file in checkelflinks:
1187 ltarget = checkelflinks[file]
1188 # If it's a symlink, and points to an ELF file, we capture the readlink target
1189 if results_map[ltarget]:
1190 target = os.readlink(file)
1191 #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget]))
1192 symlinks[file] = target
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001193
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001194 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d)
Brad Bishop15ae2502019-06-18 21:44:24 -04001195
1196 # Sort results by file path. This ensures that the files are always
1197 # processed in the same order, which is important to make sure builds
1198 # are reproducible when dealing with hardlinks
1199 results.sort(key=lambda x: x[0])
1200
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001201 for (file, elf_file) in results:
1202 # It's a file (or hardlink), not a link
1203 # ...but is it ELF, and is it already stripped?
1204 if elf_file & 1:
1205 if elf_file & 2:
Patrick Williams213cb262021-08-07 19:21:33 -05001206 if 'already-stripped' in (d.getVar('INSANE_SKIP:' + pn) or "").split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001207 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1208 else:
1209 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
Andrew Geisslereff27472021-10-29 15:35:00 -05001210 oe.qa.handle_error("already-stripped", msg, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001211 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001212
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001213 # At this point we have an unstripped elf file. We need to:
1214 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1215 # b) Only strip any hardlinked file once (no races)
1216 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1217
1218 # Use a reference of device ID and inode number to identify files
1219 file_reference = checkelf[file][1]
1220 if file_reference in inodes:
1221 os.unlink(file)
1222 os.link(inodes[file_reference][0], file)
1223 inodes[file_reference].append(file)
1224 else:
1225 inodes[file_reference] = [file]
1226 # break hardlink
1227 bb.utils.break_hardlinks(file)
1228 elffiles[file] = elf_file
1229 # Modified the file so clear the cache
1230 cpath.updatecache(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001231
Andrew Geissler5199d832021-09-24 16:47:35 -05001232 def strip_pkgd_prefix(f):
1233 nonlocal dvar
1234
1235 if f.startswith(dvar):
1236 return f[len(dvar):]
1237
1238 return f
1239
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001240 #
1241 # First lets process debug splitting
1242 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001243 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001244 results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, dv, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001245
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001246 if dv["srcdir"] and not hostos.startswith("mingw"):
Andrew Geissler82c905d2020-04-13 13:39:40 -05001247 if (d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001248 results = oe.utils.multiprocess_launch(splitstaticdebuginfo, staticlibs, d, extraargs=(dvar, dv, d))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001249 else:
1250 for file in staticlibs:
1251 results.append( (file,source_info(file, d)) )
Brad Bishop19323692019-04-05 15:28:33 -04001252
Andrew Geissler5199d832021-09-24 16:47:35 -05001253 d.setVar("PKGDEBUGSOURCES", {strip_pkgd_prefix(f): sorted(s) for f, s in results})
1254
Brad Bishop19323692019-04-05 15:28:33 -04001255 sources = set()
1256 for r in results:
1257 sources.update(r[1])
Brad Bishop316dfdd2018-06-25 12:45:53 -04001258
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001259 # Hardlink our debug symbols to the other hardlink copies
1260 for ref in inodes:
1261 if len(inodes[ref]) == 1:
1262 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001263
1264 target = inodes[ref][0][len(dvar):]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001265 for file in inodes[ref][1:]:
1266 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001267 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(target) + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001268 fpath = dvar + dest
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001269 ftarget = dvar + dv["libdir"] + os.path.dirname(target) + dv["dir"] + "/" + os.path.basename(target) + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001270 bb.utils.mkdirhier(os.path.dirname(fpath))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001271 # Only one hardlink of separated debug info file in each directory
1272 if not os.access(fpath, os.R_OK):
1273 #bb.note("Link %s -> %s" % (fpath, ftarget))
1274 os.link(ftarget, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001275
1276 # Create symlinks for all cases we were able to split symbols
1277 for file in symlinks:
1278 src = file[len(dvar):]
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001279 dest = dv["libdir"] + os.path.dirname(src) + dv["dir"] + "/" + os.path.basename(src) + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001280 fpath = dvar + dest
1281 # Skip it if the target doesn't exist
1282 try:
1283 s = os.stat(fpath)
1284 except OSError as e:
1285 (err, strerror) = e.args
1286 if err != errno.ENOENT:
1287 raise
1288 continue
1289
1290 ltarget = symlinks[file]
1291 lpath = os.path.dirname(ltarget)
1292 lbase = os.path.basename(ltarget)
1293 ftarget = ""
1294 if lpath and lpath != ".":
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001295 ftarget += lpath + dv["dir"] + "/"
1296 ftarget += lbase + dv["append"]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001297 if lpath.startswith(".."):
1298 ftarget = os.path.join("..", ftarget)
1299 bb.utils.mkdirhier(os.path.dirname(fpath))
1300 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1301 os.symlink(ftarget, fpath)
1302
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001303 # Process the dv["srcdir"] if requested...
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001304 # This copies and places the referenced sources for later debugging...
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001305 copydebugsources(dv["srcdir"], sources, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001306 #
1307 # End of debug splitting
1308 #
1309
1310 #
1311 # Now lets go back over things and strip them
1312 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001313 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1314 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001315 sfiles = []
1316 for file in elffiles:
1317 elf_file = int(elffiles[file])
1318 #bb.note("Strip %s" % file)
1319 sfiles.append((file, elf_file, strip))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001320 if (d.getVar('PACKAGE_STRIP_STATIC') == '1' or d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'):
1321 for f in staticlibs:
1322 sfiles.append((f, 16, strip))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001323
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001324 oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001325
Andrew Geissler82c905d2020-04-13 13:39:40 -05001326 # Build "minidebuginfo" and reinject it back into the stripped binaries
1327 if d.getVar('PACKAGE_MINIDEBUGINFO') == '1':
1328 oe.utils.multiprocess_launch(inject_minidebuginfo, list(elffiles), d,
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001329 extraargs=(dvar, dv, d))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001330
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001331 #
1332 # End of strip
1333 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001334 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001335}
1336
1337python populate_packages () {
1338 import glob, re
1339
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001340 workdir = d.getVar('WORKDIR')
1341 outdir = d.getVar('DEPLOY_DIR')
1342 dvar = d.getVar('PKGD')
Brad Bishop19323692019-04-05 15:28:33 -04001343 packages = d.getVar('PACKAGES').split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001344 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001345
1346 bb.utils.mkdirhier(outdir)
1347 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001348
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001349 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001350
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001351 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1352
Brad Bishop19323692019-04-05 15:28:33 -04001353 # If debug-with-srcpkg mode is enabled then add the source package if it
1354 # doesn't exist and add the source file contents to the source package.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001355 if split_source_package:
1356 src_package_name = ('%s-src' % d.getVar('PN'))
Brad Bishop19323692019-04-05 15:28:33 -04001357 if not src_package_name in packages:
1358 packages.append(src_package_name)
Patrick Williams213cb262021-08-07 19:21:33 -05001359 d.setVar('FILES:%s' % src_package_name, '/usr/src/debug')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001360
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001361 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001362 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001363 package_dict = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001364
Brad Bishop19323692019-04-05 15:28:33 -04001365 for i, pkg in enumerate(packages):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001366 if pkg in package_dict:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001367 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
Andrew Geisslereff27472021-10-29 15:35:00 -05001368 oe.qa.handle_error("packages-list", msg, d)
Brad Bishop19323692019-04-05 15:28:33 -04001369 # Ensure the source package gets the chance to pick up the source files
1370 # before the debug package by ordering it first in PACKAGES. Whether it
1371 # actually picks up any source files is controlled by
1372 # PACKAGE_DEBUG_SPLIT_STYLE.
1373 elif pkg.endswith("-src"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001374 package_dict[pkg] = (10, i)
1375 elif autodebug and pkg.endswith("-dbg"):
1376 package_dict[pkg] = (30, i)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001377 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001378 package_dict[pkg] = (50, i)
Brad Bishop19323692019-04-05 15:28:33 -04001379 packages = sorted(package_dict.keys(), key=package_dict.get)
1380 d.setVar('PACKAGES', ' '.join(packages))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001381 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001382
1383 seen = []
1384
1385 # os.mkdir masks the permissions with umask so we have to unset it first
1386 oldumask = os.umask(0)
1387
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001388 debug = []
1389 for root, dirs, files in cpath.walk(dvar):
1390 dir = root[len(dvar):]
1391 if not dir:
1392 dir = os.sep
1393 for f in (files + dirs):
1394 path = "." + os.path.join(dir, f)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001395 if "/.debug/" in path or "/.debug-static/" in path or path.endswith("/.debug"):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001396 debug.append(path)
1397
Brad Bishop19323692019-04-05 15:28:33 -04001398 for pkg in packages:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001399 root = os.path.join(pkgdest, pkg)
1400 bb.utils.mkdirhier(root)
1401
Patrick Williams213cb262021-08-07 19:21:33 -05001402 filesvar = d.getVar('FILES:%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001403 if "//" in filesvar:
1404 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 -05001405 oe.qa.handle_error("files-invalid", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001406 filesvar.replace("//", "/")
1407
1408 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001409 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001410
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001411 if autodebug and pkg.endswith("-dbg"):
1412 files.extend(debug)
1413
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001414 for file in files:
1415 if (not cpath.islink(file)) and (not cpath.exists(file)):
1416 continue
1417 if file in seen:
1418 continue
1419 seen.append(file)
1420
1421 def mkdir(src, dest, p):
1422 src = os.path.join(src, p)
1423 dest = os.path.join(dest, p)
1424 fstat = cpath.stat(src)
Brad Bishop96ff1982019-08-19 13:50:42 -04001425 os.mkdir(dest)
1426 os.chmod(dest, fstat.st_mode)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001427 os.chown(dest, fstat.st_uid, fstat.st_gid)
1428 if p not in seen:
1429 seen.append(p)
1430 cpath.updatecache(dest)
1431
1432 def mkdir_recurse(src, dest, paths):
1433 if cpath.exists(dest + '/' + paths):
1434 return
1435 while paths.startswith("./"):
1436 paths = paths[2:]
1437 p = "."
1438 for c in paths.split("/"):
1439 p = os.path.join(p, c)
1440 if not cpath.exists(os.path.join(dest, p)):
1441 mkdir(src, dest, p)
1442
1443 if cpath.isdir(file) and not cpath.islink(file):
1444 mkdir_recurse(dvar, root, file)
1445 continue
1446
1447 mkdir_recurse(dvar, root, os.path.dirname(file))
1448 fpath = os.path.join(root,file)
1449 if not cpath.islink(file):
1450 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001451 continue
1452 ret = bb.utils.copyfile(file, fpath)
1453 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001454 bb.fatal("File population failed")
1455
1456 # Check if symlink paths exist
1457 for file in symlink_paths:
1458 if not os.path.exists(os.path.join(root,file)):
1459 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1460 "parent directory structure does not exist. One of "
1461 "its parent directories is a symlink whose target "
1462 "directory is not included in the package." %
1463 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001464
1465 os.umask(oldumask)
1466 os.chdir(workdir)
1467
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001468 # Handle excluding packages with incompatible licenses
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001469 package_list = []
Brad Bishop19323692019-04-05 15:28:33 -04001470 for pkg in packages:
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001471 licenses = d.getVar('_exclude_incompatible-' + pkg)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001472 if licenses:
1473 msg = "Excluding %s from packaging as it has incompatible license(s): %s" % (pkg, licenses)
Andrew Geisslereff27472021-10-29 15:35:00 -05001474 oe.qa.handle_error("incompatible-license", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001475 else:
1476 package_list.append(pkg)
1477 d.setVar('PACKAGES', ' '.join(package_list))
1478
1479 unshipped = []
1480 for root, dirs, files in cpath.walk(dvar):
1481 dir = root[len(dvar):]
1482 if not dir:
1483 dir = os.sep
1484 for f in (files + dirs):
1485 path = os.path.join(dir, f)
1486 if ('.' + path) not in seen:
1487 unshipped.append(path)
1488
1489 if unshipped != []:
1490 msg = pn + ": Files/directories were installed but not shipped in any package:"
Patrick Williams213cb262021-08-07 19:21:33 -05001491 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP:' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001492 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1493 else:
1494 for f in unshipped:
1495 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001496 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"
1497 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Andrew Geisslereff27472021-10-29 15:35:00 -05001498 oe.qa.handle_error("installed-vs-shipped", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001499}
1500populate_packages[dirs] = "${D}"
1501
1502python package_fixsymlinks () {
1503 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001504 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001505 packages = d.getVar("PACKAGES", False).split()
1506
1507 dangling_links = {}
1508 pkg_files = {}
1509 for pkg in packages:
1510 dangling_links[pkg] = []
1511 pkg_files[pkg] = []
1512 inst_root = os.path.join(pkgdest, pkg)
1513 for path in pkgfiles[pkg]:
1514 rpath = path[len(inst_root):]
1515 pkg_files[pkg].append(rpath)
1516 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1517 if not cpath.lexists(rtarget):
1518 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1519
1520 newrdepends = {}
1521 for pkg in dangling_links:
1522 for l in dangling_links[pkg]:
1523 found = False
1524 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1525 for p in packages:
1526 if l in pkg_files[p]:
1527 found = True
1528 bb.debug(1, "target found in %s" % p)
1529 if p == pkg:
1530 break
1531 if pkg not in newrdepends:
1532 newrdepends[pkg] = []
1533 newrdepends[pkg].append(p)
1534 break
1535 if found == False:
1536 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1537
1538 for pkg in newrdepends:
Patrick Williams213cb262021-08-07 19:21:33 -05001539 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001540 for p in newrdepends[pkg]:
1541 if p not in rdepends:
1542 rdepends[p] = []
Patrick Williams213cb262021-08-07 19:21:33 -05001543 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001544}
1545
1546
1547python package_package_name_hook() {
1548 """
1549 A package_name_hook function can be used to rewrite the package names by
1550 changing PKG. For an example, see debian.bbclass.
1551 """
1552 pass
1553}
1554
1555EXPORT_FUNCTIONS package_name_hook
1556
1557
1558PKGDESTWORK = "${WORKDIR}/pkgdata"
1559
Andrew Geissler1e34c2d2020-05-29 16:02:59 -05001560PKGDATA_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 -04001561
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001562python emit_pkgdata() {
1563 from glob import glob
1564 import json
Andrew Geissler5199d832021-09-24 16:47:35 -05001565 import bb.compress.zstd
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001566
Brad Bishop316dfdd2018-06-25 12:45:53 -04001567 def process_postinst_on_target(pkg, mlprefix):
Patrick Williams213cb262021-08-07 19:21:33 -05001568 pkgval = d.getVar('PKG:%s' % pkg)
Brad Bishop96ff1982019-08-19 13:50:42 -04001569 if pkgval is None:
1570 pkgval = pkg
1571
Brad Bishop316dfdd2018-06-25 12:45:53 -04001572 defer_fragment = """
1573if [ -n "$D" ]; then
1574 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1575 exit 0
1576fi
Brad Bishop96ff1982019-08-19 13:50:42 -04001577""" % (pkgval, mlprefix)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001578
Patrick Williams213cb262021-08-07 19:21:33 -05001579 postinst = d.getVar('pkg_postinst:%s' % pkg)
1580 postinst_ontarget = d.getVar('pkg_postinst_ontarget:%s' % pkg)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001581
1582 if postinst_ontarget:
1583 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1584 if not postinst:
1585 postinst = '#!/bin/sh\n'
1586 postinst += defer_fragment
1587 postinst += postinst_ontarget
Patrick Williams213cb262021-08-07 19:21:33 -05001588 d.setVar('pkg_postinst:%s' % pkg, postinst)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001589
1590 def add_set_e_to_scriptlets(pkg):
1591 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
Patrick Williams213cb262021-08-07 19:21:33 -05001592 scriptlet = d.getVar('%s:%s' % (scriptlet_name, pkg))
Brad Bishop316dfdd2018-06-25 12:45:53 -04001593 if scriptlet:
1594 scriptlet_split = scriptlet.split('\n')
1595 if scriptlet_split[0].startswith("#!"):
1596 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1597 else:
1598 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
Patrick Williams213cb262021-08-07 19:21:33 -05001599 d.setVar('%s:%s' % (scriptlet_name, pkg), scriptlet)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001600
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001601 def write_if_exists(f, pkg, var):
1602 def encode(str):
1603 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001604 c = codecs.getencoder("unicode_escape")
1605 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001606
Patrick Williams213cb262021-08-07 19:21:33 -05001607 val = d.getVar('%s:%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001608 if val:
Patrick Williams213cb262021-08-07 19:21:33 -05001609 f.write('%s:%s: %s\n' % (var, pkg, encode(val)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001610 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001611 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001612 if val:
1613 f.write('%s: %s\n' % (var, encode(val)))
1614 return val
1615
1616 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1617 for variant in variants:
1618 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1619 fd.write("PACKAGES: %s\n" % ' '.join(
1620 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1621
1622 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1623 for variant in variants:
1624 for pkg in packages.split():
1625 ml_pkg = "%s-%s" % (variant, pkg)
1626 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1627 with open(subdata_file, 'w') as fd:
Patrick Williams213cb262021-08-07 19:21:33 -05001628 fd.write("PKG:%s: %s" % (ml_pkg, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001629
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001630 packages = d.getVar('PACKAGES')
1631 pkgdest = d.getVar('PKGDEST')
1632 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001633
Brad Bishop64c979e2019-11-04 13:55:29 -05001634 data_file = pkgdatadir + d.expand("/${PN}")
1635 with open(data_file, 'w') as fd:
1636 fd.write("PACKAGES: %s\n" % packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001637
Andrew Geissler5199d832021-09-24 16:47:35 -05001638 pkgdebugsource = d.getVar("PKGDEBUGSOURCES") or []
1639
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001640 pn = d.getVar('PN')
1641 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1642 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001643
1644 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1645 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1646
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001647 if bb.data.inherits_class('allarch', d) and not variants \
1648 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001649 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1650
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001651 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001652
1653 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05001654 pkgval = d.getVar('PKG:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001655 if pkgval is None:
1656 pkgval = pkg
Patrick Williams213cb262021-08-07 19:21:33 -05001657 d.setVar('PKG:%s' % pkg, pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001658
Andrew Geissler5199d832021-09-24 16:47:35 -05001659 extended_data = {
1660 "files_info": {}
1661 }
1662
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001663 pkgdestpkg = os.path.join(pkgdest, pkg)
1664 files = {}
Andrew Geissler5199d832021-09-24 16:47:35 -05001665 files_extra = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001666 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001667 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001668 for f in pkgfiles[pkg]:
Andrew Geissler5199d832021-09-24 16:47:35 -05001669 fpath = os.sep + os.path.relpath(f, pkgdestpkg)
1670
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001671 fstat = os.lstat(f)
Andrew Geissler5199d832021-09-24 16:47:35 -05001672 files[fpath] = fstat.st_size
1673
1674 extended_data["files_info"].setdefault(fpath, {})
1675 extended_data["files_info"][fpath]['size'] = fstat.st_size
1676
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001677 if fstat.st_ino not in seen:
1678 seen.add(fstat.st_ino)
1679 total_size += fstat.st_size
Andrew Geissler5199d832021-09-24 16:47:35 -05001680
1681 if fpath in pkgdebugsource:
1682 extended_data["files_info"][fpath]['debugsrc'] = pkgdebugsource[fpath]
1683 del pkgdebugsource[fpath]
1684
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001685 d.setVar('FILES_INFO:' + pkg , json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001686
Brad Bishop316dfdd2018-06-25 12:45:53 -04001687 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1688 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001689
Brad Bishop15ae2502019-06-18 21:44:24 -04001690 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1691 with open(subdata_file, 'w') as sf:
1692 for var in (d.getVar('PKGDATA_VARS') or "").split():
1693 val = write_if_exists(sf, pkg, var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001694
Brad Bishop15ae2502019-06-18 21:44:24 -04001695 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
Andrew Geissler5199d832021-09-24 16:47:35 -05001696 for dfile in sorted((d.getVar('FILERPROVIDESFLIST:' + pkg) or "").split()):
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001697 write_if_exists(sf, pkg, 'FILERPROVIDES:' + dfile)
Brad Bishop15ae2502019-06-18 21:44:24 -04001698
1699 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Andrew Geissler5199d832021-09-24 16:47:35 -05001700 for dfile in sorted((d.getVar('FILERDEPENDSFLIST:' + pkg) or "").split()):
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001701 write_if_exists(sf, pkg, 'FILERDEPENDS:' + dfile)
Brad Bishop15ae2502019-06-18 21:44:24 -04001702
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001703 sf.write('%s:%s: %d\n' % ('PKGSIZE', pkg, total_size))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001704
Andrew Geissler5199d832021-09-24 16:47:35 -05001705 subdata_extended_file = pkgdatadir + "/extended/%s.json.zstd" % pkg
1706 num_threads = int(d.getVar("BB_NUMBER_THREADS"))
1707 with bb.compress.zstd.open(subdata_extended_file, "wt", encoding="utf-8", num_threads=num_threads) as f:
1708 json.dump(extended_data, f, sort_keys=True, separators=(",", ":"))
1709
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001710 # Symlinks needed for rprovides lookup
Patrick Williams213cb262021-08-07 19:21:33 -05001711 rprov = d.getVar('RPROVIDES:%s' % pkg) or d.getVar('RPROVIDES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001712 if rprov:
Andrew Geisslerc9f78652020-09-18 14:11:35 -05001713 for p in bb.utils.explode_deps(rprov):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001714 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1715 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1716 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1717
Patrick Williams213cb262021-08-07 19:21:33 -05001718 allow_empty = d.getVar('ALLOW_EMPTY:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001719 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001720 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001721 root = "%s/%s" % (pkgdest, pkg)
1722 os.chdir(root)
1723 g = glob('*')
1724 if g or allow_empty == "1":
1725 # Symlinks needed for reverse lookups (from the final package name)
1726 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1727 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1728
1729 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1730 open(packagedfile, 'w').close()
1731
1732 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1733 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1734
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001735 if bb.data.inherits_class('allarch', d) and not variants \
1736 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001737 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1738
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001739}
Andrew Geissler5199d832021-09-24 16:47:35 -05001740emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides ${PKGDESTWORK}/extended"
1741emit_pkgdata[vardepsexclude] = "BB_NUMBER_THREADS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001742
1743ldconfig_postinst_fragment() {
1744if [ x"$D" = "x" ]; then
1745 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1746fi
1747}
1748
Andrew Geissler90fd73c2021-03-05 15:25:55 -06001749RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps --define '__font_provides %{nil}'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001750
1751# Collect perfile run-time dependency metadata
1752# Output:
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001753# FILERPROVIDESFLIST:pkg - list of all files w/ deps
1754# FILERPROVIDES:filepath:pkg - per file dep
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001755#
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001756# FILERDEPENDSFLIST:pkg - list of all files w/ deps
1757# FILERDEPENDS:filepath:pkg - per file dep
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001758
1759python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001760 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001761 return
1762
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001763 pkgdest = d.getVar('PKGDEST')
1764 packages = d.getVar('PACKAGES')
1765 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001766
1767 def chunks(files, n):
1768 return [files[i:i+n] for i in range(0, len(files), n)]
1769
1770 pkglist = []
1771 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05001772 if d.getVar('SKIP_FILEDEPS:' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001773 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001774 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 -05001775 continue
1776 for files in chunks(pkgfiles[pkg], 100):
1777 pkglist.append((pkg, files, rpmdeps, pkgdest))
1778
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001779 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001780
1781 provides_files = {}
1782 requires_files = {}
1783
1784 for result in processed:
1785 (pkg, provides, requires) = result
1786
1787 if pkg not in provides_files:
1788 provides_files[pkg] = []
1789 if pkg not in requires_files:
1790 requires_files[pkg] = []
1791
Brad Bishop19323692019-04-05 15:28:33 -04001792 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001793 provides_files[pkg].append(file)
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001794 key = "FILERPROVIDES:" + file + ":" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001795 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001796
Brad Bishop19323692019-04-05 15:28:33 -04001797 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001798 requires_files[pkg].append(file)
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001799 key = "FILERDEPENDS:" + file + ":" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001800 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001801
1802 for pkg in requires_files:
Andrew Geissler5199d832021-09-24 16:47:35 -05001803 d.setVar("FILERDEPENDSFLIST:" + pkg, " ".join(sorted(requires_files[pkg])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001804 for pkg in provides_files:
Andrew Geissler5199d832021-09-24 16:47:35 -05001805 d.setVar("FILERPROVIDESFLIST:" + pkg, " ".join(sorted(provides_files[pkg])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001806}
1807
Brad Bishop96ff1982019-08-19 13:50:42 -04001808SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001809SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1810
1811python package_do_shlibs() {
Brad Bishop00e122a2019-10-05 11:10:57 -04001812 import itertools
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001813 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001814 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001815
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001816 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001817 if exclude_shlibs:
1818 bb.note("not generating shlibs")
1819 return
1820
Brad Bishop19323692019-04-05 15:28:33 -04001821 lib_re = re.compile(r"^.*\.so")
1822 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001823
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001824 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001825
1826 shlib_pkgs = []
1827 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1828 if exclusion_list:
1829 for pkg in packages.split():
1830 if pkg not in exclusion_list.split():
1831 shlib_pkgs.append(pkg)
1832 else:
1833 bb.note("not generating shlibs for %s" % pkg)
1834 else:
1835 shlib_pkgs = packages.split()
1836
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001837 hostos = d.getVar('HOST_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001838
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001839 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001840
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001841 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001842 if not ver:
1843 msg = "PKGV not defined"
Andrew Geisslereff27472021-10-29 15:35:00 -05001844 oe.qa.handle_error("pkgv-undefined", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001845 return
1846
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001847 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001848
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001849 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001850
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001851 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001852 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001853 needed = set()
1854 sonames = set()
1855 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001856 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001857 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001858 fd = os.popen(cmd)
1859 lines = fd.readlines()
1860 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001861 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001862 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001863 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001864 if m:
1865 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001866 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001867 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001868 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001869 if m:
1870 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001871 if dep not in needed:
1872 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001873 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001874 if m:
1875 this_soname = m.group(1)
1876 prov = (this_soname, ldir, pkgver)
1877 if not prov in sonames:
1878 # if library is private (only used by package) then do not build shlib for it
Brad Bishop79641f22019-09-10 07:20:22 -04001879 import fnmatch
1880 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 -08001881 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001882 if libdir_re.match(os.path.dirname(file)):
1883 needs_ldconfig = True
Andrew Geissler595f6302022-01-24 19:11:47 +00001884 if needs_ldconfig and snap_symlinks and (os.path.basename(file) != this_soname):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001885 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001886 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001887
1888 def darwin_so(file, needed, sonames, renames, pkgver):
1889 if not os.path.exists(file):
1890 return
1891 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1892
1893 def get_combinations(base):
1894 #
1895 # Given a base library name, find all combinations of this split by "." and "-"
1896 #
1897 combos = []
1898 options = base.split(".")
1899 for i in range(1, len(options) + 1):
1900 combos.append(".".join(options[0:i]))
1901 options = base.split("-")
1902 for i in range(1, len(options) + 1):
1903 combos.append("-".join(options[0:i]))
1904 return combos
1905
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001906 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 -05001907 # Drop suffix
1908 name = os.path.basename(file).rsplit(".",1)[0]
1909 # Find all combinations
1910 combos = get_combinations(name)
1911 for combo in combos:
1912 if not combo in sonames:
1913 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001914 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001915 if file.endswith('.dylib') or file.endswith('.so'):
1916 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001917 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001918 out, err = p.communicate()
1919 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001920 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001921 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001922 l = l.strip()
1923 if l.startswith('path '):
1924 rpath.append(l.split()[1])
1925
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001926 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001927 out, err = p.communicate()
1928 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001929 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001930 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001931 l = l.strip()
1932 if not l or l.endswith(":"):
1933 continue
1934 if "is not an object file" in l:
1935 continue
1936 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1937 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001938 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001939
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001940 def mingw_dll(file, needed, sonames, renames, pkgver):
1941 if not os.path.exists(file):
1942 return
1943
1944 if file.endswith(".dll"):
1945 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001946 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001947
1948 if (file.endswith(".dll") or file.endswith(".exe")):
1949 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001950 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001951 out, err = p.communicate()
1952 # process the output, grabbing all .dll names
1953 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001954 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001955 dllname = m.group(1)
1956 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001957 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001958
1959 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001960 snap_symlinks = True
1961 else:
1962 snap_symlinks = False
1963
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001964 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001965
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001966 shlib_provider = oe.package.read_shlib_providers(d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001967
1968 for pkg in shlib_pkgs:
Patrick Williams213cb262021-08-07 19:21:33 -05001969 private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001970 private_libs = private_libs.split()
1971 needs_ldconfig = False
1972 bb.debug(2, "calculating shlib provides for %s" % pkg)
1973
Patrick Williams213cb262021-08-07 19:21:33 -05001974 pkgver = d.getVar('PKGV:' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001975 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001976 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001977 if not pkgver:
1978 pkgver = ver
1979
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001980 needed[pkg] = set()
1981 sonames = set()
1982 renames = []
1983 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001984 for file in pkgfiles[pkg]:
1985 soname = None
1986 if cpath.islink(file):
1987 continue
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001988 if hostos == "darwin" or hostos == "darwin8":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001989 darwin_so(file, needed, sonames, renames, pkgver)
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001990 elif hostos.startswith("mingw"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001991 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001992 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001993 linuxlist.append(file)
1994
1995 if linuxlist:
1996 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1997 for r in results:
1998 ldconfig = r[0]
1999 needed[pkg] |= r[1]
2000 sonames |= r[2]
2001 renames.extend(r[3])
2002 needs_ldconfig = needs_ldconfig or ldconfig
2003
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002004 for (old, new) in renames:
2005 bb.note("Renaming %s to %s" % (old, new))
Andrew Geisslerc926e172021-05-07 16:11:35 -05002006 bb.utils.rename(old, new)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002007 pkgfiles[pkg].remove(old)
Brad Bishop64c979e2019-11-04 13:55:29 -05002008
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002009 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
2010 if len(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05002011 with open(shlibs_file, 'w') as fd:
Andrew Geissler635e0e42020-08-21 15:58:33 -05002012 for s in sorted(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05002013 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
2014 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
2015 if old_pkg != pkg:
2016 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))
2017 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
2018 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
2019 if s[0] not in shlib_provider:
2020 shlib_provider[s[0]] = {}
2021 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
Brad Bishop1d80a2e2019-11-15 16:35:03 -05002022 if needs_ldconfig:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002023 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Patrick Williams213cb262021-08-07 19:21:33 -05002024 postinst = d.getVar('pkg_postinst:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002025 if not postinst:
2026 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002027 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williams213cb262021-08-07 19:21:33 -05002028 d.setVar('pkg_postinst:%s' % pkg, postinst)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002029 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
2030
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002031 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002032 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002033 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002034 for e in assumed_libs.split():
2035 l, dep_pkg = e.split(":")
2036 lib_ver = None
2037 dep_pkg = dep_pkg.rsplit("_", 1)
2038 if len(dep_pkg) == 2:
2039 lib_ver = dep_pkg[1]
2040 dep_pkg = dep_pkg[0]
2041 if l not in shlib_provider:
2042 shlib_provider[l] = {}
2043 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
2044
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002045 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002046
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002047 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002048 bb.debug(2, "calculating shlib requirements for %s" % pkg)
2049
Patrick Williams213cb262021-08-07 19:21:33 -05002050 private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Brad Bishop316dfdd2018-06-25 12:45:53 -04002051 private_libs = private_libs.split()
2052
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002053 deps = list()
2054 for n in needed[pkg]:
2055 # if n is in private libraries, don't try to search provider for it
2056 # this could cause problem in case some abc.bb provides private
2057 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
2058 # but skipping it is still better alternative than providing own
2059 # version and then adding runtime dependency for the same system library
Brad Bishop79641f22019-09-10 07:20:22 -04002060 import fnmatch
2061 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 -05002062 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
2063 continue
2064 if n[0] in shlib_provider.keys():
Brad Bishop00e122a2019-10-05 11:10:57 -04002065 shlib_provider_map = shlib_provider[n[0]]
2066 matches = set()
2067 for p in itertools.chain(list(n[2]), sorted(shlib_provider_map.keys()), libsearchpath):
2068 if p in shlib_provider_map:
2069 matches.add(p)
2070 if len(matches) > 1:
2071 matchpkgs = ', '.join([shlib_provider_map[match][0] for match in matches])
2072 bb.error("%s: Multiple shlib providers for %s: %s (used by files: %s)" % (pkg, n[0], matchpkgs, n[1]))
2073 elif len(matches) == 1:
2074 (dep_pkg, ver_needed) = shlib_provider_map[matches.pop()]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002075
2076 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
2077
2078 if dep_pkg == pkg:
2079 continue
2080
2081 if ver_needed:
2082 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
2083 else:
2084 dep = dep_pkg
2085 if not dep in deps:
2086 deps.append(dep)
2087 continue
2088 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
2089
2090 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
2091 if os.path.exists(deps_file):
2092 os.remove(deps_file)
Brad Bishop64c979e2019-11-04 13:55:29 -05002093 if deps:
2094 with open(deps_file, 'w') as fd:
2095 for dep in sorted(deps):
2096 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002097}
2098
2099python package_do_pkgconfig () {
2100 import re
2101
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002102 packages = d.getVar('PACKAGES')
2103 workdir = d.getVar('WORKDIR')
2104 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002105
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002106 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
2107 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002108
Brad Bishop19323692019-04-05 15:28:33 -04002109 pc_re = re.compile(r'(.*)\.pc$')
2110 var_re = re.compile(r'(.*)=(.*)')
2111 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002112
2113 pkgconfig_provided = {}
2114 pkgconfig_needed = {}
2115 for pkg in packages.split():
2116 pkgconfig_provided[pkg] = []
2117 pkgconfig_needed[pkg] = []
Patrick Williams93c203f2021-10-06 16:15:23 -05002118 for file in sorted(pkgfiles[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002119 m = pc_re.match(file)
2120 if m:
2121 pd = bb.data.init()
2122 name = m.group(1)
Patrick Williams93c203f2021-10-06 16:15:23 -05002123 pkgconfig_provided[pkg].append(os.path.basename(name))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002124 if not os.access(file, os.R_OK):
2125 continue
Brad Bishop64c979e2019-11-04 13:55:29 -05002126 with open(file, 'r') as f:
2127 lines = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002128 for l in lines:
2129 m = var_re.match(l)
2130 if m:
2131 name = m.group(1)
2132 val = m.group(2)
2133 pd.setVar(name, pd.expand(val))
2134 continue
2135 m = field_re.match(l)
2136 if m:
2137 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002138 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002139 if hdr == 'Requires':
2140 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
2141
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002142 for pkg in packages.split():
2143 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
2144 if pkgconfig_provided[pkg] != []:
Brad Bishop64c979e2019-11-04 13:55:29 -05002145 with open(pkgs_file, 'w') as f:
Patrick Williams93c203f2021-10-06 16:15:23 -05002146 for p in sorted(pkgconfig_provided[pkg]):
Brad Bishop64c979e2019-11-04 13:55:29 -05002147 f.write('%s\n' % p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002148
2149 # Go from least to most specific since the last one found wins
2150 for dir in reversed(shlibs_dirs):
2151 if not os.path.exists(dir):
2152 continue
Brad Bishop08902b02019-08-20 09:16:51 -04002153 for file in sorted(os.listdir(dir)):
Brad Bishop19323692019-04-05 15:28:33 -04002154 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002155 if m:
2156 pkg = m.group(1)
Brad Bishop64c979e2019-11-04 13:55:29 -05002157 with open(os.path.join(dir, file)) as fd:
2158 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002159 pkgconfig_provided[pkg] = []
2160 for l in lines:
2161 pkgconfig_provided[pkg].append(l.rstrip())
2162
2163 for pkg in packages.split():
2164 deps = []
2165 for n in pkgconfig_needed[pkg]:
2166 found = False
2167 for k in pkgconfig_provided.keys():
2168 if n in pkgconfig_provided[k]:
2169 if k != pkg and not (k in deps):
2170 deps.append(k)
2171 found = True
2172 if found == False:
2173 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
2174 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
2175 if len(deps):
Brad Bishop64c979e2019-11-04 13:55:29 -05002176 with open(deps_file, 'w') as fd:
2177 for dep in deps:
2178 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002179}
2180
2181def read_libdep_files(d):
2182 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002183 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002184 for pkg in packages:
2185 pkglibdeps[pkg] = {}
2186 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
2187 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
2188 if os.access(depsfile, os.R_OK):
Brad Bishop64c979e2019-11-04 13:55:29 -05002189 with open(depsfile) as fd:
2190 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002191 for l in lines:
2192 l.rstrip()
2193 deps = bb.utils.explode_dep_versions2(l)
2194 for dep in deps:
2195 if not dep in pkglibdeps[pkg]:
2196 pkglibdeps[pkg][dep] = deps[dep]
2197 return pkglibdeps
2198
2199python read_shlibdeps () {
2200 pkglibdeps = read_libdep_files(d)
2201
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002202 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002203 for pkg in packages:
Patrick Williams213cb262021-08-07 19:21:33 -05002204 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04002205 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002206 # Add the dep if it's not already there, or if no comparison is set
2207 if dep not in rdepends:
2208 rdepends[dep] = []
2209 for v in pkglibdeps[pkg][dep]:
2210 if v not in rdepends[dep]:
2211 rdepends[dep].append(v)
Patrick Williams213cb262021-08-07 19:21:33 -05002212 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002213}
2214
2215python package_depchains() {
2216 """
2217 For a given set of prefix and postfix modifiers, make those packages
2218 RRECOMMENDS on the corresponding packages for its RDEPENDS.
2219
2220 Example: If package A depends upon package B, and A's .bb emits an
2221 A-dev package, this would make A-dev Recommends: B-dev.
2222
2223 If only one of a given suffix is specified, it will take the RRECOMMENDS
2224 based on the RDEPENDS of *all* other packages. If more than one of a given
2225 suffix is specified, its will only use the RDEPENDS of the single parent
2226 package.
2227 """
2228
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002229 packages = d.getVar('PACKAGES')
2230 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2231 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002232
2233 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2234
2235 #bb.note('depends for %s is %s' % (base, depends))
Patrick Williams213cb262021-08-07 19:21:33 -05002236 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002237
Brad Bishop19323692019-04-05 15:28:33 -04002238 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002239 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2240 #bb.note("Skipping %s" % depend)
2241 continue
2242 if depend.endswith('-dev'):
2243 depend = depend[:-4]
2244 if depend.endswith('-dbg'):
2245 depend = depend[:-4]
2246 pkgname = getname(depend, suffix)
2247 #bb.note("Adding %s for %s" % (pkgname, depend))
2248 if pkgname not in rreclist and pkgname != pkg:
2249 rreclist[pkgname] = []
2250
Patrick Williams213cb262021-08-07 19:21:33 -05002251 #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist)))
2252 d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002253
2254 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2255
2256 #bb.note('rdepends for %s is %s' % (base, rdepends))
Patrick Williams213cb262021-08-07 19:21:33 -05002257 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002258
Brad Bishop19323692019-04-05 15:28:33 -04002259 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002260 if depend.find('virtual-locale-') != -1:
2261 #bb.note("Skipping %s" % depend)
2262 continue
2263 if depend.endswith('-dev'):
2264 depend = depend[:-4]
2265 if depend.endswith('-dbg'):
2266 depend = depend[:-4]
2267 pkgname = getname(depend, suffix)
2268 #bb.note("Adding %s for %s" % (pkgname, depend))
2269 if pkgname not in rreclist and pkgname != pkg:
2270 rreclist[pkgname] = []
2271
Patrick Williams213cb262021-08-07 19:21:33 -05002272 #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist)))
2273 d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002274
2275 def add_dep(list, dep):
2276 if dep not in list:
2277 list.append(dep)
2278
2279 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002280 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002281 add_dep(depends, dep)
2282
2283 rdepends = []
2284 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05002285 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002286 add_dep(rdepends, dep)
2287
2288 #bb.note('rdepends is %s' % rdepends)
2289
2290 def post_getname(name, suffix):
2291 return '%s%s' % (name, suffix)
2292 def pre_getname(name, suffix):
2293 return '%s%s' % (suffix, name)
2294
2295 pkgs = {}
2296 for pkg in packages.split():
2297 for postfix in postfixes:
2298 if pkg.endswith(postfix):
2299 if not postfix in pkgs:
2300 pkgs[postfix] = {}
2301 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2302
2303 for prefix in prefixes:
2304 if pkg.startswith(prefix):
2305 if not prefix in pkgs:
2306 pkgs[prefix] = {}
2307 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2308
2309 if "-dbg" in pkgs:
2310 pkglibdeps = read_libdep_files(d)
2311 pkglibdeplist = []
2312 for pkg in pkglibdeps:
2313 for k in pkglibdeps[pkg]:
2314 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002315 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002316
2317 for suffix in pkgs:
2318 for pkg in pkgs[suffix]:
Patrick Williams213cb262021-08-07 19:21:33 -05002319 if d.getVarFlag('RRECOMMENDS:' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002320 continue
2321 (base, func) = pkgs[suffix][pkg]
2322 if suffix == "-dev":
2323 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2324 elif suffix == "-dbg":
2325 if not dbgdefaultdeps:
2326 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2327 continue
2328 if len(pkgs[suffix]) == 1:
2329 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2330 else:
2331 rdeps = []
Patrick Williams213cb262021-08-07 19:21:33 -05002332 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002333 add_dep(rdeps, dep)
2334 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2335}
2336
2337# Since bitbake can't determine which variables are accessed during package
2338# iteration, we need to list them here:
Andrew Geissler1e34c2d2020-05-29 16:02:59 -05002339PACKAGEVARS = "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 -05002340
Andrew Geissler82c905d2020-04-13 13:39:40 -05002341def gen_packagevar(d, pkgvars="PACKAGEVARS"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002342 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002343 pkgs = (d.getVar("PACKAGES") or "").split()
Andrew Geissler82c905d2020-04-13 13:39:40 -05002344 vars = (d.getVar(pkgvars) or "").split()
2345 for v in vars:
2346 ret.append(v)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002347 for p in pkgs:
2348 for v in vars:
Patrick Williams213cb262021-08-07 19:21:33 -05002349 ret.append(v + ":" + p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002350
2351 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2352 # affected recipes.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002353 ret.append('_exclude_incompatible-%s' % p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002354 return " ".join(ret)
2355
2356PACKAGE_PREPROCESS_FUNCS ?= ""
2357# Functions for setting up PKGD
2358PACKAGEBUILDPKGD ?= " \
Brad Bishop96ff1982019-08-19 13:50:42 -04002359 package_prepare_pkgdata \
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002360 perform_packagecopy \
2361 ${PACKAGE_PREPROCESS_FUNCS} \
2362 split_and_strip_files \
2363 fixup_perms \
2364 "
2365# Functions which split PKGD up into separate packages
2366PACKAGESPLITFUNCS ?= " \
2367 package_do_split_locales \
2368 populate_packages"
2369# Functions which process metadata based on split packages
2370PACKAGEFUNCS += " \
2371 package_fixsymlinks \
2372 package_name_hook \
2373 package_do_filedeps \
2374 package_do_shlibs \
2375 package_do_pkgconfig \
2376 read_shlibdeps \
2377 package_depchains \
2378 emit_pkgdata"
2379
2380python do_package () {
2381 # Change the following version to cause sstate to invalidate the package
2382 # cache. This is useful if an item this class depends on changes in a
2383 # way that the output of this class changes. rpmdeps is a good example
2384 # as any change to rpmdeps requires this to be rerun.
Andrew Geissler6ce62a22020-11-30 19:58:47 -06002385 # PACKAGE_BBCLASS_VERSION = "4"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002386
2387 # Init cachedpath
2388 global cpath
2389 cpath = oe.cachedpath.CachedPath()
2390
2391 ###########################################################################
2392 # Sanity test the setup
2393 ###########################################################################
2394
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002395 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002396 if len(packages) < 1:
2397 bb.debug(1, "No packages to build, skipping do_package")
2398 return
2399
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002400 workdir = d.getVar('WORKDIR')
2401 outdir = d.getVar('DEPLOY_DIR')
2402 dest = d.getVar('D')
2403 dvar = d.getVar('PKGD')
2404 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002405
2406 if not workdir or not outdir or not dest or not dvar or not pn:
2407 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
Andrew Geisslereff27472021-10-29 15:35:00 -05002408 oe.qa.handle_error("var-undefined", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002409 return
2410
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002411 bb.build.exec_func("package_convert_pr_autoinc", d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002412
2413 ###########################################################################
2414 # Optimisations
2415 ###########################################################################
2416
2417 # Continually expanding complex expressions is inefficient, particularly
2418 # when we write to the datastore and invalidate the expansion cache. This
2419 # code pre-expands some frequently used variables
2420
2421 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002422 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002423
2424 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2425 expandVar(x, d)
2426
2427 ###########################################################################
2428 # Setup PKGD (from D)
2429 ###########################################################################
2430
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002431 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002432 bb.build.exec_func(f, d)
2433
2434 ###########################################################################
2435 # Split up PKGD into PKGDEST
2436 ###########################################################################
2437
2438 cpath = oe.cachedpath.CachedPath()
2439
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002440 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002441 bb.build.exec_func(f, d)
2442
2443 ###########################################################################
2444 # Process PKGDEST
2445 ###########################################################################
2446
2447 # Build global list of files in each split package
2448 global pkgfiles
2449 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002450 packages = d.getVar('PACKAGES').split()
2451 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002452 for pkg in packages:
2453 pkgfiles[pkg] = []
2454 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2455 for file in files:
2456 pkgfiles[pkg].append(walkroot + os.sep + file)
2457
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002458 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002459 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002460
Andrew Geisslereff27472021-10-29 15:35:00 -05002461 oe.qa.exit_if_errors(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002462}
2463
Andrew Geissler9aee5002022-03-30 16:27:02 +00002464do_package[dirs] = "${SHLIBSWORKDIR} ${D}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002465do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2466addtask package after do_install
2467
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002468SSTATETASKS += "do_package"
2469do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2470do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002471do_package_setscene[dirs] = "${STAGING_DIR}"
2472
2473python do_package_setscene () {
2474 sstate_setscene(d)
2475}
2476addtask do_package_setscene
2477
Brad Bishopc68388fc2019-08-26 01:33:31 -04002478# Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both
2479# do_package_setscene and do_packagedata_setscene leading to races
2480python do_packagedata () {
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002481 bb.build.exec_func("package_get_auto_pr", d)
2482
Brad Bishopc68388fc2019-08-26 01:33:31 -04002483 src = d.expand("${PKGDESTWORK}")
2484 dest = d.expand("${WORKDIR}/pkgdata-pdata-input")
2485 oe.path.copyhardlinktree(src, dest)
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002486
2487 bb.build.exec_func("packagedata_translate_pr_autoinc", d)
2488}
Andrew Geisslerd1e89492021-02-12 15:35:20 -06002489do_packagedata[cleandirs] += "${WORKDIR}/pkgdata-pdata-input"
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002490
2491# Translate the EXTENDPRAUTO and AUTOINC to the final values
2492packagedata_translate_pr_autoinc() {
2493 find ${WORKDIR}/pkgdata-pdata-input -type f | xargs --no-run-if-empty \
2494 sed -e 's,@PRSERV_PV_AUTOINC@,${PRSERV_PV_AUTOINC},g' \
2495 -e 's,@EXTENDPRAUTO@,${EXTENDPRAUTO},g' -i
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002496}
2497
2498addtask packagedata before do_build after do_package
2499
2500SSTATETASKS += "do_packagedata"
Brad Bishopc68388fc2019-08-26 01:33:31 -04002501do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002502do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002503do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002504
2505python do_packagedata_setscene () {
2506 sstate_setscene(d)
2507}
2508addtask do_packagedata_setscene
2509
2510#
2511# Helper functions for the package writing classes
2512#
2513
2514def mapping_rename_hook(d):
2515 """
2516 Rewrite variables to account for package renaming in things
2517 like debian.bbclass or manual PKG variable name changes
2518 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002519 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002520 runtime_mapping_rename("RDEPENDS", pkg, d)
2521 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2522 runtime_mapping_rename("RSUGGESTS", pkg, d)