blob: 4927fb99ff1948cd98eda4cf894d7c03b7d0acc4 [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
Brad Bishop19323692019-04-05 15:28:33 -0400370def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, 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):]
381 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
382 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...
400 if debugsrcdir:
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 Geissler82c905d2020-04-13 13:39:40 -0500415def splitstaticdebuginfo(file, dvar, debugstaticdir, debugstaticlibdir, debugstaticappend, debugsrcdir, d):
416 # Unlike the function above, there is no way to split a static library
417 # two components. So to get similar results we will copy the unmodified
418 # static library (containing the debug symbols) into a new directory.
419 # We will then strip (preserving symbols) the static library in the
420 # typical location.
421 #
422 # return a mapping of files:debugsources
423
424 import stat
425 import shutil
426
427 src = file[len(dvar):]
428 dest = debugstaticlibdir + os.path.dirname(src) + debugstaticdir + "/" + os.path.basename(src) + debugstaticappend
429 debugfile = dvar + dest
430 sources = []
431
432 # Copy the file...
433 bb.utils.mkdirhier(os.path.dirname(debugfile))
434 #bb.note("Copy %s -> %s" % (file, debugfile))
435
436 dvar = d.getVar('PKGD')
437
438 newmode = None
439 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
440 origmode = os.stat(file)[stat.ST_MODE]
441 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
442 os.chmod(file, newmode)
443
444 # We need to extract the debug src information here...
445 if debugsrcdir:
446 sources = source_info(file, d)
447
448 bb.utils.mkdirhier(os.path.dirname(debugfile))
449
450 # Copy the unmodified item to the debug directory
451 shutil.copy2(file, debugfile)
452
453 if newmode:
454 os.chmod(file, origmode)
455
456 return (file, sources)
457
458def inject_minidebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d):
459 # Extract just the symbols from debuginfo into minidebuginfo,
460 # compress it with xz and inject it back into the binary in a .gnu_debugdata section.
461 # https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
462
463 import subprocess
464
465 readelf = d.getVar('READELF')
466 nm = d.getVar('NM')
467 objcopy = d.getVar('OBJCOPY')
468
469 minidebuginfodir = d.expand('${WORKDIR}/minidebuginfo')
470
471 src = file[len(dvar):]
472 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
473 debugfile = dvar + dest
474 minidebugfile = minidebuginfodir + src + '.minidebug'
475 bb.utils.mkdirhier(os.path.dirname(minidebugfile))
476
477 # If we didn't produce debuginfo for any reason, we can't produce minidebuginfo either
478 # so skip it.
479 if not os.path.exists(debugfile):
480 bb.debug(1, 'ELF file {} has no debuginfo, skipping minidebuginfo injection'.format(file))
481 return
482
483 # Find non-allocated PROGBITS, NOTE, and NOBITS sections in the debuginfo.
484 # We will exclude all of these from minidebuginfo to save space.
485 remove_section_names = []
486 for line in subprocess.check_output([readelf, '-W', '-S', debugfile], universal_newlines=True).splitlines():
487 fields = line.split()
488 if len(fields) < 8:
489 continue
490 name = fields[0]
491 type = fields[1]
492 flags = fields[7]
493 # .debug_ sections will be removed by objcopy -S so no need to explicitly remove them
494 if name.startswith('.debug_'):
495 continue
496 if 'A' not in flags and type in ['PROGBITS', 'NOTE', 'NOBITS']:
497 remove_section_names.append(name)
498
499 # List dynamic symbols in the binary. We can exclude these from minidebuginfo
500 # because they are always present in the binary.
501 dynsyms = set()
502 for line in subprocess.check_output([nm, '-D', file, '--format=posix', '--defined-only'], universal_newlines=True).splitlines():
503 dynsyms.add(line.split()[0])
504
505 # Find all function symbols from debuginfo which aren't in the dynamic symbols table.
506 # These are the ones we want to keep in minidebuginfo.
507 keep_symbols_file = minidebugfile + '.symlist'
508 found_any_symbols = False
509 with open(keep_symbols_file, 'w') as f:
510 for line in subprocess.check_output([nm, debugfile, '--format=sysv', '--defined-only'], universal_newlines=True).splitlines():
511 fields = line.split('|')
512 if len(fields) < 7:
513 continue
514 name = fields[0].strip()
515 type = fields[3].strip()
516 if type == 'FUNC' and name not in dynsyms:
517 f.write('{}\n'.format(name))
518 found_any_symbols = True
519
520 if not found_any_symbols:
521 bb.debug(1, 'ELF file {} contains no symbols, skipping minidebuginfo injection'.format(file))
522 return
523
524 bb.utils.remove(minidebugfile)
525 bb.utils.remove(minidebugfile + '.xz')
526
527 subprocess.check_call([objcopy, '-S'] +
528 ['--remove-section={}'.format(s) for s in remove_section_names] +
529 ['--keep-symbols={}'.format(keep_symbols_file), debugfile, minidebugfile])
530
531 subprocess.check_call(['xz', '--keep', minidebugfile])
532
533 subprocess.check_call([objcopy, '--add-section', '.gnu_debugdata={}.xz'.format(minidebugfile), file])
534
Brad Bishop19323692019-04-05 15:28:33 -0400535def copydebugsources(debugsrcdir, sources, d):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400536 # The debug src information written out to sourcefile is further processed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500537 # and copied to the destination here.
538
539 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800540 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500541
Brad Bishop19323692019-04-05 15:28:33 -0400542 if debugsrcdir and sources:
543 sourcefile = d.expand("${WORKDIR}/debugsources.list")
544 bb.utils.remove(sourcefile)
545
546 # filenames are null-separated - this is an artefact of the previous use
547 # of rpm's debugedit, which was writing them out that way, and the code elsewhere
548 # is still assuming that.
549 debuglistoutput = '\0'.join(sources) + '\0'
550 with open(sourcefile, 'a') as sf:
551 sf.write(debuglistoutput)
552
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500553 dvar = d.getVar('PKGD')
554 strip = d.getVar("STRIP")
555 objcopy = d.getVar("OBJCOPY")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500556 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557 workparentdir = os.path.dirname(os.path.dirname(workdir))
558 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
559
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500560 # If build path exists in sourcefile, it means toolchain did not use
561 # -fdebug-prefix-map to compile
562 if checkbuildpath(sourcefile, d):
563 localsrc_prefix = workparentdir + "/"
564 else:
565 localsrc_prefix = "/usr/src/debug/"
566
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500567 nosuchdir = []
568 basepath = dvar
569 for p in debugsrcdir.split("/"):
570 basepath = basepath + "/" + p
571 if not cpath.exists(basepath):
572 nosuchdir.append(basepath)
573 bb.utils.mkdirhier(basepath)
574 cpath.updatecache(basepath)
575
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500576 # Ignore files from the recipe sysroots (target and native)
577 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500578 # We need to ignore files that are not actually ours
579 # we do this by only paying attention to items from this package
580 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500581 # Remove prefix in the source paths
582 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500583 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
584
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500585 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800586 try:
587 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
588 except subprocess.CalledProcessError:
589 # Can "fail" if internal headers/transient sources are attempted
590 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500591
592 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
593 # Work around this by manually finding and copying any symbolic links that made it through.
Brad Bishop19323692019-04-05 15:28:33 -0400594 cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s')" % \
595 (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800596 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500597
598 # The copy by cpio may have resulted in some empty directories! Remove these
599 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800600 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500601
602 # Also remove debugsrcdir if its empty
603 for p in nosuchdir[::-1]:
604 if os.path.exists(p) and not os.listdir(p):
605 os.rmdir(p)
606
607#
608# Package data handling routines
609#
610
Andrew Geissler82c905d2020-04-13 13:39:40 -0500611def get_package_mapping (pkg, basepkg, d, depversions=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500612 import oe.packagedata
613
614 data = oe.packagedata.read_subpkgdata(pkg, d)
Patrick Williams213cb262021-08-07 19:21:33 -0500615 key = "PKG:%s" % pkg
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500616
617 if key in data:
Andrew Geissler595f6302022-01-24 19:11:47 +0000618 if bb.data.inherits_class('allarch', d) and bb.data.inherits_class('packagegroup', d) and pkg != data[key]:
619 bb.error("An allarch packagegroup shouldn't depend on packages which are dynamically renamed (%s to %s)" % (pkg, data[key]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500620 # Have to avoid undoing the write_extra_pkgs(global_variants...)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800621 if bb.data.inherits_class('allarch', d) and not d.getVar('MULTILIB_VARIANTS') \
622 and data[key] == basepkg:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623 return pkg
Andrew Geissler82c905d2020-04-13 13:39:40 -0500624 if depversions == []:
625 # Avoid returning a mapping if the renamed package rprovides its original name
Patrick Williams213cb262021-08-07 19:21:33 -0500626 rprovkey = "RPROVIDES:%s" % pkg
Andrew Geissler82c905d2020-04-13 13:39:40 -0500627 if rprovkey in data:
628 if pkg in bb.utils.explode_dep_versions2(data[rprovkey]):
629 bb.note("%s rprovides %s, not replacing the latter" % (data[key], pkg))
630 return pkg
631 # Do map to rewritten package name
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500632 return data[key]
633
634 return pkg
635
636def get_package_additional_metadata (pkg_type, d):
637 base_key = "PACKAGE_ADD_METADATA"
638 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
639 if d.getVar(key, False) is None:
640 continue
641 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500642 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500643 d.setVarFlag(key, "separator", "\\n")
644 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
645 return "\n".join(metadata_fields).strip()
646
647def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500648 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500649
650 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500651 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Andrew Geissler82c905d2020-04-13 13:39:40 -0500652 for depend, depversions in deps.items():
653 new_depend = get_package_mapping(depend, pkg, d, depversions)
654 if depend != new_depend:
655 bb.note("package name mapping done: %s -> %s" % (depend, new_depend))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500656 new_depends[new_depend] = deps[depend]
657
658 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
659
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500660 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500661
662#
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500663# Used by do_packagedata (and possibly other routines post do_package)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664#
665
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500666package_get_auto_pr[vardepsexclude] = "BB_TASKDEPDATA"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667python package_get_auto_pr() {
668 import oe.prservice
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500669
670 def get_do_package_hash(pn):
671 if d.getVar("BB_RUNTASK") != "do_package":
672 taskdepdata = d.getVar("BB_TASKDEPDATA", False)
673 for dep in taskdepdata:
674 if taskdepdata[dep][1] == "do_package" and taskdepdata[dep][0] == pn:
675 return taskdepdata[dep][6]
676 return None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500677
678 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500679 pn = d.getVar('PN')
680 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500681 if not (host is None):
682 d.setVar("PRSERV_HOST", host)
683
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500684 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500685
686 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500687 if not d.getVar('PRSERV_HOST'):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500688 d.setVar("PRSERV_PV_AUTOINC", "0")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500689 return
690
691 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500692 pv = d.getVar("PV")
693 version = d.getVar("PRAUTOINX")
694 pkgarch = d.getVar("PACKAGE_ARCH")
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500695 checksum = get_do_package_hash(pn)
696
697 # If do_package isn't in the dependencies, we can't get the checksum...
698 if not checksum:
699 bb.warn('Task %s requested do_package unihash, but it was not available.' % d.getVar('BB_RUNTASK'))
700 #taskdepdata = d.getVar("BB_TASKDEPDATA", False)
701 #for dep in taskdepdata:
702 # bb.warn('%s:%s = %s' % (taskdepdata[dep][0], taskdepdata[dep][1], taskdepdata[dep][6]))
703 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500704
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500705 if d.getVar('PRSERV_LOCKDOWN'):
706 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500707 if auto_pr is None:
708 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
709 d.setVar('PRAUTO',str(auto_pr))
710 return
711
712 try:
Andrew Geisslerd159c7f2021-09-02 21:05:58 -0500713 conn = oe.prservice.prserv_make_conn(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500714 if conn is not None:
715 if "AUTOINC" in pkgv:
716 srcpv = bb.fetch2.get_srcrev(d)
717 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
718 value = conn.getPR(base_ver, pkgarch, srcpv)
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500719 d.setVar("PRSERV_PV_AUTOINC", str(value))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500720
721 auto_pr = conn.getPR(version, pkgarch, checksum)
Andrew Geisslerd159c7f2021-09-02 21:05:58 -0500722 conn.close()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500723 except Exception as e:
724 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
725 if auto_pr is None:
726 bb.fatal("Can NOT get PRAUTO from remote PR service")
727 d.setVar('PRAUTO',str(auto_pr))
728}
729
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500730#
731# Package functions suitable for inclusion in PACKAGEFUNCS
732#
733
734python package_convert_pr_autoinc() {
735 pkgv = d.getVar("PKGV")
736
737 # Adjust pkgv as necessary...
738 if 'AUTOINC' in pkgv:
739 d.setVar("PKGV", pkgv.replace("AUTOINC", "${PRSERV_PV_AUTOINC}"))
740
741 # Change PRSERV_PV_AUTOINC and EXTENDPRAUTO usage to special values
742 d.setVar('PRSERV_PV_AUTOINC', '@PRSERV_PV_AUTOINC@')
743 d.setVar('EXTENDPRAUTO', '@EXTENDPRAUTO@')
744}
745
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500746LOCALEBASEPN ??= "${PN}"
747
748python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500749 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750 bb.debug(1, "package requested not splitting locales")
751 return
752
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500753 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500754
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500755 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500756 if not datadir:
757 bb.note("datadir not defined")
758 return
759
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500760 dvar = d.getVar('PKGD')
761 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500762
763 if pn + '-locale' in packages:
764 packages.remove(pn + '-locale')
765
766 localedir = os.path.join(dvar + datadir, 'locale')
767
768 if not cpath.isdir(localedir):
769 bb.debug(1, "No locale files in this package")
770 return
771
772 locales = os.listdir(localedir)
773
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500774 summary = d.getVar('SUMMARY') or pn
775 description = d.getVar('DESCRIPTION') or ""
776 locale_section = d.getVar('LOCALE_SECTION')
777 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500778 for l in sorted(locales):
779 ln = legitimize_package_name(l)
780 pkg = pn + '-locale-' + ln
781 packages.append(pkg)
Patrick Williams213cb262021-08-07 19:21:33 -0500782 d.setVar('FILES:' + pkg, os.path.join(datadir, 'locale', l))
783 d.setVar('RRECOMMENDS:' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
784 d.setVar('RPROVIDES:' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
785 d.setVar('SUMMARY:' + pkg, '%s - %s translations' % (summary, l))
786 d.setVar('DESCRIPTION:' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500787 if locale_section:
Patrick Williams213cb262021-08-07 19:21:33 -0500788 d.setVar('SECTION:' + pkg, locale_section)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500789
790 d.setVar('PACKAGES', ' '.join(packages))
791
792 # Disabled by RP 18/06/07
793 # Wildcards aren't supported in debian
794 # They break with ipkg since glibc-locale* will mean that
795 # glibc-localedata-translit* won't install as a dependency
796 # for some other package which breaks meta-toolchain
797 # Probably breaks since virtual-locale- isn't provided anywhere
Patrick Williams213cb262021-08-07 19:21:33 -0500798 #rdep = (d.getVar('RDEPENDS:%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500799 #rdep.append('%s-locale*' % pn)
Patrick Williams213cb262021-08-07 19:21:33 -0500800 #d.setVar('RDEPENDS:%s' % pn, ' '.join(rdep))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500801}
802
803python perform_packagecopy () {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800804 import subprocess
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600805 import shutil
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800806
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500807 dest = d.getVar('D')
808 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500809
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600810 # Remove ${D}/sysroot-only if present
811 sysroot_only = os.path.join(dest, 'sysroot-only')
812 if cpath.exists(sysroot_only) and cpath.isdir(sysroot_only):
813 shutil.rmtree(sysroot_only)
814
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500815 # Start by package population by taking a copy of the installed
816 # files to operate on
817 # Preserve sparse files and hard links
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800818 cmd = 'tar -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar)
819 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500820
821 # replace RPATHs for the nativesdk binaries, to make them relocatable
822 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
823 rpath_replace (dvar, d)
824}
825perform_packagecopy[cleandirs] = "${PKGD}"
826perform_packagecopy[dirs] = "${PKGD}"
827
828# We generate a master list of directories to process, we start by
829# seeding this list with reasonable defaults, then load from
830# the fs-perms.txt files
831python fixup_perms () {
832 import pwd, grp
833
834 # init using a string with the same format as a line as documented in
835 # the fs-perms.txt file
836 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
837 # <path> link <link target>
838 #
839 # __str__ can be used to print out an entry in the input format
840 #
841 # if fs_perms_entry.path is None:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400842 # an error occurred
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500843 # if fs_perms_entry.link, you can retrieve:
844 # fs_perms_entry.path = path
845 # fs_perms_entry.link = target of link
846 # if not fs_perms_entry.link, you can retrieve:
847 # fs_perms_entry.path = path
848 # fs_perms_entry.mode = expected dir mode or None
849 # fs_perms_entry.uid = expected uid or -1
850 # fs_perms_entry.gid = expected gid or -1
851 # fs_perms_entry.walk = 'true' or something else
852 # fs_perms_entry.fmode = expected file mode or None
853 # fs_perms_entry.fuid = expected file uid or -1
854 # fs_perms_entry_fgid = expected file gid or -1
855 class fs_perms_entry():
856 def __init__(self, line):
857 lsplit = line.split()
858 if len(lsplit) == 3 and lsplit[1].lower() == "link":
859 self._setlink(lsplit[0], lsplit[2])
860 elif len(lsplit) == 8:
861 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
862 else:
863 msg = "Fixup Perms: invalid config line %s" % line
Andrew Geisslereff27472021-10-29 15:35:00 -0500864 oe.qa.handle_error("perm-config", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500865 self.path = None
866 self.link = None
867
868 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
869 self.path = os.path.normpath(path)
870 self.link = None
871 self.mode = self._procmode(mode)
872 self.uid = self._procuid(uid)
873 self.gid = self._procgid(gid)
874 self.walk = walk.lower()
875 self.fmode = self._procmode(fmode)
876 self.fuid = self._procuid(fuid)
877 self.fgid = self._procgid(fgid)
878
879 def _setlink(self, path, link):
880 self.path = os.path.normpath(path)
881 self.link = link
882
883 def _procmode(self, mode):
884 if not mode or (mode and mode == "-"):
885 return None
886 else:
887 return int(mode,8)
888
889 # Note uid/gid -1 has special significance in os.lchown
890 def _procuid(self, uid):
891 if uid is None or uid == "-":
892 return -1
893 elif uid.isdigit():
894 return int(uid)
895 else:
896 return pwd.getpwnam(uid).pw_uid
897
898 def _procgid(self, gid):
899 if gid is None or gid == "-":
900 return -1
901 elif gid.isdigit():
902 return int(gid)
903 else:
904 return grp.getgrnam(gid).gr_gid
905
906 # Use for debugging the entries
907 def __str__(self):
908 if self.link:
909 return "%s link %s" % (self.path, self.link)
910 else:
911 mode = "-"
912 if self.mode:
913 mode = "0%o" % self.mode
914 fmode = "-"
915 if self.fmode:
916 fmode = "0%o" % self.fmode
917 uid = self._mapugid(self.uid)
918 gid = self._mapugid(self.gid)
919 fuid = self._mapugid(self.fuid)
920 fgid = self._mapugid(self.fgid)
921 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
922
923 def _mapugid(self, id):
924 if id is None or id == -1:
925 return "-"
926 else:
927 return "%d" % id
928
929 # Fix the permission, owner and group of path
930 def fix_perms(path, mode, uid, gid, dir):
931 if mode and not os.path.islink(path):
932 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
933 os.chmod(path, mode)
934 # -1 is a special value that means don't change the uid/gid
935 # if they are BOTH -1, don't bother to lchown
936 if not (uid == -1 and gid == -1):
937 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
938 os.lchown(path, uid, gid)
939
940 # Return a list of configuration files based on either the default
941 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
942 # paths are resolved via BBPATH
943 def get_fs_perms_list(d):
944 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500945 bbpath = d.getVar('BBPATH')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500946 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500947 for conf_file in fs_perms_tables.split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800948 confpath = bb.utils.which(bbpath, conf_file)
949 if confpath:
950 str += " %s" % bb.utils.which(bbpath, conf_file)
951 else:
952 bb.warn("cannot find %s specified in FILESYSTEM_PERMS_TABLES" % conf_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500953 return str
954
955
956
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500957 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500958
959 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500960 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500961
962 # By default all of the standard directories specified in
963 # bitbake.conf will get 0755 root:root.
964 target_path_vars = [ 'base_prefix',
965 'prefix',
966 'exec_prefix',
967 'base_bindir',
968 'base_sbindir',
969 'base_libdir',
970 'datadir',
971 'sysconfdir',
972 'servicedir',
973 'sharedstatedir',
974 'localstatedir',
975 'infodir',
976 'mandir',
977 'docdir',
978 'bindir',
979 'sbindir',
980 'libexecdir',
981 'libdir',
982 'includedir',
983 'oldincludedir' ]
984
985 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500986 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500987 if dir == "":
988 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500989 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500990
991 # Now we actually load from the configuration files
992 for conf in get_fs_perms_list(d).split():
Brad Bishop64c979e2019-11-04 13:55:29 -0500993 if not os.path.exists(conf):
994 continue
995 with open(conf) as f:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500996 for line in f:
997 if line.startswith('#'):
998 continue
999 lsplit = line.split()
1000 if len(lsplit) == 0:
1001 continue
1002 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
1003 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
Andrew Geisslereff27472021-10-29 15:35:00 -05001004 oe.qa.handle_error("perm-line", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001005 continue
1006 entry = fs_perms_entry(d.expand(line))
1007 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001008 if entry.link:
1009 fs_link_table[entry.path] = entry
1010 if entry.path in fs_perms_table:
1011 fs_perms_table.pop(entry.path)
1012 else:
1013 fs_perms_table[entry.path] = entry
1014 if entry.path in fs_link_table:
1015 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001016
1017 # Debug -- list out in-memory table
1018 #for dir in fs_perms_table:
1019 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001020 #for link in fs_link_table:
1021 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001022
1023 # We process links first, so we can go back and fixup directory ownership
1024 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001025 # Process in sorted order so /run gets created before /run/lock, etc.
1026 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
1027 link = entry.link
1028 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001029 origin = dvar + dir
1030 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
1031 continue
1032
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001033 if link[0] == "/":
1034 target = dvar + link
1035 ptarget = link
1036 else:
1037 target = os.path.join(os.path.dirname(origin), link)
1038 ptarget = os.path.join(os.path.dirname(dir), link)
1039 if os.path.exists(target):
1040 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
Andrew Geisslereff27472021-10-29 15:35:00 -05001041 oe.qa.handle_error("perm-link", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001042 continue
1043
1044 # Create path to move directory to, move it, and then setup the symlink
1045 bb.utils.mkdirhier(os.path.dirname(target))
1046 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
Andrew Geisslerc926e172021-05-07 16:11:35 -05001047 bb.utils.rename(origin, target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001048 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
1049 os.symlink(link, origin)
1050
1051 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001052 origin = dvar + dir
1053 if not (cpath.exists(origin) and cpath.isdir(origin)):
1054 continue
1055
1056 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
1057
1058 if fs_perms_table[dir].walk == 'true':
1059 for root, dirs, files in os.walk(origin):
1060 for dr in dirs:
1061 each_dir = os.path.join(root, dr)
1062 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
1063 for f in files:
1064 each_file = os.path.join(root, f)
1065 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
1066}
1067
1068python split_and_strip_files () {
1069 import stat, errno
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001070 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001071
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001072 dvar = d.getVar('PKGD')
1073 pn = d.getVar('PN')
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001074 hostos = d.getVar('HOST_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001075
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001076 oldcwd = os.getcwd()
1077 os.chdir(dvar)
1078
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001079 # We default to '.debug' style
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001080 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001081 # Single debug-file-directory style debug info
1082 debugappend = ".debug"
Andrew Geissler82c905d2020-04-13 13:39:40 -05001083 debugstaticappend = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001084 debugdir = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001085 debugstaticdir = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001086 debuglibdir = "/usr/lib/debug"
Andrew Geissler82c905d2020-04-13 13:39:40 -05001087 debugstaticlibdir = "/usr/lib/debug-static"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001088 debugsrcdir = "/usr/src/debug"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001089 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001090 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
1091 debugappend = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001092 debugstaticappend = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001093 debugdir = "/.debug"
Andrew Geissler82c905d2020-04-13 13:39:40 -05001094 debugstaticdir = "/.debug-static"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001095 debuglibdir = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001096 debugstaticlibdir = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001097 debugsrcdir = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001098 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
1099 debugappend = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001100 debugstaticappend = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001101 debugdir = "/.debug"
Andrew Geissler82c905d2020-04-13 13:39:40 -05001102 debugstaticdir = "/.debug-static"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001103 debuglibdir = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001104 debugstaticlibdir = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001105 debugsrcdir = "/usr/src/debug"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001106 else:
1107 # Original OE-core, a.k.a. ".debug", style debug info
1108 debugappend = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001109 debugstaticappend = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001110 debugdir = "/.debug"
Andrew Geissler82c905d2020-04-13 13:39:40 -05001111 debugstaticdir = "/.debug-static"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001112 debuglibdir = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -05001113 debugstaticlibdir = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001114 debugsrcdir = "/usr/src/debug"
1115
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001116 #
1117 # First lets figure out all of the files we may have to process ... do this only once!
1118 #
1119 elffiles = {}
1120 symlinks = {}
Brad Bishop316dfdd2018-06-25 12:45:53 -04001121 staticlibs = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001122 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001123 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
1124 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
Brad Bishop316dfdd2018-06-25 12:45:53 -04001125 skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001126 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
1127 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001128 checkelf = {}
1129 checkelflinks = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001130 for root, dirs, files in cpath.walk(dvar):
1131 for f in files:
1132 file = os.path.join(root, f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001133
1134 # Skip debug files
1135 if debugappend and file.endswith(debugappend):
1136 continue
1137 if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
1138 continue
1139
Brad Bishop316dfdd2018-06-25 12:45:53 -04001140 if file in skipfiles:
1141 continue
1142
Andrew Geissler82c905d2020-04-13 13:39:40 -05001143 if oe.package.is_static_lib(file):
1144 staticlibs.append(file)
1145 continue
1146
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001147 try:
1148 ltarget = cpath.realpath(file, dvar, False)
1149 s = cpath.lstat(ltarget)
1150 except OSError as e:
1151 (err, strerror) = e.args
1152 if err != errno.ENOENT:
1153 raise
1154 # Skip broken symlinks
1155 continue
1156 if not s:
1157 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -04001158 # Check its an executable
Andrew Geissler595f6302022-01-24 19:11:47 +00001159 if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) \
1160 or (s[stat.ST_MODE] & stat.S_IXOTH) \
1161 or ((file.startswith(libdir) or file.startswith(baselibdir)) \
1162 and (".so" in f or ".node" in f)) \
1163 or (f.startswith('vmlinux') or ".ko" in f):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001164
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001165 if cpath.islink(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001166 checkelflinks[file] = ltarget
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001167 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001168 # Use a reference of device ID and inode number to identify files
1169 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
1170 checkelf[file] = (file, file_reference)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001171
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001172 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d)
1173 results_map = {}
1174 for (ltarget, elf_file) in results:
1175 results_map[ltarget] = elf_file
1176 for file in checkelflinks:
1177 ltarget = checkelflinks[file]
1178 # If it's a symlink, and points to an ELF file, we capture the readlink target
1179 if results_map[ltarget]:
1180 target = os.readlink(file)
1181 #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget]))
1182 symlinks[file] = target
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001183
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001184 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d)
Brad Bishop15ae2502019-06-18 21:44:24 -04001185
1186 # Sort results by file path. This ensures that the files are always
1187 # processed in the same order, which is important to make sure builds
1188 # are reproducible when dealing with hardlinks
1189 results.sort(key=lambda x: x[0])
1190
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001191 for (file, elf_file) in results:
1192 # It's a file (or hardlink), not a link
1193 # ...but is it ELF, and is it already stripped?
1194 if elf_file & 1:
1195 if elf_file & 2:
Patrick Williams213cb262021-08-07 19:21:33 -05001196 if 'already-stripped' in (d.getVar('INSANE_SKIP:' + pn) or "").split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001197 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1198 else:
1199 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
Andrew Geisslereff27472021-10-29 15:35:00 -05001200 oe.qa.handle_error("already-stripped", msg, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001201 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001202
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001203 # At this point we have an unstripped elf file. We need to:
1204 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1205 # b) Only strip any hardlinked file once (no races)
1206 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1207
1208 # Use a reference of device ID and inode number to identify files
1209 file_reference = checkelf[file][1]
1210 if file_reference in inodes:
1211 os.unlink(file)
1212 os.link(inodes[file_reference][0], file)
1213 inodes[file_reference].append(file)
1214 else:
1215 inodes[file_reference] = [file]
1216 # break hardlink
1217 bb.utils.break_hardlinks(file)
1218 elffiles[file] = elf_file
1219 # Modified the file so clear the cache
1220 cpath.updatecache(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001221
Andrew Geissler5199d832021-09-24 16:47:35 -05001222 def strip_pkgd_prefix(f):
1223 nonlocal dvar
1224
1225 if f.startswith(dvar):
1226 return f[len(dvar):]
1227
1228 return f
1229
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001230 #
1231 # First lets process debug splitting
1232 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001233 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop19323692019-04-05 15:28:33 -04001234 results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001235
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001236 if debugsrcdir and not hostos.startswith("mingw"):
Andrew Geissler82c905d2020-04-13 13:39:40 -05001237 if (d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'):
1238 results = oe.utils.multiprocess_launch(splitstaticdebuginfo, staticlibs, d, extraargs=(dvar, debugstaticdir, debugstaticlibdir, debugstaticappend, debugsrcdir, d))
1239 else:
1240 for file in staticlibs:
1241 results.append( (file,source_info(file, d)) )
Brad Bishop19323692019-04-05 15:28:33 -04001242
Andrew Geissler5199d832021-09-24 16:47:35 -05001243 d.setVar("PKGDEBUGSOURCES", {strip_pkgd_prefix(f): sorted(s) for f, s in results})
1244
Brad Bishop19323692019-04-05 15:28:33 -04001245 sources = set()
1246 for r in results:
1247 sources.update(r[1])
Brad Bishop316dfdd2018-06-25 12:45:53 -04001248
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001249 # Hardlink our debug symbols to the other hardlink copies
1250 for ref in inodes:
1251 if len(inodes[ref]) == 1:
1252 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001253
1254 target = inodes[ref][0][len(dvar):]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001255 for file in inodes[ref][1:]:
1256 src = file[len(dvar):]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001257 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(target) + debugappend
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001258 fpath = dvar + dest
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001259 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1260 bb.utils.mkdirhier(os.path.dirname(fpath))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001261 # Only one hardlink of separated debug info file in each directory
1262 if not os.access(fpath, os.R_OK):
1263 #bb.note("Link %s -> %s" % (fpath, ftarget))
1264 os.link(ftarget, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001265
1266 # Create symlinks for all cases we were able to split symbols
1267 for file in symlinks:
1268 src = file[len(dvar):]
1269 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1270 fpath = dvar + dest
1271 # Skip it if the target doesn't exist
1272 try:
1273 s = os.stat(fpath)
1274 except OSError as e:
1275 (err, strerror) = e.args
1276 if err != errno.ENOENT:
1277 raise
1278 continue
1279
1280 ltarget = symlinks[file]
1281 lpath = os.path.dirname(ltarget)
1282 lbase = os.path.basename(ltarget)
1283 ftarget = ""
1284 if lpath and lpath != ".":
1285 ftarget += lpath + debugdir + "/"
1286 ftarget += lbase + debugappend
1287 if lpath.startswith(".."):
1288 ftarget = os.path.join("..", ftarget)
1289 bb.utils.mkdirhier(os.path.dirname(fpath))
1290 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1291 os.symlink(ftarget, fpath)
1292
1293 # Process the debugsrcdir if requested...
1294 # This copies and places the referenced sources for later debugging...
Brad Bishop19323692019-04-05 15:28:33 -04001295 copydebugsources(debugsrcdir, sources, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001296 #
1297 # End of debug splitting
1298 #
1299
1300 #
1301 # Now lets go back over things and strip them
1302 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001303 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1304 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001305 sfiles = []
1306 for file in elffiles:
1307 elf_file = int(elffiles[file])
1308 #bb.note("Strip %s" % file)
1309 sfiles.append((file, elf_file, strip))
Andrew Geissler82c905d2020-04-13 13:39:40 -05001310 if (d.getVar('PACKAGE_STRIP_STATIC') == '1' or d.getVar('PACKAGE_DEBUG_STATIC_SPLIT') == '1'):
1311 for f in staticlibs:
1312 sfiles.append((f, 16, strip))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001313
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001314 oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001315
Andrew Geissler82c905d2020-04-13 13:39:40 -05001316 # Build "minidebuginfo" and reinject it back into the stripped binaries
1317 if d.getVar('PACKAGE_MINIDEBUGINFO') == '1':
1318 oe.utils.multiprocess_launch(inject_minidebuginfo, list(elffiles), d,
1319 extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d))
1320
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001321 #
1322 # End of strip
1323 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001324 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001325}
1326
1327python populate_packages () {
1328 import glob, re
1329
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001330 workdir = d.getVar('WORKDIR')
1331 outdir = d.getVar('DEPLOY_DIR')
1332 dvar = d.getVar('PKGD')
Brad Bishop19323692019-04-05 15:28:33 -04001333 packages = d.getVar('PACKAGES').split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001334 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001335
1336 bb.utils.mkdirhier(outdir)
1337 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001338
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001339 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001340
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001341 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1342
Brad Bishop19323692019-04-05 15:28:33 -04001343 # If debug-with-srcpkg mode is enabled then add the source package if it
1344 # doesn't exist and add the source file contents to the source package.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001345 if split_source_package:
1346 src_package_name = ('%s-src' % d.getVar('PN'))
Brad Bishop19323692019-04-05 15:28:33 -04001347 if not src_package_name in packages:
1348 packages.append(src_package_name)
Patrick Williams213cb262021-08-07 19:21:33 -05001349 d.setVar('FILES:%s' % src_package_name, '/usr/src/debug')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001350
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001351 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001352 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001353 package_dict = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001354
Brad Bishop19323692019-04-05 15:28:33 -04001355 for i, pkg in enumerate(packages):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001356 if pkg in package_dict:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001357 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
Andrew Geisslereff27472021-10-29 15:35:00 -05001358 oe.qa.handle_error("packages-list", msg, d)
Brad Bishop19323692019-04-05 15:28:33 -04001359 # Ensure the source package gets the chance to pick up the source files
1360 # before the debug package by ordering it first in PACKAGES. Whether it
1361 # actually picks up any source files is controlled by
1362 # PACKAGE_DEBUG_SPLIT_STYLE.
1363 elif pkg.endswith("-src"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001364 package_dict[pkg] = (10, i)
1365 elif autodebug and pkg.endswith("-dbg"):
1366 package_dict[pkg] = (30, i)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001367 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001368 package_dict[pkg] = (50, i)
Brad Bishop19323692019-04-05 15:28:33 -04001369 packages = sorted(package_dict.keys(), key=package_dict.get)
1370 d.setVar('PACKAGES', ' '.join(packages))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001371 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001372
1373 seen = []
1374
1375 # os.mkdir masks the permissions with umask so we have to unset it first
1376 oldumask = os.umask(0)
1377
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001378 debug = []
1379 for root, dirs, files in cpath.walk(dvar):
1380 dir = root[len(dvar):]
1381 if not dir:
1382 dir = os.sep
1383 for f in (files + dirs):
1384 path = "." + os.path.join(dir, f)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001385 if "/.debug/" in path or "/.debug-static/" in path or path.endswith("/.debug"):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001386 debug.append(path)
1387
Brad Bishop19323692019-04-05 15:28:33 -04001388 for pkg in packages:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001389 root = os.path.join(pkgdest, pkg)
1390 bb.utils.mkdirhier(root)
1391
Patrick Williams213cb262021-08-07 19:21:33 -05001392 filesvar = d.getVar('FILES:%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001393 if "//" in filesvar:
1394 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 -05001395 oe.qa.handle_error("files-invalid", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001396 filesvar.replace("//", "/")
1397
1398 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001399 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001400
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001401 if autodebug and pkg.endswith("-dbg"):
1402 files.extend(debug)
1403
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001404 for file in files:
1405 if (not cpath.islink(file)) and (not cpath.exists(file)):
1406 continue
1407 if file in seen:
1408 continue
1409 seen.append(file)
1410
1411 def mkdir(src, dest, p):
1412 src = os.path.join(src, p)
1413 dest = os.path.join(dest, p)
1414 fstat = cpath.stat(src)
Brad Bishop96ff1982019-08-19 13:50:42 -04001415 os.mkdir(dest)
1416 os.chmod(dest, fstat.st_mode)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001417 os.chown(dest, fstat.st_uid, fstat.st_gid)
1418 if p not in seen:
1419 seen.append(p)
1420 cpath.updatecache(dest)
1421
1422 def mkdir_recurse(src, dest, paths):
1423 if cpath.exists(dest + '/' + paths):
1424 return
1425 while paths.startswith("./"):
1426 paths = paths[2:]
1427 p = "."
1428 for c in paths.split("/"):
1429 p = os.path.join(p, c)
1430 if not cpath.exists(os.path.join(dest, p)):
1431 mkdir(src, dest, p)
1432
1433 if cpath.isdir(file) and not cpath.islink(file):
1434 mkdir_recurse(dvar, root, file)
1435 continue
1436
1437 mkdir_recurse(dvar, root, os.path.dirname(file))
1438 fpath = os.path.join(root,file)
1439 if not cpath.islink(file):
1440 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001441 continue
1442 ret = bb.utils.copyfile(file, fpath)
1443 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001444 bb.fatal("File population failed")
1445
1446 # Check if symlink paths exist
1447 for file in symlink_paths:
1448 if not os.path.exists(os.path.join(root,file)):
1449 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1450 "parent directory structure does not exist. One of "
1451 "its parent directories is a symlink whose target "
1452 "directory is not included in the package." %
1453 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001454
1455 os.umask(oldumask)
1456 os.chdir(workdir)
1457
1458 # Handle LICENSE_EXCLUSION
1459 package_list = []
Brad Bishop19323692019-04-05 15:28:33 -04001460 for pkg in packages:
Andrew Geissler82c905d2020-04-13 13:39:40 -05001461 licenses = d.getVar('LICENSE_EXCLUSION-' + pkg)
1462 if licenses:
1463 msg = "Excluding %s from packaging as it has incompatible license(s): %s" % (pkg, licenses)
Andrew Geisslereff27472021-10-29 15:35:00 -05001464 oe.qa.handle_error("incompatible-license", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001465 else:
1466 package_list.append(pkg)
1467 d.setVar('PACKAGES', ' '.join(package_list))
1468
1469 unshipped = []
1470 for root, dirs, files in cpath.walk(dvar):
1471 dir = root[len(dvar):]
1472 if not dir:
1473 dir = os.sep
1474 for f in (files + dirs):
1475 path = os.path.join(dir, f)
1476 if ('.' + path) not in seen:
1477 unshipped.append(path)
1478
1479 if unshipped != []:
1480 msg = pn + ": Files/directories were installed but not shipped in any package:"
Patrick Williams213cb262021-08-07 19:21:33 -05001481 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP:' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001482 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1483 else:
1484 for f in unshipped:
1485 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001486 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"
1487 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Andrew Geisslereff27472021-10-29 15:35:00 -05001488 oe.qa.handle_error("installed-vs-shipped", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001489}
1490populate_packages[dirs] = "${D}"
1491
1492python package_fixsymlinks () {
1493 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001494 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001495 packages = d.getVar("PACKAGES", False).split()
1496
1497 dangling_links = {}
1498 pkg_files = {}
1499 for pkg in packages:
1500 dangling_links[pkg] = []
1501 pkg_files[pkg] = []
1502 inst_root = os.path.join(pkgdest, pkg)
1503 for path in pkgfiles[pkg]:
1504 rpath = path[len(inst_root):]
1505 pkg_files[pkg].append(rpath)
1506 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1507 if not cpath.lexists(rtarget):
1508 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1509
1510 newrdepends = {}
1511 for pkg in dangling_links:
1512 for l in dangling_links[pkg]:
1513 found = False
1514 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1515 for p in packages:
1516 if l in pkg_files[p]:
1517 found = True
1518 bb.debug(1, "target found in %s" % p)
1519 if p == pkg:
1520 break
1521 if pkg not in newrdepends:
1522 newrdepends[pkg] = []
1523 newrdepends[pkg].append(p)
1524 break
1525 if found == False:
1526 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1527
1528 for pkg in newrdepends:
Patrick Williams213cb262021-08-07 19:21:33 -05001529 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001530 for p in newrdepends[pkg]:
1531 if p not in rdepends:
1532 rdepends[p] = []
Patrick Williams213cb262021-08-07 19:21:33 -05001533 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001534}
1535
1536
1537python package_package_name_hook() {
1538 """
1539 A package_name_hook function can be used to rewrite the package names by
1540 changing PKG. For an example, see debian.bbclass.
1541 """
1542 pass
1543}
1544
1545EXPORT_FUNCTIONS package_name_hook
1546
1547
1548PKGDESTWORK = "${WORKDIR}/pkgdata"
1549
Andrew Geissler1e34c2d2020-05-29 16:02:59 -05001550PKGDATA_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 -04001551
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001552python emit_pkgdata() {
1553 from glob import glob
1554 import json
Andrew Geissler5199d832021-09-24 16:47:35 -05001555 import bb.compress.zstd
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001556
Brad Bishop316dfdd2018-06-25 12:45:53 -04001557 def process_postinst_on_target(pkg, mlprefix):
Patrick Williams213cb262021-08-07 19:21:33 -05001558 pkgval = d.getVar('PKG:%s' % pkg)
Brad Bishop96ff1982019-08-19 13:50:42 -04001559 if pkgval is None:
1560 pkgval = pkg
1561
Brad Bishop316dfdd2018-06-25 12:45:53 -04001562 defer_fragment = """
1563if [ -n "$D" ]; then
1564 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1565 exit 0
1566fi
Brad Bishop96ff1982019-08-19 13:50:42 -04001567""" % (pkgval, mlprefix)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001568
Patrick Williams213cb262021-08-07 19:21:33 -05001569 postinst = d.getVar('pkg_postinst:%s' % pkg)
1570 postinst_ontarget = d.getVar('pkg_postinst_ontarget:%s' % pkg)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001571
1572 if postinst_ontarget:
1573 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1574 if not postinst:
1575 postinst = '#!/bin/sh\n'
1576 postinst += defer_fragment
1577 postinst += postinst_ontarget
Patrick Williams213cb262021-08-07 19:21:33 -05001578 d.setVar('pkg_postinst:%s' % pkg, postinst)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001579
1580 def add_set_e_to_scriptlets(pkg):
1581 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
Patrick Williams213cb262021-08-07 19:21:33 -05001582 scriptlet = d.getVar('%s:%s' % (scriptlet_name, pkg))
Brad Bishop316dfdd2018-06-25 12:45:53 -04001583 if scriptlet:
1584 scriptlet_split = scriptlet.split('\n')
1585 if scriptlet_split[0].startswith("#!"):
1586 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1587 else:
1588 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
Patrick Williams213cb262021-08-07 19:21:33 -05001589 d.setVar('%s:%s' % (scriptlet_name, pkg), scriptlet)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001590
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001591 def write_if_exists(f, pkg, var):
1592 def encode(str):
1593 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001594 c = codecs.getencoder("unicode_escape")
1595 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001596
Patrick Williams213cb262021-08-07 19:21:33 -05001597 val = d.getVar('%s:%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001598 if val:
Patrick Williams213cb262021-08-07 19:21:33 -05001599 f.write('%s:%s: %s\n' % (var, pkg, encode(val)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001600 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001601 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001602 if val:
1603 f.write('%s: %s\n' % (var, encode(val)))
1604 return val
1605
1606 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1607 for variant in variants:
1608 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1609 fd.write("PACKAGES: %s\n" % ' '.join(
1610 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1611
1612 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1613 for variant in variants:
1614 for pkg in packages.split():
1615 ml_pkg = "%s-%s" % (variant, pkg)
1616 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1617 with open(subdata_file, 'w') as fd:
Patrick Williams213cb262021-08-07 19:21:33 -05001618 fd.write("PKG:%s: %s" % (ml_pkg, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001619
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001620 packages = d.getVar('PACKAGES')
1621 pkgdest = d.getVar('PKGDEST')
1622 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001623
Brad Bishop64c979e2019-11-04 13:55:29 -05001624 data_file = pkgdatadir + d.expand("/${PN}")
1625 with open(data_file, 'w') as fd:
1626 fd.write("PACKAGES: %s\n" % packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001627
Andrew Geissler5199d832021-09-24 16:47:35 -05001628 pkgdebugsource = d.getVar("PKGDEBUGSOURCES") or []
1629
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001630 pn = d.getVar('PN')
1631 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1632 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001633
1634 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1635 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1636
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001637 if bb.data.inherits_class('allarch', d) and not variants \
1638 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001639 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1640
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001641 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001642
1643 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05001644 pkgval = d.getVar('PKG:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001645 if pkgval is None:
1646 pkgval = pkg
Patrick Williams213cb262021-08-07 19:21:33 -05001647 d.setVar('PKG:%s' % pkg, pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001648
Andrew Geissler5199d832021-09-24 16:47:35 -05001649 extended_data = {
1650 "files_info": {}
1651 }
1652
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001653 pkgdestpkg = os.path.join(pkgdest, pkg)
1654 files = {}
Andrew Geissler5199d832021-09-24 16:47:35 -05001655 files_extra = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001656 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001657 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001658 for f in pkgfiles[pkg]:
Andrew Geissler5199d832021-09-24 16:47:35 -05001659 fpath = os.sep + os.path.relpath(f, pkgdestpkg)
1660
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001661 fstat = os.lstat(f)
Andrew Geissler5199d832021-09-24 16:47:35 -05001662 files[fpath] = fstat.st_size
1663
1664 extended_data["files_info"].setdefault(fpath, {})
1665 extended_data["files_info"][fpath]['size'] = fstat.st_size
1666
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001667 if fstat.st_ino not in seen:
1668 seen.add(fstat.st_ino)
1669 total_size += fstat.st_size
Andrew Geissler5199d832021-09-24 16:47:35 -05001670
1671 if fpath in pkgdebugsource:
1672 extended_data["files_info"][fpath]['debugsrc'] = pkgdebugsource[fpath]
1673 del pkgdebugsource[fpath]
1674
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001675 d.setVar('FILES_INFO:' + pkg , json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001676
Brad Bishop316dfdd2018-06-25 12:45:53 -04001677 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1678 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001679
Brad Bishop15ae2502019-06-18 21:44:24 -04001680 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1681 with open(subdata_file, 'w') as sf:
1682 for var in (d.getVar('PKGDATA_VARS') or "").split():
1683 val = write_if_exists(sf, pkg, var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001684
Brad Bishop15ae2502019-06-18 21:44:24 -04001685 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
Andrew Geissler5199d832021-09-24 16:47:35 -05001686 for dfile in sorted((d.getVar('FILERPROVIDESFLIST:' + pkg) or "").split()):
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001687 write_if_exists(sf, pkg, 'FILERPROVIDES:' + dfile)
Brad Bishop15ae2502019-06-18 21:44:24 -04001688
1689 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Andrew Geissler5199d832021-09-24 16:47:35 -05001690 for dfile in sorted((d.getVar('FILERDEPENDSFLIST:' + pkg) or "").split()):
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001691 write_if_exists(sf, pkg, 'FILERDEPENDS:' + dfile)
Brad Bishop15ae2502019-06-18 21:44:24 -04001692
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001693 sf.write('%s:%s: %d\n' % ('PKGSIZE', pkg, total_size))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001694
Andrew Geissler5199d832021-09-24 16:47:35 -05001695 subdata_extended_file = pkgdatadir + "/extended/%s.json.zstd" % pkg
1696 num_threads = int(d.getVar("BB_NUMBER_THREADS"))
1697 with bb.compress.zstd.open(subdata_extended_file, "wt", encoding="utf-8", num_threads=num_threads) as f:
1698 json.dump(extended_data, f, sort_keys=True, separators=(",", ":"))
1699
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001700 # Symlinks needed for rprovides lookup
Patrick Williams213cb262021-08-07 19:21:33 -05001701 rprov = d.getVar('RPROVIDES:%s' % pkg) or d.getVar('RPROVIDES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001702 if rprov:
Andrew Geisslerc9f78652020-09-18 14:11:35 -05001703 for p in bb.utils.explode_deps(rprov):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001704 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1705 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1706 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1707
Patrick Williams213cb262021-08-07 19:21:33 -05001708 allow_empty = d.getVar('ALLOW_EMPTY:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001709 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001710 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001711 root = "%s/%s" % (pkgdest, pkg)
1712 os.chdir(root)
1713 g = glob('*')
1714 if g or allow_empty == "1":
1715 # Symlinks needed for reverse lookups (from the final package name)
1716 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1717 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1718
1719 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1720 open(packagedfile, 'w').close()
1721
1722 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1723 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1724
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001725 if bb.data.inherits_class('allarch', d) and not variants \
1726 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001727 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1728
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001729}
Andrew Geissler5199d832021-09-24 16:47:35 -05001730emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides ${PKGDESTWORK}/extended"
1731emit_pkgdata[vardepsexclude] = "BB_NUMBER_THREADS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001732
1733ldconfig_postinst_fragment() {
1734if [ x"$D" = "x" ]; then
1735 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1736fi
1737}
1738
Andrew Geissler90fd73c2021-03-05 15:25:55 -06001739RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps --define '__font_provides %{nil}'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001740
1741# Collect perfile run-time dependency metadata
1742# Output:
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001743# FILERPROVIDESFLIST:pkg - list of all files w/ deps
1744# FILERPROVIDES:filepath:pkg - per file dep
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001745#
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001746# FILERDEPENDSFLIST:pkg - list of all files w/ deps
1747# FILERDEPENDS:filepath:pkg - per file dep
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001748
1749python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001750 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001751 return
1752
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001753 pkgdest = d.getVar('PKGDEST')
1754 packages = d.getVar('PACKAGES')
1755 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001756
1757 def chunks(files, n):
1758 return [files[i:i+n] for i in range(0, len(files), n)]
1759
1760 pkglist = []
1761 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05001762 if d.getVar('SKIP_FILEDEPS:' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001763 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001764 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 -05001765 continue
1766 for files in chunks(pkgfiles[pkg], 100):
1767 pkglist.append((pkg, files, rpmdeps, pkgdest))
1768
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001769 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001770
1771 provides_files = {}
1772 requires_files = {}
1773
1774 for result in processed:
1775 (pkg, provides, requires) = result
1776
1777 if pkg not in provides_files:
1778 provides_files[pkg] = []
1779 if pkg not in requires_files:
1780 requires_files[pkg] = []
1781
Brad Bishop19323692019-04-05 15:28:33 -04001782 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001783 provides_files[pkg].append(file)
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001784 key = "FILERPROVIDES:" + file + ":" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001785 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001786
Brad Bishop19323692019-04-05 15:28:33 -04001787 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001788 requires_files[pkg].append(file)
Patrick Williams0ca19cc2021-08-16 14:03:13 -05001789 key = "FILERDEPENDS:" + file + ":" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001790 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001791
1792 for pkg in requires_files:
Andrew Geissler5199d832021-09-24 16:47:35 -05001793 d.setVar("FILERDEPENDSFLIST:" + pkg, " ".join(sorted(requires_files[pkg])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001794 for pkg in provides_files:
Andrew Geissler5199d832021-09-24 16:47:35 -05001795 d.setVar("FILERPROVIDESFLIST:" + pkg, " ".join(sorted(provides_files[pkg])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001796}
1797
Brad Bishop96ff1982019-08-19 13:50:42 -04001798SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001799SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1800
1801python package_do_shlibs() {
Brad Bishop00e122a2019-10-05 11:10:57 -04001802 import itertools
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001803 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001804 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001805
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001806 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001807 if exclude_shlibs:
1808 bb.note("not generating shlibs")
1809 return
1810
Brad Bishop19323692019-04-05 15:28:33 -04001811 lib_re = re.compile(r"^.*\.so")
1812 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001813
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001814 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001815
1816 shlib_pkgs = []
1817 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1818 if exclusion_list:
1819 for pkg in packages.split():
1820 if pkg not in exclusion_list.split():
1821 shlib_pkgs.append(pkg)
1822 else:
1823 bb.note("not generating shlibs for %s" % pkg)
1824 else:
1825 shlib_pkgs = packages.split()
1826
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001827 hostos = d.getVar('HOST_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001828
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001829 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001830
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001831 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001832 if not ver:
1833 msg = "PKGV not defined"
Andrew Geisslereff27472021-10-29 15:35:00 -05001834 oe.qa.handle_error("pkgv-undefined", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001835 return
1836
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001837 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001838
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001839 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001840
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001841 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001842 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001843 needed = set()
1844 sonames = set()
1845 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001846 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001847 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001848 fd = os.popen(cmd)
1849 lines = fd.readlines()
1850 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001851 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001852 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001853 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001854 if m:
1855 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001856 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001857 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001858 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001859 if m:
1860 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001861 if dep not in needed:
1862 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001863 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001864 if m:
1865 this_soname = m.group(1)
1866 prov = (this_soname, ldir, pkgver)
1867 if not prov in sonames:
1868 # if library is private (only used by package) then do not build shlib for it
Brad Bishop79641f22019-09-10 07:20:22 -04001869 import fnmatch
1870 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 -08001871 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001872 if libdir_re.match(os.path.dirname(file)):
1873 needs_ldconfig = True
Andrew Geissler595f6302022-01-24 19:11:47 +00001874 if needs_ldconfig and snap_symlinks and (os.path.basename(file) != this_soname):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001875 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001876 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001877
1878 def darwin_so(file, needed, sonames, renames, pkgver):
1879 if not os.path.exists(file):
1880 return
1881 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1882
1883 def get_combinations(base):
1884 #
1885 # Given a base library name, find all combinations of this split by "." and "-"
1886 #
1887 combos = []
1888 options = base.split(".")
1889 for i in range(1, len(options) + 1):
1890 combos.append(".".join(options[0:i]))
1891 options = base.split("-")
1892 for i in range(1, len(options) + 1):
1893 combos.append("-".join(options[0:i]))
1894 return combos
1895
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001896 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 -05001897 # Drop suffix
1898 name = os.path.basename(file).rsplit(".",1)[0]
1899 # Find all combinations
1900 combos = get_combinations(name)
1901 for combo in combos:
1902 if not combo in sonames:
1903 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001904 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001905 if file.endswith('.dylib') or file.endswith('.so'):
1906 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001907 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001908 out, err = p.communicate()
1909 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001910 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001911 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001912 l = l.strip()
1913 if l.startswith('path '):
1914 rpath.append(l.split()[1])
1915
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001916 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001917 out, err = p.communicate()
1918 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001919 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001920 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001921 l = l.strip()
1922 if not l or l.endswith(":"):
1923 continue
1924 if "is not an object file" in l:
1925 continue
1926 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1927 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001928 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001929
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001930 def mingw_dll(file, needed, sonames, renames, pkgver):
1931 if not os.path.exists(file):
1932 return
1933
1934 if file.endswith(".dll"):
1935 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001936 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001937
1938 if (file.endswith(".dll") or file.endswith(".exe")):
1939 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001940 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001941 out, err = p.communicate()
1942 # process the output, grabbing all .dll names
1943 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001944 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001945 dllname = m.group(1)
1946 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001947 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001948
1949 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001950 snap_symlinks = True
1951 else:
1952 snap_symlinks = False
1953
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001954 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001955
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001956 shlib_provider = oe.package.read_shlib_providers(d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001957
1958 for pkg in shlib_pkgs:
Patrick Williams213cb262021-08-07 19:21:33 -05001959 private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001960 private_libs = private_libs.split()
1961 needs_ldconfig = False
1962 bb.debug(2, "calculating shlib provides for %s" % pkg)
1963
Patrick Williams213cb262021-08-07 19:21:33 -05001964 pkgver = d.getVar('PKGV:' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001965 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001966 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001967 if not pkgver:
1968 pkgver = ver
1969
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001970 needed[pkg] = set()
1971 sonames = set()
1972 renames = []
1973 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001974 for file in pkgfiles[pkg]:
1975 soname = None
1976 if cpath.islink(file):
1977 continue
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001978 if hostos == "darwin" or hostos == "darwin8":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001979 darwin_so(file, needed, sonames, renames, pkgver)
Andrew Geisslerb7d28612020-07-24 16:15:54 -05001980 elif hostos.startswith("mingw"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001981 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001982 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001983 linuxlist.append(file)
1984
1985 if linuxlist:
1986 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1987 for r in results:
1988 ldconfig = r[0]
1989 needed[pkg] |= r[1]
1990 sonames |= r[2]
1991 renames.extend(r[3])
1992 needs_ldconfig = needs_ldconfig or ldconfig
1993
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001994 for (old, new) in renames:
1995 bb.note("Renaming %s to %s" % (old, new))
Andrew Geisslerc926e172021-05-07 16:11:35 -05001996 bb.utils.rename(old, new)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001997 pkgfiles[pkg].remove(old)
Brad Bishop64c979e2019-11-04 13:55:29 -05001998
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001999 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
2000 if len(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05002001 with open(shlibs_file, 'w') as fd:
Andrew Geissler635e0e42020-08-21 15:58:33 -05002002 for s in sorted(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05002003 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
2004 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
2005 if old_pkg != pkg:
2006 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))
2007 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
2008 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
2009 if s[0] not in shlib_provider:
2010 shlib_provider[s[0]] = {}
2011 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
Brad Bishop1d80a2e2019-11-15 16:35:03 -05002012 if needs_ldconfig:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002013 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Patrick Williams213cb262021-08-07 19:21:33 -05002014 postinst = d.getVar('pkg_postinst:%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002015 if not postinst:
2016 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002017 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williams213cb262021-08-07 19:21:33 -05002018 d.setVar('pkg_postinst:%s' % pkg, postinst)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002019 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
2020
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002021 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002022 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002023 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002024 for e in assumed_libs.split():
2025 l, dep_pkg = e.split(":")
2026 lib_ver = None
2027 dep_pkg = dep_pkg.rsplit("_", 1)
2028 if len(dep_pkg) == 2:
2029 lib_ver = dep_pkg[1]
2030 dep_pkg = dep_pkg[0]
2031 if l not in shlib_provider:
2032 shlib_provider[l] = {}
2033 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
2034
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002035 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002036
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002037 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002038 bb.debug(2, "calculating shlib requirements for %s" % pkg)
2039
Patrick Williams213cb262021-08-07 19:21:33 -05002040 private_libs = d.getVar('PRIVATE_LIBS:' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Brad Bishop316dfdd2018-06-25 12:45:53 -04002041 private_libs = private_libs.split()
2042
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002043 deps = list()
2044 for n in needed[pkg]:
2045 # if n is in private libraries, don't try to search provider for it
2046 # this could cause problem in case some abc.bb provides private
2047 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
2048 # but skipping it is still better alternative than providing own
2049 # version and then adding runtime dependency for the same system library
Brad Bishop79641f22019-09-10 07:20:22 -04002050 import fnmatch
2051 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 -05002052 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
2053 continue
2054 if n[0] in shlib_provider.keys():
Brad Bishop00e122a2019-10-05 11:10:57 -04002055 shlib_provider_map = shlib_provider[n[0]]
2056 matches = set()
2057 for p in itertools.chain(list(n[2]), sorted(shlib_provider_map.keys()), libsearchpath):
2058 if p in shlib_provider_map:
2059 matches.add(p)
2060 if len(matches) > 1:
2061 matchpkgs = ', '.join([shlib_provider_map[match][0] for match in matches])
2062 bb.error("%s: Multiple shlib providers for %s: %s (used by files: %s)" % (pkg, n[0], matchpkgs, n[1]))
2063 elif len(matches) == 1:
2064 (dep_pkg, ver_needed) = shlib_provider_map[matches.pop()]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002065
2066 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
2067
2068 if dep_pkg == pkg:
2069 continue
2070
2071 if ver_needed:
2072 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
2073 else:
2074 dep = dep_pkg
2075 if not dep in deps:
2076 deps.append(dep)
2077 continue
2078 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
2079
2080 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
2081 if os.path.exists(deps_file):
2082 os.remove(deps_file)
Brad Bishop64c979e2019-11-04 13:55:29 -05002083 if deps:
2084 with open(deps_file, 'w') as fd:
2085 for dep in sorted(deps):
2086 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002087}
2088
2089python package_do_pkgconfig () {
2090 import re
2091
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002092 packages = d.getVar('PACKAGES')
2093 workdir = d.getVar('WORKDIR')
2094 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002095
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002096 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
2097 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002098
Brad Bishop19323692019-04-05 15:28:33 -04002099 pc_re = re.compile(r'(.*)\.pc$')
2100 var_re = re.compile(r'(.*)=(.*)')
2101 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002102
2103 pkgconfig_provided = {}
2104 pkgconfig_needed = {}
2105 for pkg in packages.split():
2106 pkgconfig_provided[pkg] = []
2107 pkgconfig_needed[pkg] = []
Patrick Williams93c203f2021-10-06 16:15:23 -05002108 for file in sorted(pkgfiles[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002109 m = pc_re.match(file)
2110 if m:
2111 pd = bb.data.init()
2112 name = m.group(1)
Patrick Williams93c203f2021-10-06 16:15:23 -05002113 pkgconfig_provided[pkg].append(os.path.basename(name))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002114 if not os.access(file, os.R_OK):
2115 continue
Brad Bishop64c979e2019-11-04 13:55:29 -05002116 with open(file, 'r') as f:
2117 lines = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002118 for l in lines:
2119 m = var_re.match(l)
2120 if m:
2121 name = m.group(1)
2122 val = m.group(2)
2123 pd.setVar(name, pd.expand(val))
2124 continue
2125 m = field_re.match(l)
2126 if m:
2127 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002128 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002129 if hdr == 'Requires':
2130 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
2131
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002132 for pkg in packages.split():
2133 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
2134 if pkgconfig_provided[pkg] != []:
Brad Bishop64c979e2019-11-04 13:55:29 -05002135 with open(pkgs_file, 'w') as f:
Patrick Williams93c203f2021-10-06 16:15:23 -05002136 for p in sorted(pkgconfig_provided[pkg]):
Brad Bishop64c979e2019-11-04 13:55:29 -05002137 f.write('%s\n' % p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002138
2139 # Go from least to most specific since the last one found wins
2140 for dir in reversed(shlibs_dirs):
2141 if not os.path.exists(dir):
2142 continue
Brad Bishop08902b02019-08-20 09:16:51 -04002143 for file in sorted(os.listdir(dir)):
Brad Bishop19323692019-04-05 15:28:33 -04002144 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002145 if m:
2146 pkg = m.group(1)
Brad Bishop64c979e2019-11-04 13:55:29 -05002147 with open(os.path.join(dir, file)) as fd:
2148 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002149 pkgconfig_provided[pkg] = []
2150 for l in lines:
2151 pkgconfig_provided[pkg].append(l.rstrip())
2152
2153 for pkg in packages.split():
2154 deps = []
2155 for n in pkgconfig_needed[pkg]:
2156 found = False
2157 for k in pkgconfig_provided.keys():
2158 if n in pkgconfig_provided[k]:
2159 if k != pkg and not (k in deps):
2160 deps.append(k)
2161 found = True
2162 if found == False:
2163 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
2164 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
2165 if len(deps):
Brad Bishop64c979e2019-11-04 13:55:29 -05002166 with open(deps_file, 'w') as fd:
2167 for dep in deps:
2168 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002169}
2170
2171def read_libdep_files(d):
2172 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002173 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002174 for pkg in packages:
2175 pkglibdeps[pkg] = {}
2176 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
2177 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
2178 if os.access(depsfile, os.R_OK):
Brad Bishop64c979e2019-11-04 13:55:29 -05002179 with open(depsfile) as fd:
2180 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002181 for l in lines:
2182 l.rstrip()
2183 deps = bb.utils.explode_dep_versions2(l)
2184 for dep in deps:
2185 if not dep in pkglibdeps[pkg]:
2186 pkglibdeps[pkg][dep] = deps[dep]
2187 return pkglibdeps
2188
2189python read_shlibdeps () {
2190 pkglibdeps = read_libdep_files(d)
2191
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002192 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002193 for pkg in packages:
Patrick Williams213cb262021-08-07 19:21:33 -05002194 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04002195 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002196 # Add the dep if it's not already there, or if no comparison is set
2197 if dep not in rdepends:
2198 rdepends[dep] = []
2199 for v in pkglibdeps[pkg][dep]:
2200 if v not in rdepends[dep]:
2201 rdepends[dep].append(v)
Patrick Williams213cb262021-08-07 19:21:33 -05002202 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002203}
2204
2205python package_depchains() {
2206 """
2207 For a given set of prefix and postfix modifiers, make those packages
2208 RRECOMMENDS on the corresponding packages for its RDEPENDS.
2209
2210 Example: If package A depends upon package B, and A's .bb emits an
2211 A-dev package, this would make A-dev Recommends: B-dev.
2212
2213 If only one of a given suffix is specified, it will take the RRECOMMENDS
2214 based on the RDEPENDS of *all* other packages. If more than one of a given
2215 suffix is specified, its will only use the RDEPENDS of the single parent
2216 package.
2217 """
2218
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002219 packages = d.getVar('PACKAGES')
2220 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2221 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002222
2223 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2224
2225 #bb.note('depends for %s is %s' % (base, depends))
Patrick Williams213cb262021-08-07 19:21:33 -05002226 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002227
Brad Bishop19323692019-04-05 15:28:33 -04002228 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002229 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2230 #bb.note("Skipping %s" % depend)
2231 continue
2232 if depend.endswith('-dev'):
2233 depend = depend[:-4]
2234 if depend.endswith('-dbg'):
2235 depend = depend[:-4]
2236 pkgname = getname(depend, suffix)
2237 #bb.note("Adding %s for %s" % (pkgname, depend))
2238 if pkgname not in rreclist and pkgname != pkg:
2239 rreclist[pkgname] = []
2240
Patrick Williams213cb262021-08-07 19:21:33 -05002241 #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist)))
2242 d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002243
2244 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2245
2246 #bb.note('rdepends for %s is %s' % (base, rdepends))
Patrick Williams213cb262021-08-07 19:21:33 -05002247 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS:' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002248
Brad Bishop19323692019-04-05 15:28:33 -04002249 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002250 if depend.find('virtual-locale-') != -1:
2251 #bb.note("Skipping %s" % depend)
2252 continue
2253 if depend.endswith('-dev'):
2254 depend = depend[:-4]
2255 if depend.endswith('-dbg'):
2256 depend = depend[:-4]
2257 pkgname = getname(depend, suffix)
2258 #bb.note("Adding %s for %s" % (pkgname, depend))
2259 if pkgname not in rreclist and pkgname != pkg:
2260 rreclist[pkgname] = []
2261
Patrick Williams213cb262021-08-07 19:21:33 -05002262 #bb.note('setting: RRECOMMENDS:%s=%s' % (pkg, ' '.join(rreclist)))
2263 d.setVar('RRECOMMENDS:%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002264
2265 def add_dep(list, dep):
2266 if dep not in list:
2267 list.append(dep)
2268
2269 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002270 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002271 add_dep(depends, dep)
2272
2273 rdepends = []
2274 for pkg in packages.split():
Patrick Williams213cb262021-08-07 19:21:33 -05002275 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002276 add_dep(rdepends, dep)
2277
2278 #bb.note('rdepends is %s' % rdepends)
2279
2280 def post_getname(name, suffix):
2281 return '%s%s' % (name, suffix)
2282 def pre_getname(name, suffix):
2283 return '%s%s' % (suffix, name)
2284
2285 pkgs = {}
2286 for pkg in packages.split():
2287 for postfix in postfixes:
2288 if pkg.endswith(postfix):
2289 if not postfix in pkgs:
2290 pkgs[postfix] = {}
2291 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2292
2293 for prefix in prefixes:
2294 if pkg.startswith(prefix):
2295 if not prefix in pkgs:
2296 pkgs[prefix] = {}
2297 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2298
2299 if "-dbg" in pkgs:
2300 pkglibdeps = read_libdep_files(d)
2301 pkglibdeplist = []
2302 for pkg in pkglibdeps:
2303 for k in pkglibdeps[pkg]:
2304 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002305 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002306
2307 for suffix in pkgs:
2308 for pkg in pkgs[suffix]:
Patrick Williams213cb262021-08-07 19:21:33 -05002309 if d.getVarFlag('RRECOMMENDS:' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002310 continue
2311 (base, func) = pkgs[suffix][pkg]
2312 if suffix == "-dev":
2313 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2314 elif suffix == "-dbg":
2315 if not dbgdefaultdeps:
2316 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2317 continue
2318 if len(pkgs[suffix]) == 1:
2319 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2320 else:
2321 rdeps = []
Patrick Williams213cb262021-08-07 19:21:33 -05002322 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS:' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002323 add_dep(rdeps, dep)
2324 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2325}
2326
2327# Since bitbake can't determine which variables are accessed during package
2328# iteration, we need to list them here:
Andrew Geissler1e34c2d2020-05-29 16:02:59 -05002329PACKAGEVARS = "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 -05002330
Andrew Geissler82c905d2020-04-13 13:39:40 -05002331def gen_packagevar(d, pkgvars="PACKAGEVARS"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002332 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002333 pkgs = (d.getVar("PACKAGES") or "").split()
Andrew Geissler82c905d2020-04-13 13:39:40 -05002334 vars = (d.getVar(pkgvars) or "").split()
2335 for v in vars:
2336 ret.append(v)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002337 for p in pkgs:
2338 for v in vars:
Patrick Williams213cb262021-08-07 19:21:33 -05002339 ret.append(v + ":" + p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002340
2341 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2342 # affected recipes.
2343 ret.append('LICENSE_EXCLUSION-%s' % p)
2344 return " ".join(ret)
2345
2346PACKAGE_PREPROCESS_FUNCS ?= ""
2347# Functions for setting up PKGD
2348PACKAGEBUILDPKGD ?= " \
Brad Bishop96ff1982019-08-19 13:50:42 -04002349 package_prepare_pkgdata \
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002350 perform_packagecopy \
2351 ${PACKAGE_PREPROCESS_FUNCS} \
2352 split_and_strip_files \
2353 fixup_perms \
2354 "
2355# Functions which split PKGD up into separate packages
2356PACKAGESPLITFUNCS ?= " \
2357 package_do_split_locales \
2358 populate_packages"
2359# Functions which process metadata based on split packages
2360PACKAGEFUNCS += " \
2361 package_fixsymlinks \
2362 package_name_hook \
2363 package_do_filedeps \
2364 package_do_shlibs \
2365 package_do_pkgconfig \
2366 read_shlibdeps \
2367 package_depchains \
2368 emit_pkgdata"
2369
2370python do_package () {
2371 # Change the following version to cause sstate to invalidate the package
2372 # cache. This is useful if an item this class depends on changes in a
2373 # way that the output of this class changes. rpmdeps is a good example
2374 # as any change to rpmdeps requires this to be rerun.
Andrew Geissler6ce62a22020-11-30 19:58:47 -06002375 # PACKAGE_BBCLASS_VERSION = "4"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002376
2377 # Init cachedpath
2378 global cpath
2379 cpath = oe.cachedpath.CachedPath()
2380
2381 ###########################################################################
2382 # Sanity test the setup
2383 ###########################################################################
2384
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002385 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002386 if len(packages) < 1:
2387 bb.debug(1, "No packages to build, skipping do_package")
2388 return
2389
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002390 workdir = d.getVar('WORKDIR')
2391 outdir = d.getVar('DEPLOY_DIR')
2392 dest = d.getVar('D')
2393 dvar = d.getVar('PKGD')
2394 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002395
2396 if not workdir or not outdir or not dest or not dvar or not pn:
2397 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
Andrew Geisslereff27472021-10-29 15:35:00 -05002398 oe.qa.handle_error("var-undefined", msg, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002399 return
2400
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002401 bb.build.exec_func("package_convert_pr_autoinc", d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002402
2403 ###########################################################################
2404 # Optimisations
2405 ###########################################################################
2406
2407 # Continually expanding complex expressions is inefficient, particularly
2408 # when we write to the datastore and invalidate the expansion cache. This
2409 # code pre-expands some frequently used variables
2410
2411 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002412 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002413
2414 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2415 expandVar(x, d)
2416
2417 ###########################################################################
2418 # Setup PKGD (from D)
2419 ###########################################################################
2420
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002421 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002422 bb.build.exec_func(f, d)
2423
2424 ###########################################################################
2425 # Split up PKGD into PKGDEST
2426 ###########################################################################
2427
2428 cpath = oe.cachedpath.CachedPath()
2429
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002430 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002431 bb.build.exec_func(f, d)
2432
2433 ###########################################################################
2434 # Process PKGDEST
2435 ###########################################################################
2436
2437 # Build global list of files in each split package
2438 global pkgfiles
2439 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002440 packages = d.getVar('PACKAGES').split()
2441 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002442 for pkg in packages:
2443 pkgfiles[pkg] = []
2444 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2445 for file in files:
2446 pkgfiles[pkg].append(walkroot + os.sep + file)
2447
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002448 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002449 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002450
Andrew Geisslereff27472021-10-29 15:35:00 -05002451 oe.qa.exit_if_errors(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002452}
2453
2454do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2455do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2456addtask package after do_install
2457
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002458SSTATETASKS += "do_package"
2459do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2460do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002461do_package_setscene[dirs] = "${STAGING_DIR}"
2462
2463python do_package_setscene () {
2464 sstate_setscene(d)
2465}
2466addtask do_package_setscene
2467
Brad Bishopc68388fc2019-08-26 01:33:31 -04002468# Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both
2469# do_package_setscene and do_packagedata_setscene leading to races
2470python do_packagedata () {
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002471 bb.build.exec_func("package_get_auto_pr", d)
2472
Brad Bishopc68388fc2019-08-26 01:33:31 -04002473 src = d.expand("${PKGDESTWORK}")
2474 dest = d.expand("${WORKDIR}/pkgdata-pdata-input")
2475 oe.path.copyhardlinktree(src, dest)
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002476
2477 bb.build.exec_func("packagedata_translate_pr_autoinc", d)
2478}
Andrew Geisslerd1e89492021-02-12 15:35:20 -06002479do_packagedata[cleandirs] += "${WORKDIR}/pkgdata-pdata-input"
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002480
2481# Translate the EXTENDPRAUTO and AUTOINC to the final values
2482packagedata_translate_pr_autoinc() {
2483 find ${WORKDIR}/pkgdata-pdata-input -type f | xargs --no-run-if-empty \
2484 sed -e 's,@PRSERV_PV_AUTOINC@,${PRSERV_PV_AUTOINC},g' \
2485 -e 's,@EXTENDPRAUTO@,${EXTENDPRAUTO},g' -i
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002486}
2487
2488addtask packagedata before do_build after do_package
2489
2490SSTATETASKS += "do_packagedata"
Brad Bishopc68388fc2019-08-26 01:33:31 -04002491do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002492do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002493do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002494
2495python do_packagedata_setscene () {
2496 sstate_setscene(d)
2497}
2498addtask do_packagedata_setscene
2499
2500#
2501# Helper functions for the package writing classes
2502#
2503
2504def mapping_rename_hook(d):
2505 """
2506 Rewrite variables to account for package renaming in things
2507 like debian.bbclass or manual PKG variable name changes
2508 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002509 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002510 runtime_mapping_rename("RDEPENDS", pkg, d)
2511 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2512 runtime_mapping_rename("RSUGGESTS", pkg, d)