blob: edeffa978fab8014dd29aaeef80e082a4d3b8f44 [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#
10# a) package_get_auto_pr - get PRAUTO from remote PR service
11#
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
43
44# Need the package_qa_handle_error() in insane.bbclass
45inherit insane
46
47PKGD = "${WORKDIR}/package"
48PKGDEST = "${WORKDIR}/packages-split"
49
50LOCALE_SECTION ?= ''
51
52ALL_MULTILIB_PACKAGE_ARCHS = "${@all_multilib_tune_values(d, 'PACKAGE_ARCHS')}"
53
54# rpm is used for the per-file dependency identification
Brad Bishop316dfdd2018-06-25 12:45:53 -040055# dwarfsrcfiles is used to determine the list of debug source files
56PACKAGE_DEPENDS += "rpm-native dwarfsrcfiles-native"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057
Brad Bishop6e60e8b2018-02-01 10:27:11 -050058
59# If your postinstall can execute at rootfs creation time rather than on
60# target but depends on a native/cross tool in order to execute, you need to
61# list that tool in PACKAGE_WRITE_DEPENDS. Target package dependencies belong
62# in the package dependencies as normal, this is just for native/cross support
63# tools at rootfs build time.
64PACKAGE_WRITE_DEPS ??= ""
65
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066def legitimize_package_name(s):
67 """
68 Make sure package names are legitimate strings
69 """
70 import re
71
72 def fixutf(m):
73 cp = m.group(1)
74 if cp:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060075 return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076
77 # Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
78 s = re.sub('<U([0-9A-Fa-f]{1,4})>', fixutf, s)
79
80 # Remaining package name validity fixes
81 return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
82
83def 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):
84 """
85 Used in .bb files to split up dynamically generated subpackages of a
86 given package, usually plugins or modules.
87
88 Arguments:
89 root -- the path in which to search
90 file_regex -- regular expression to match searched files. Use
91 parentheses () to mark the part of this expression
92 that should be used to derive the module name (to be
93 substituted where %s is used in other function
94 arguments as noted below)
95 output_pattern -- pattern to use for the package names. Must include %s.
96 description -- description to set for each package. Must include %s.
97 postinst -- postinstall script to use for all packages (as a
98 string)
99 recursive -- True to perform a recursive search - default False
100 hook -- a hook function to be called for every match. The
101 function will be called with the following arguments
102 (in the order listed):
103 f: full path to the file/directory match
104 pkg: the package name
105 file_regex: as above
106 output_pattern: as above
107 modulename: the module name derived using file_regex
108 extra_depends -- extra runtime dependencies (RDEPENDS) to be set for
109 all packages. The default value of None causes a
110 dependency on the main package (${PN}) - if you do
111 not want this, pass '' for this parameter.
112 aux_files_pattern -- extra item(s) to be added to FILES for each
113 package. Can be a single string item or a list of
114 strings for multiple items. Must include %s.
115 postrm -- postrm script to use for all packages (as a string)
116 allow_dirs -- True allow directories to be matched - default False
117 prepend -- if True, prepend created packages to PACKAGES instead
118 of the default False which appends them
119 match_path -- match file_regex on the whole relative path to the
120 root rather than just the file name
121 aux_files_pattern_verbatim -- extra item(s) to be added to FILES for
122 each package, using the actual derived module name
123 rather than converting it to something legal for a
124 package name. Can be a single string item or a list
125 of strings for multiple items. Must include %s.
126 allow_links -- True to allow symlinks to be matched - default False
127 summary -- Summary to set for each package. Must include %s;
128 defaults to description if not set.
129
130 """
131
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500132 dvar = d.getVar('PKGD')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500133 root = d.expand(root)
134 output_pattern = d.expand(output_pattern)
135 extra_depends = d.expand(extra_depends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500136
137 # If the root directory doesn't exist, don't error out later but silently do
138 # no splitting.
139 if not os.path.exists(dvar + root):
140 return []
141
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500142 ml = d.getVar("MLPREFIX")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500143 if ml:
144 if not output_pattern.startswith(ml):
145 output_pattern = ml + output_pattern
146
147 newdeps = []
148 for dep in (extra_depends or "").split():
149 if dep.startswith(ml):
150 newdeps.append(dep)
151 else:
152 newdeps.append(ml + dep)
153 if newdeps:
154 extra_depends = " ".join(newdeps)
155
156
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500157 packages = d.getVar('PACKAGES').split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600158 split_packages = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159
160 if postinst:
161 postinst = '#!/bin/sh\n' + postinst + '\n'
162 if postrm:
163 postrm = '#!/bin/sh\n' + postrm + '\n'
164 if not recursive:
165 objs = os.listdir(dvar + root)
166 else:
167 objs = []
168 for walkroot, dirs, files in os.walk(dvar + root):
169 for file in files:
170 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
171 if relpath:
172 objs.append(relpath)
173
174 if extra_depends == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500175 extra_depends = d.getVar("PN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500176
177 if not summary:
178 summary = description
179
180 for o in sorted(objs):
181 import re, stat
182 if match_path:
183 m = re.match(file_regex, o)
184 else:
185 m = re.match(file_regex, os.path.basename(o))
186
187 if not m:
188 continue
189 f = os.path.join(dvar + root, o)
190 mode = os.lstat(f).st_mode
191 if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))):
192 continue
193 on = legitimize_package_name(m.group(1))
194 pkg = output_pattern % on
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600195 split_packages.add(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500196 if not pkg in packages:
197 if prepend:
198 packages = [pkg] + packages
199 else:
200 packages.append(pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500201 oldfiles = d.getVar('FILES_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500202 newfile = os.path.join(root, o)
203 # These names will be passed through glob() so if the filename actually
204 # contains * or ? (rare, but possible) we need to handle that specially
205 newfile = newfile.replace('*', '[*]')
206 newfile = newfile.replace('?', '[?]')
207 if not oldfiles:
208 the_files = [newfile]
209 if aux_files_pattern:
210 if type(aux_files_pattern) is list:
211 for fp in aux_files_pattern:
212 the_files.append(fp % on)
213 else:
214 the_files.append(aux_files_pattern % on)
215 if aux_files_pattern_verbatim:
216 if type(aux_files_pattern_verbatim) is list:
217 for fp in aux_files_pattern_verbatim:
218 the_files.append(fp % m.group(1))
219 else:
220 the_files.append(aux_files_pattern_verbatim % m.group(1))
221 d.setVar('FILES_' + pkg, " ".join(the_files))
222 else:
223 d.setVar('FILES_' + pkg, oldfiles + " " + newfile)
224 if extra_depends != '':
225 d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500226 if not d.getVar('DESCRIPTION_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500227 d.setVar('DESCRIPTION_' + pkg, description % on)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500228 if not d.getVar('SUMMARY_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229 d.setVar('SUMMARY_' + pkg, summary % on)
230 if postinst:
231 d.setVar('pkg_postinst_' + pkg, postinst)
232 if postrm:
233 d.setVar('pkg_postrm_' + pkg, postrm)
234 if callable(hook):
235 hook(f, pkg, file_regex, output_pattern, m.group(1))
236
237 d.setVar('PACKAGES', ' '.join(packages))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600238 return list(split_packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500239
240PACKAGE_DEPENDS += "file-native"
241
242python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500243 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500244 deps = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500245 for dep in (d.getVar('PACKAGE_DEPENDS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500246 deps += " %s:do_populate_sysroot" % dep
247 d.appendVarFlag('do_package', 'depends', deps)
248
249 # shlibs requires any DEPENDS to have already packaged for the *.list files
250 d.appendVarFlag('do_package', 'deptask', " do_packagedata")
251}
252
253# Get a list of files from file vars by searching files under current working directory
254# The list contains symlinks, directories and normal files.
255def files_from_filevars(filevars):
256 import os,glob
257 cpath = oe.cachedpath.CachedPath()
258 files = []
259 for f in filevars:
260 if os.path.isabs(f):
261 f = '.' + f
262 if not f.startswith("./"):
263 f = './' + f
264 globbed = glob.glob(f)
265 if globbed:
266 if [ f ] != globbed:
267 files += globbed
268 continue
269 files.append(f)
270
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600271 symlink_paths = []
272 for ind, f in enumerate(files):
273 # Handle directory symlinks. Truncate path to the lowest level symlink
274 parent = ''
275 for dirname in f.split('/')[:-1]:
276 parent = os.path.join(parent, dirname)
277 if dirname == '.':
278 continue
279 if cpath.islink(parent):
280 bb.warn("FILES contains file '%s' which resides under a "
281 "directory symlink. Please fix the recipe and use the "
282 "real path for the file." % f[1:])
283 symlink_paths.append(f)
284 files[ind] = parent
285 f = parent
286 break
287
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500288 if not cpath.islink(f):
289 if cpath.isdir(f):
290 newfiles = [ os.path.join(f,x) for x in os.listdir(f) ]
291 if newfiles:
292 files += newfiles
293
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600294 return files, symlink_paths
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500295
296# Called in package_<rpm,ipk,deb>.bbclass to get the correct list of configuration files
297def get_conffiles(pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500298 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500299 root = os.path.join(pkgdest, pkg)
300 cwd = os.getcwd()
301 os.chdir(root)
302
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500303 conffiles = d.getVar('CONFFILES_%s' % pkg);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304 if conffiles == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500305 conffiles = d.getVar('CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500306 if conffiles == None:
307 conffiles = ""
308 conffiles = conffiles.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600309 conf_orig_list = files_from_filevars(conffiles)[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500310
311 # Remove links and directories from conf_orig_list to get conf_list which only contains normal files
312 conf_list = []
313 for f in conf_orig_list:
314 if os.path.isdir(f):
315 continue
316 if os.path.islink(f):
317 continue
318 if not os.path.exists(f):
319 continue
320 conf_list.append(f)
321
322 # Remove the leading './'
323 for i in range(0, len(conf_list)):
324 conf_list[i] = conf_list[i][1:]
325
326 os.chdir(cwd)
327 return conf_list
328
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500329def checkbuildpath(file, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500330 tmpdir = d.getVar('TMPDIR')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500331 with open(file) as f:
332 file_content = f.read()
333 if tmpdir in file_content:
334 return True
335
336 return False
337
Brad Bishop316dfdd2018-06-25 12:45:53 -0400338def parse_debugsources_from_dwarfsrcfiles_output(dwarfsrcfiles_output):
339 debugfiles = {}
340
341 for line in dwarfsrcfiles_output.splitlines():
342 if line.startswith("\t"):
343 debugfiles[os.path.normpath(line.split()[0])] = ""
344
345 return debugfiles.keys()
346
347def append_source_info(file, sourcefile, d, fatal=True):
348 cmd = "'dwarfsrcfiles' '%s'" % (file)
349 (retval, output) = oe.utils.getstatusoutput(cmd)
350 # 255 means a specific file wasn't fully parsed to get the debug file list, which is not a fatal failure
351 if retval != 0 and retval != 255:
352 msg = "dwarfsrcfiles failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else "")
353 if fatal:
354 bb.fatal(msg)
355 bb.note(msg)
356
357 debugsources = parse_debugsources_from_dwarfsrcfiles_output(output)
358 # filenames are null-separated - this is an artefact of the previous use
359 # of rpm's debugedit, which was writing them out that way, and the code elsewhere
360 # is still assuming that.
361 debuglistoutput = '\0'.join(debugsources) + '\0'
362 open(sourcefile, 'a').write(debuglistoutput)
363
364
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365def splitdebuginfo(file, debugfile, debugsrcdir, sourcefile, d):
366 # Function to split a single file into two components, one is the stripped
367 # target system binary, the other contains any debugging information. The
368 # two files are linked to reference each other.
369 #
370 # sourcefile is also generated containing a list of debugsources
371
372 import stat
373
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500374 dvar = d.getVar('PKGD')
375 objcopy = d.getVar("OBJCOPY")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376
377 # We ignore kernel modules, we don't generate debug info files.
378 if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
379 return 1
380
381 newmode = None
382 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
383 origmode = os.stat(file)[stat.ST_MODE]
384 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
385 os.chmod(file, newmode)
386
387 # We need to extract the debug src information here...
388 if debugsrcdir:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400389 append_source_info(file, sourcefile, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500390
391 bb.utils.mkdirhier(os.path.dirname(debugfile))
392
393 cmd = "'%s' --only-keep-debug '%s' '%s'" % (objcopy, file, debugfile)
394 (retval, output) = oe.utils.getstatusoutput(cmd)
395 if retval:
396 bb.fatal("objcopy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
397
398 # Set the debuglink to have the view of the file path on the target
399 cmd = "'%s' --add-gnu-debuglink='%s' '%s'" % (objcopy, debugfile, file)
400 (retval, output) = oe.utils.getstatusoutput(cmd)
401 if retval:
402 bb.fatal("objcopy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
403
404 if newmode:
405 os.chmod(file, origmode)
406
407 return 0
408
409def copydebugsources(debugsrcdir, d):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400410 # The debug src information written out to sourcefile is further processed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500411 # and copied to the destination here.
412
413 import stat
414
415 sourcefile = d.expand("${WORKDIR}/debugsources.list")
416 if debugsrcdir and os.path.isfile(sourcefile):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500417 dvar = d.getVar('PKGD')
418 strip = d.getVar("STRIP")
419 objcopy = d.getVar("OBJCOPY")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500420 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500421 workparentdir = os.path.dirname(os.path.dirname(workdir))
422 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
423
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500424 # If build path exists in sourcefile, it means toolchain did not use
425 # -fdebug-prefix-map to compile
426 if checkbuildpath(sourcefile, d):
427 localsrc_prefix = workparentdir + "/"
428 else:
429 localsrc_prefix = "/usr/src/debug/"
430
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500431 nosuchdir = []
432 basepath = dvar
433 for p in debugsrcdir.split("/"):
434 basepath = basepath + "/" + p
435 if not cpath.exists(basepath):
436 nosuchdir.append(basepath)
437 bb.utils.mkdirhier(basepath)
438 cpath.updatecache(basepath)
439
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500440 # Ignore files from the recipe sysroots (target and native)
441 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500442 # We need to ignore files that are not actually ours
443 # we do this by only paying attention to items from this package
444 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500445 # Remove prefix in the source paths
446 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500447 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
448
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500449 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 (retval, output) = oe.utils.getstatusoutput(cmd)
451 # Can "fail" if internal headers/transient sources are attempted
452 #if retval:
453 # bb.fatal("debug source copy failed with exit code %s (cmd was %s)" % (retval, cmd))
454
455 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
456 # Work around this by manually finding and copying any symbolic links that made it through.
457 cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s' 2>/dev/null)" % (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
458 (retval, output) = oe.utils.getstatusoutput(cmd)
459 if retval:
460 bb.fatal("debugsrc symlink fixup failed with exit code %s (cmd was %s)" % (retval, cmd))
461
462 # The copy by cpio may have resulted in some empty directories! Remove these
463 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
464 (retval, output) = oe.utils.getstatusoutput(cmd)
465 if retval:
466 bb.fatal("empty directory removal failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
467
468 # Also remove debugsrcdir if its empty
469 for p in nosuchdir[::-1]:
470 if os.path.exists(p) and not os.listdir(p):
471 os.rmdir(p)
472
473#
474# Package data handling routines
475#
476
477def get_package_mapping (pkg, basepkg, d):
478 import oe.packagedata
479
480 data = oe.packagedata.read_subpkgdata(pkg, d)
481 key = "PKG_%s" % pkg
482
483 if key in data:
484 # Have to avoid undoing the write_extra_pkgs(global_variants...)
485 if bb.data.inherits_class('allarch', d) and data[key] == basepkg:
486 return pkg
487 return data[key]
488
489 return pkg
490
491def get_package_additional_metadata (pkg_type, d):
492 base_key = "PACKAGE_ADD_METADATA"
493 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
494 if d.getVar(key, False) is None:
495 continue
496 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500497 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500498 d.setVarFlag(key, "separator", "\\n")
499 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
500 return "\n".join(metadata_fields).strip()
501
502def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500503 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500504
505 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500506 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500507 for depend in deps:
508 new_depend = get_package_mapping(depend, pkg, d)
509 new_depends[new_depend] = deps[depend]
510
511 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
512
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500513 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500514
515#
516# Package functions suitable for inclusion in PACKAGEFUNCS
517#
518
519python package_get_auto_pr() {
520 import oe.prservice
521 import re
522
523 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500524 pn = d.getVar('PN')
525 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500526 if not (host is None):
527 d.setVar("PRSERV_HOST", host)
528
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500529 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500530
531 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500532 if not d.getVar('PRSERV_HOST'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500533 if 'AUTOINC' in pkgv:
534 d.setVar("PKGV", pkgv.replace("AUTOINC", "0"))
535 return
536
537 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500538 pv = d.getVar("PV")
539 version = d.getVar("PRAUTOINX")
540 pkgarch = d.getVar("PACKAGE_ARCH")
541 checksum = d.getVar("BB_TASKHASH")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500542
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500543 if d.getVar('PRSERV_LOCKDOWN'):
544 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500545 if auto_pr is None:
546 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
547 d.setVar('PRAUTO',str(auto_pr))
548 return
549
550 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500551 conn = d.getVar("__PRSERV_CONN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500552 if conn is None:
553 conn = oe.prservice.prserv_make_conn(d)
554 if conn is not None:
555 if "AUTOINC" in pkgv:
556 srcpv = bb.fetch2.get_srcrev(d)
557 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
558 value = conn.getPR(base_ver, pkgarch, srcpv)
559 d.setVar("PKGV", pkgv.replace("AUTOINC", str(value)))
560
561 auto_pr = conn.getPR(version, pkgarch, checksum)
562 except Exception as e:
563 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
564 if auto_pr is None:
565 bb.fatal("Can NOT get PRAUTO from remote PR service")
566 d.setVar('PRAUTO',str(auto_pr))
567}
568
569LOCALEBASEPN ??= "${PN}"
570
571python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500572 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500573 bb.debug(1, "package requested not splitting locales")
574 return
575
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500576 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500577
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500578 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500579 if not datadir:
580 bb.note("datadir not defined")
581 return
582
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500583 dvar = d.getVar('PKGD')
584 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500585
586 if pn + '-locale' in packages:
587 packages.remove(pn + '-locale')
588
589 localedir = os.path.join(dvar + datadir, 'locale')
590
591 if not cpath.isdir(localedir):
592 bb.debug(1, "No locale files in this package")
593 return
594
595 locales = os.listdir(localedir)
596
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500597 summary = d.getVar('SUMMARY') or pn
598 description = d.getVar('DESCRIPTION') or ""
599 locale_section = d.getVar('LOCALE_SECTION')
600 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500601 for l in sorted(locales):
602 ln = legitimize_package_name(l)
603 pkg = pn + '-locale-' + ln
604 packages.append(pkg)
605 d.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l))
606 d.setVar('RRECOMMENDS_' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
607 d.setVar('RPROVIDES_' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
608 d.setVar('SUMMARY_' + pkg, '%s - %s translations' % (summary, l))
609 d.setVar('DESCRIPTION_' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
610 if locale_section:
611 d.setVar('SECTION_' + pkg, locale_section)
612
613 d.setVar('PACKAGES', ' '.join(packages))
614
615 # Disabled by RP 18/06/07
616 # Wildcards aren't supported in debian
617 # They break with ipkg since glibc-locale* will mean that
618 # glibc-localedata-translit* won't install as a dependency
619 # for some other package which breaks meta-toolchain
620 # Probably breaks since virtual-locale- isn't provided anywhere
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500621 #rdep = (d.getVar('RDEPENDS_%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500622 #rdep.append('%s-locale*' % pn)
623 #d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep))
624}
625
626python perform_packagecopy () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500627 dest = d.getVar('D')
628 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500629
630 # Start by package population by taking a copy of the installed
631 # files to operate on
632 # Preserve sparse files and hard links
633 cmd = 'tar -cf - -C %s -p . | tar -xf - -C %s' % (dest, dvar)
634 (retval, output) = oe.utils.getstatusoutput(cmd)
635 if retval:
636 bb.fatal("file copy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
637
638 # replace RPATHs for the nativesdk binaries, to make them relocatable
639 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
640 rpath_replace (dvar, d)
641}
642perform_packagecopy[cleandirs] = "${PKGD}"
643perform_packagecopy[dirs] = "${PKGD}"
644
645# We generate a master list of directories to process, we start by
646# seeding this list with reasonable defaults, then load from
647# the fs-perms.txt files
648python fixup_perms () {
649 import pwd, grp
650
651 # init using a string with the same format as a line as documented in
652 # the fs-perms.txt file
653 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
654 # <path> link <link target>
655 #
656 # __str__ can be used to print out an entry in the input format
657 #
658 # if fs_perms_entry.path is None:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400659 # an error occurred
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500660 # if fs_perms_entry.link, you can retrieve:
661 # fs_perms_entry.path = path
662 # fs_perms_entry.link = target of link
663 # if not fs_perms_entry.link, you can retrieve:
664 # fs_perms_entry.path = path
665 # fs_perms_entry.mode = expected dir mode or None
666 # fs_perms_entry.uid = expected uid or -1
667 # fs_perms_entry.gid = expected gid or -1
668 # fs_perms_entry.walk = 'true' or something else
669 # fs_perms_entry.fmode = expected file mode or None
670 # fs_perms_entry.fuid = expected file uid or -1
671 # fs_perms_entry_fgid = expected file gid or -1
672 class fs_perms_entry():
673 def __init__(self, line):
674 lsplit = line.split()
675 if len(lsplit) == 3 and lsplit[1].lower() == "link":
676 self._setlink(lsplit[0], lsplit[2])
677 elif len(lsplit) == 8:
678 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
679 else:
680 msg = "Fixup Perms: invalid config line %s" % line
681 package_qa_handle_error("perm-config", msg, d)
682 self.path = None
683 self.link = None
684
685 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
686 self.path = os.path.normpath(path)
687 self.link = None
688 self.mode = self._procmode(mode)
689 self.uid = self._procuid(uid)
690 self.gid = self._procgid(gid)
691 self.walk = walk.lower()
692 self.fmode = self._procmode(fmode)
693 self.fuid = self._procuid(fuid)
694 self.fgid = self._procgid(fgid)
695
696 def _setlink(self, path, link):
697 self.path = os.path.normpath(path)
698 self.link = link
699
700 def _procmode(self, mode):
701 if not mode or (mode and mode == "-"):
702 return None
703 else:
704 return int(mode,8)
705
706 # Note uid/gid -1 has special significance in os.lchown
707 def _procuid(self, uid):
708 if uid is None or uid == "-":
709 return -1
710 elif uid.isdigit():
711 return int(uid)
712 else:
713 return pwd.getpwnam(uid).pw_uid
714
715 def _procgid(self, gid):
716 if gid is None or gid == "-":
717 return -1
718 elif gid.isdigit():
719 return int(gid)
720 else:
721 return grp.getgrnam(gid).gr_gid
722
723 # Use for debugging the entries
724 def __str__(self):
725 if self.link:
726 return "%s link %s" % (self.path, self.link)
727 else:
728 mode = "-"
729 if self.mode:
730 mode = "0%o" % self.mode
731 fmode = "-"
732 if self.fmode:
733 fmode = "0%o" % self.fmode
734 uid = self._mapugid(self.uid)
735 gid = self._mapugid(self.gid)
736 fuid = self._mapugid(self.fuid)
737 fgid = self._mapugid(self.fgid)
738 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
739
740 def _mapugid(self, id):
741 if id is None or id == -1:
742 return "-"
743 else:
744 return "%d" % id
745
746 # Fix the permission, owner and group of path
747 def fix_perms(path, mode, uid, gid, dir):
748 if mode and not os.path.islink(path):
749 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
750 os.chmod(path, mode)
751 # -1 is a special value that means don't change the uid/gid
752 # if they are BOTH -1, don't bother to lchown
753 if not (uid == -1 and gid == -1):
754 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
755 os.lchown(path, uid, gid)
756
757 # Return a list of configuration files based on either the default
758 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
759 # paths are resolved via BBPATH
760 def get_fs_perms_list(d):
761 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500762 bbpath = d.getVar('BBPATH')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500763 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500764 for conf_file in fs_perms_tables.split():
765 str += " %s" % bb.utils.which(bbpath, conf_file)
766 return str
767
768
769
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500770 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500771
772 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500773 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500774
775 # By default all of the standard directories specified in
776 # bitbake.conf will get 0755 root:root.
777 target_path_vars = [ 'base_prefix',
778 'prefix',
779 'exec_prefix',
780 'base_bindir',
781 'base_sbindir',
782 'base_libdir',
783 'datadir',
784 'sysconfdir',
785 'servicedir',
786 'sharedstatedir',
787 'localstatedir',
788 'infodir',
789 'mandir',
790 'docdir',
791 'bindir',
792 'sbindir',
793 'libexecdir',
794 'libdir',
795 'includedir',
796 'oldincludedir' ]
797
798 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500799 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500800 if dir == "":
801 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500802 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500803
804 # Now we actually load from the configuration files
805 for conf in get_fs_perms_list(d).split():
806 if os.path.exists(conf):
807 f = open(conf)
808 for line in f:
809 if line.startswith('#'):
810 continue
811 lsplit = line.split()
812 if len(lsplit) == 0:
813 continue
814 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
815 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
816 package_qa_handle_error("perm-line", msg, d)
817 continue
818 entry = fs_perms_entry(d.expand(line))
819 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500820 if entry.link:
821 fs_link_table[entry.path] = entry
822 if entry.path in fs_perms_table:
823 fs_perms_table.pop(entry.path)
824 else:
825 fs_perms_table[entry.path] = entry
826 if entry.path in fs_link_table:
827 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500828 f.close()
829
830 # Debug -- list out in-memory table
831 #for dir in fs_perms_table:
832 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500833 #for link in fs_link_table:
834 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500835
836 # We process links first, so we can go back and fixup directory ownership
837 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500838 # Process in sorted order so /run gets created before /run/lock, etc.
839 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
840 link = entry.link
841 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500842 origin = dvar + dir
843 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
844 continue
845
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500846 if link[0] == "/":
847 target = dvar + link
848 ptarget = link
849 else:
850 target = os.path.join(os.path.dirname(origin), link)
851 ptarget = os.path.join(os.path.dirname(dir), link)
852 if os.path.exists(target):
853 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
854 package_qa_handle_error("perm-link", msg, d)
855 continue
856
857 # Create path to move directory to, move it, and then setup the symlink
858 bb.utils.mkdirhier(os.path.dirname(target))
859 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
860 os.rename(origin, target)
861 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
862 os.symlink(link, origin)
863
864 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500865 origin = dvar + dir
866 if not (cpath.exists(origin) and cpath.isdir(origin)):
867 continue
868
869 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
870
871 if fs_perms_table[dir].walk == 'true':
872 for root, dirs, files in os.walk(origin):
873 for dr in dirs:
874 each_dir = os.path.join(root, dr)
875 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
876 for f in files:
877 each_file = os.path.join(root, f)
878 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
879}
880
881python split_and_strip_files () {
882 import stat, errno
883
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500884 dvar = d.getVar('PKGD')
885 pn = d.getVar('PN')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400886 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500887
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600888 oldcwd = os.getcwd()
889 os.chdir(dvar)
890
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500891 # We default to '.debug' style
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500892 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500893 # Single debug-file-directory style debug info
894 debugappend = ".debug"
895 debugdir = ""
896 debuglibdir = "/usr/lib/debug"
897 debugsrcdir = "/usr/src/debug"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500898 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500899 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
900 debugappend = ""
901 debugdir = "/.debug"
902 debuglibdir = ""
903 debugsrcdir = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500904 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
905 debugappend = ""
906 debugdir = "/.debug"
907 debuglibdir = ""
908 debugsrcdir = "/usr/src/debug"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500909 else:
910 # Original OE-core, a.k.a. ".debug", style debug info
911 debugappend = ""
912 debugdir = "/.debug"
913 debuglibdir = ""
914 debugsrcdir = "/usr/src/debug"
915
916 sourcefile = d.expand("${WORKDIR}/debugsources.list")
917 bb.utils.remove(sourcefile)
918
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500919 # Return type (bits):
920 # 0 - not elf
921 # 1 - ELF
922 # 2 - stripped
923 # 4 - executable
924 # 8 - shared library
925 # 16 - kernel module
926 def isELF(path):
927 type = 0
Brad Bishop316dfdd2018-06-25 12:45:53 -0400928 ret, result = oe.utils.getstatusoutput("file -b '%s'" % path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500929
930 if ret:
931 msg = "split_and_strip_files: 'file %s' failed" % path
932 package_qa_handle_error("split-strip", msg, d)
933 return type
934
935 # Not stripped
936 if "ELF" in result:
937 type |= 1
938 if "not stripped" not in result:
939 type |= 2
940 if "executable" in result:
941 type |= 4
942 if "shared" in result:
943 type |= 8
944 return type
945
Brad Bishop316dfdd2018-06-25 12:45:53 -0400946 def isStaticLib(path):
947 if path.endswith('.a') and not os.path.islink(path):
948 with open(path, 'rb') as fh:
949 # The magic must include the first slash to avoid
950 # matching golang static libraries
951 magic = b'!<arch>\x0a/'
952 start = fh.read(len(magic))
953 return start == magic
954 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500955
956 #
957 # First lets figure out all of the files we may have to process ... do this only once!
958 #
959 elffiles = {}
960 symlinks = {}
961 kernmods = []
Brad Bishop316dfdd2018-06-25 12:45:53 -0400962 staticlibs = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500963 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500964 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
965 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
Brad Bishop316dfdd2018-06-25 12:45:53 -0400966 skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500967 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
968 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500969 for root, dirs, files in cpath.walk(dvar):
970 for f in files:
971 file = os.path.join(root, f)
972 if file.endswith(".ko") and file.find("/lib/modules/") != -1:
973 kernmods.append(file)
974 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -0400975 if isStaticLib(file):
976 staticlibs.append(file)
977 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500978
979 # Skip debug files
980 if debugappend and file.endswith(debugappend):
981 continue
982 if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
983 continue
984
Brad Bishop316dfdd2018-06-25 12:45:53 -0400985 if file in skipfiles:
986 continue
987
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500988 try:
989 ltarget = cpath.realpath(file, dvar, False)
990 s = cpath.lstat(ltarget)
991 except OSError as e:
992 (err, strerror) = e.args
993 if err != errno.ENOENT:
994 raise
995 # Skip broken symlinks
996 continue
997 if not s:
998 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -0400999 # Check its an executable
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001000 if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) or (s[stat.ST_MODE] & stat.S_IXOTH) \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001001 or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001002 # If it's a symlink, and points to an ELF file, we capture the readlink target
1003 if cpath.islink(file):
1004 target = os.readlink(file)
1005 if isELF(ltarget):
1006 #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget)))
1007 symlinks[file] = target
1008 continue
1009
1010 # It's a file (or hardlink), not a link
1011 # ...but is it ELF, and is it already stripped?
1012 elf_file = isELF(file)
1013 if elf_file & 1:
1014 if elf_file & 2:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001015 if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001016 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1017 else:
1018 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
1019 package_qa_handle_error("already-stripped", msg, d)
1020 continue
1021
1022 # At this point we have an unstripped elf file. We need to:
1023 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1024 # b) Only strip any hardlinked file once (no races)
1025 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1026
Brad Bishop316dfdd2018-06-25 12:45:53 -04001027 # Use a reference of device ID and inode number to identify files
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001028 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
1029 if file_reference in inodes:
1030 os.unlink(file)
1031 os.link(inodes[file_reference][0], file)
1032 inodes[file_reference].append(file)
1033 else:
1034 inodes[file_reference] = [file]
1035 # break hardlink
1036 bb.utils.copyfile(file, file)
1037 elffiles[file] = elf_file
1038 # Modified the file so clear the cache
1039 cpath.updatecache(file)
1040
1041 #
1042 # First lets process debug splitting
1043 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001044 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001045 for file in elffiles:
1046 src = file[len(dvar):]
1047 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1048 fpath = dvar + dest
1049
1050 # Split the file...
1051 bb.utils.mkdirhier(os.path.dirname(fpath))
1052 #bb.note("Split %s -> %s" % (file, fpath))
1053 # Only store off the hard link reference if we successfully split!
1054 splitdebuginfo(file, fpath, debugsrcdir, sourcefile, d)
1055
Brad Bishop316dfdd2018-06-25 12:45:53 -04001056 if debugsrcdir and not targetos.startswith("mingw"):
1057 for file in staticlibs:
1058 append_source_info(file, sourcefile, d, fatal=False)
1059
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001060 # Hardlink our debug symbols to the other hardlink copies
1061 for ref in inodes:
1062 if len(inodes[ref]) == 1:
1063 continue
1064 for file in inodes[ref][1:]:
1065 src = file[len(dvar):]
1066 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1067 fpath = dvar + dest
1068 target = inodes[ref][0][len(dvar):]
1069 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1070 bb.utils.mkdirhier(os.path.dirname(fpath))
1071 #bb.note("Link %s -> %s" % (fpath, ftarget))
1072 os.link(ftarget, fpath)
1073
1074 # Create symlinks for all cases we were able to split symbols
1075 for file in symlinks:
1076 src = file[len(dvar):]
1077 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1078 fpath = dvar + dest
1079 # Skip it if the target doesn't exist
1080 try:
1081 s = os.stat(fpath)
1082 except OSError as e:
1083 (err, strerror) = e.args
1084 if err != errno.ENOENT:
1085 raise
1086 continue
1087
1088 ltarget = symlinks[file]
1089 lpath = os.path.dirname(ltarget)
1090 lbase = os.path.basename(ltarget)
1091 ftarget = ""
1092 if lpath and lpath != ".":
1093 ftarget += lpath + debugdir + "/"
1094 ftarget += lbase + debugappend
1095 if lpath.startswith(".."):
1096 ftarget = os.path.join("..", ftarget)
1097 bb.utils.mkdirhier(os.path.dirname(fpath))
1098 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1099 os.symlink(ftarget, fpath)
1100
1101 # Process the debugsrcdir if requested...
1102 # This copies and places the referenced sources for later debugging...
1103 copydebugsources(debugsrcdir, d)
1104 #
1105 # End of debug splitting
1106 #
1107
1108 #
1109 # Now lets go back over things and strip them
1110 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001111 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1112 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001113 sfiles = []
1114 for file in elffiles:
1115 elf_file = int(elffiles[file])
1116 #bb.note("Strip %s" % file)
1117 sfiles.append((file, elf_file, strip))
1118 for f in kernmods:
1119 sfiles.append((f, 16, strip))
1120
1121 oe.utils.multiprocess_exec(sfiles, oe.package.runstrip)
1122
1123 #
1124 # End of strip
1125 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001126 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001127}
1128
1129python populate_packages () {
1130 import glob, re
1131
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001132 workdir = d.getVar('WORKDIR')
1133 outdir = d.getVar('DEPLOY_DIR')
1134 dvar = d.getVar('PKGD')
1135 packages = d.getVar('PACKAGES')
1136 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001137
1138 bb.utils.mkdirhier(outdir)
1139 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001140
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001141 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001142
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001143 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1144
1145 # If debug-with-srcpkg mode is enabled then the src package is added
1146 # into the package list and the source directory as its main content
1147 if split_source_package:
1148 src_package_name = ('%s-src' % d.getVar('PN'))
1149 packages += (' ' + src_package_name)
1150 d.setVar('FILES_%s' % src_package_name, '/usr/src/debug')
1151
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001152 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001153 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001154 package_list = []
1155
1156 for pkg in packages.split():
1157 if pkg in package_list:
1158 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
1159 package_qa_handle_error("packages-list", msg, d)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001160 # If debug-with-srcpkg mode is enabled then the src package will have
1161 # priority over dbg package when assigning the files.
1162 # This allows src package to include source files and remove them from dbg.
1163 elif split_source_package and pkg.endswith("-src"):
1164 package_list.insert(0, pkg)
1165 elif autodebug and pkg.endswith("-dbg") and not split_source_package:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001166 package_list.insert(0, pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001167 else:
1168 package_list.append(pkg)
1169 d.setVar('PACKAGES', ' '.join(package_list))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001170 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001171
1172 seen = []
1173
1174 # os.mkdir masks the permissions with umask so we have to unset it first
1175 oldumask = os.umask(0)
1176
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001177 debug = []
1178 for root, dirs, files in cpath.walk(dvar):
1179 dir = root[len(dvar):]
1180 if not dir:
1181 dir = os.sep
1182 for f in (files + dirs):
1183 path = "." + os.path.join(dir, f)
1184 if "/.debug/" in path or path.endswith("/.debug"):
1185 debug.append(path)
1186
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001187 for pkg in package_list:
1188 root = os.path.join(pkgdest, pkg)
1189 bb.utils.mkdirhier(root)
1190
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001191 filesvar = d.getVar('FILES_%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001192 if "//" in filesvar:
1193 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
1194 package_qa_handle_error("files-invalid", msg, d)
1195 filesvar.replace("//", "/")
1196
1197 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001198 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001199
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001200 if autodebug and pkg.endswith("-dbg"):
1201 files.extend(debug)
1202
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001203 for file in files:
1204 if (not cpath.islink(file)) and (not cpath.exists(file)):
1205 continue
1206 if file in seen:
1207 continue
1208 seen.append(file)
1209
1210 def mkdir(src, dest, p):
1211 src = os.path.join(src, p)
1212 dest = os.path.join(dest, p)
1213 fstat = cpath.stat(src)
1214 os.mkdir(dest, fstat.st_mode)
1215 os.chown(dest, fstat.st_uid, fstat.st_gid)
1216 if p not in seen:
1217 seen.append(p)
1218 cpath.updatecache(dest)
1219
1220 def mkdir_recurse(src, dest, paths):
1221 if cpath.exists(dest + '/' + paths):
1222 return
1223 while paths.startswith("./"):
1224 paths = paths[2:]
1225 p = "."
1226 for c in paths.split("/"):
1227 p = os.path.join(p, c)
1228 if not cpath.exists(os.path.join(dest, p)):
1229 mkdir(src, dest, p)
1230
1231 if cpath.isdir(file) and not cpath.islink(file):
1232 mkdir_recurse(dvar, root, file)
1233 continue
1234
1235 mkdir_recurse(dvar, root, os.path.dirname(file))
1236 fpath = os.path.join(root,file)
1237 if not cpath.islink(file):
1238 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001239 continue
1240 ret = bb.utils.copyfile(file, fpath)
1241 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001242 bb.fatal("File population failed")
1243
1244 # Check if symlink paths exist
1245 for file in symlink_paths:
1246 if not os.path.exists(os.path.join(root,file)):
1247 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1248 "parent directory structure does not exist. One of "
1249 "its parent directories is a symlink whose target "
1250 "directory is not included in the package." %
1251 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001252
1253 os.umask(oldumask)
1254 os.chdir(workdir)
1255
1256 # Handle LICENSE_EXCLUSION
1257 package_list = []
1258 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001259 if d.getVar('LICENSE_EXCLUSION-' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001260 msg = "%s has an incompatible license. Excluding from packaging." % pkg
1261 package_qa_handle_error("incompatible-license", msg, d)
1262 else:
1263 package_list.append(pkg)
1264 d.setVar('PACKAGES', ' '.join(package_list))
1265
1266 unshipped = []
1267 for root, dirs, files in cpath.walk(dvar):
1268 dir = root[len(dvar):]
1269 if not dir:
1270 dir = os.sep
1271 for f in (files + dirs):
1272 path = os.path.join(dir, f)
1273 if ('.' + path) not in seen:
1274 unshipped.append(path)
1275
1276 if unshipped != []:
1277 msg = pn + ": Files/directories were installed but not shipped in any package:"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001278 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001279 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1280 else:
1281 for f in unshipped:
1282 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001283 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"
1284 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001285 package_qa_handle_error("installed-vs-shipped", msg, d)
1286}
1287populate_packages[dirs] = "${D}"
1288
1289python package_fixsymlinks () {
1290 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001291 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001292 packages = d.getVar("PACKAGES", False).split()
1293
1294 dangling_links = {}
1295 pkg_files = {}
1296 for pkg in packages:
1297 dangling_links[pkg] = []
1298 pkg_files[pkg] = []
1299 inst_root = os.path.join(pkgdest, pkg)
1300 for path in pkgfiles[pkg]:
1301 rpath = path[len(inst_root):]
1302 pkg_files[pkg].append(rpath)
1303 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1304 if not cpath.lexists(rtarget):
1305 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1306
1307 newrdepends = {}
1308 for pkg in dangling_links:
1309 for l in dangling_links[pkg]:
1310 found = False
1311 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1312 for p in packages:
1313 if l in pkg_files[p]:
1314 found = True
1315 bb.debug(1, "target found in %s" % p)
1316 if p == pkg:
1317 break
1318 if pkg not in newrdepends:
1319 newrdepends[pkg] = []
1320 newrdepends[pkg].append(p)
1321 break
1322 if found == False:
1323 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1324
1325 for pkg in newrdepends:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001326 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001327 for p in newrdepends[pkg]:
1328 if p not in rdepends:
1329 rdepends[p] = []
1330 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1331}
1332
1333
1334python package_package_name_hook() {
1335 """
1336 A package_name_hook function can be used to rewrite the package names by
1337 changing PKG. For an example, see debian.bbclass.
1338 """
1339 pass
1340}
1341
1342EXPORT_FUNCTIONS package_name_hook
1343
1344
1345PKGDESTWORK = "${WORKDIR}/pkgdata"
1346
1347python emit_pkgdata() {
1348 from glob import glob
1349 import json
1350
Brad Bishop316dfdd2018-06-25 12:45:53 -04001351 def process_postinst_on_target(pkg, mlprefix):
1352 defer_fragment = """
1353if [ -n "$D" ]; then
1354 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1355 exit 0
1356fi
1357""" % (pkg, mlprefix)
1358
1359 postinst = d.getVar('pkg_postinst_%s' % pkg)
1360 postinst_ontarget = d.getVar('pkg_postinst_ontarget_%s' % pkg)
1361
1362 if postinst_ontarget:
1363 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1364 if not postinst:
1365 postinst = '#!/bin/sh\n'
1366 postinst += defer_fragment
1367 postinst += postinst_ontarget
1368 d.setVar('pkg_postinst_%s' % pkg, postinst)
1369
1370 def add_set_e_to_scriptlets(pkg):
1371 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
1372 scriptlet = d.getVar('%s_%s' % (scriptlet_name, pkg))
1373 if scriptlet:
1374 scriptlet_split = scriptlet.split('\n')
1375 if scriptlet_split[0].startswith("#!"):
1376 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1377 else:
1378 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
1379 d.setVar('%s_%s' % (scriptlet_name, pkg), scriptlet)
1380
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001381 def write_if_exists(f, pkg, var):
1382 def encode(str):
1383 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001384 c = codecs.getencoder("unicode_escape")
1385 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001386
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001387 val = d.getVar('%s_%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001388 if val:
1389 f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
1390 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001391 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001392 if val:
1393 f.write('%s: %s\n' % (var, encode(val)))
1394 return val
1395
1396 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1397 for variant in variants:
1398 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1399 fd.write("PACKAGES: %s\n" % ' '.join(
1400 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1401
1402 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1403 for variant in variants:
1404 for pkg in packages.split():
1405 ml_pkg = "%s-%s" % (variant, pkg)
1406 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1407 with open(subdata_file, 'w') as fd:
1408 fd.write("PKG_%s: %s" % (ml_pkg, pkg))
1409
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001410 packages = d.getVar('PACKAGES')
1411 pkgdest = d.getVar('PKGDEST')
1412 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001413
1414 # Take shared lock since we're only reading, not writing
1415 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1416
1417 data_file = pkgdatadir + d.expand("/${PN}" )
1418 f = open(data_file, 'w')
1419 f.write("PACKAGES: %s\n" % packages)
1420 f.close()
1421
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001422 pn = d.getVar('PN')
1423 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1424 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001425
1426 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1427 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1428
1429 if (bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d)):
1430 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1431
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001432 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001433
1434 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001435 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001436 if pkgval is None:
1437 pkgval = pkg
1438 d.setVar('PKG_%s' % pkg, pkg)
1439
1440 pkgdestpkg = os.path.join(pkgdest, pkg)
1441 files = {}
1442 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001443 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001444 for f in pkgfiles[pkg]:
1445 relpth = os.path.relpath(f, pkgdestpkg)
1446 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001447 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001448 if fstat.st_ino not in seen:
1449 seen.add(fstat.st_ino)
1450 total_size += fstat.st_size
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001451 d.setVar('FILES_INFO', json.dumps(files))
1452
1453 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1454 sf = open(subdata_file, 'w')
1455 write_if_exists(sf, pkg, 'PN')
1456 write_if_exists(sf, pkg, 'PE')
1457 write_if_exists(sf, pkg, 'PV')
1458 write_if_exists(sf, pkg, 'PR')
1459 write_if_exists(sf, pkg, 'PKGE')
1460 write_if_exists(sf, pkg, 'PKGV')
1461 write_if_exists(sf, pkg, 'PKGR')
1462 write_if_exists(sf, pkg, 'LICENSE')
1463 write_if_exists(sf, pkg, 'DESCRIPTION')
1464 write_if_exists(sf, pkg, 'SUMMARY')
1465 write_if_exists(sf, pkg, 'RDEPENDS')
1466 rprov = write_if_exists(sf, pkg, 'RPROVIDES')
1467 write_if_exists(sf, pkg, 'RRECOMMENDS')
1468 write_if_exists(sf, pkg, 'RSUGGESTS')
1469 write_if_exists(sf, pkg, 'RREPLACES')
1470 write_if_exists(sf, pkg, 'RCONFLICTS')
1471 write_if_exists(sf, pkg, 'SECTION')
1472 write_if_exists(sf, pkg, 'PKG')
1473 write_if_exists(sf, pkg, 'ALLOW_EMPTY')
1474 write_if_exists(sf, pkg, 'FILES')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001475 write_if_exists(sf, pkg, 'CONFFILES')
Brad Bishop316dfdd2018-06-25 12:45:53 -04001476 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1477 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001478 write_if_exists(sf, pkg, 'pkg_postinst')
1479 write_if_exists(sf, pkg, 'pkg_postrm')
1480 write_if_exists(sf, pkg, 'pkg_preinst')
1481 write_if_exists(sf, pkg, 'pkg_prerm')
1482 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1483 write_if_exists(sf, pkg, 'FILES_INFO')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001484 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001485 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1486
1487 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001488 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001489 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1490
1491 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
1492 sf.close()
1493
1494 # Symlinks needed for rprovides lookup
1495 if rprov:
1496 for p in rprov.strip().split():
1497 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1498 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1499 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1500
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001501 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001502 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001503 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001504 root = "%s/%s" % (pkgdest, pkg)
1505 os.chdir(root)
1506 g = glob('*')
1507 if g or allow_empty == "1":
1508 # Symlinks needed for reverse lookups (from the final package name)
1509 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1510 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1511
1512 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1513 open(packagedfile, 'w').close()
1514
1515 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1516 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1517
1518 if bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d):
1519 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1520
1521 bb.utils.unlockfile(lf)
1522}
1523emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1524
1525ldconfig_postinst_fragment() {
1526if [ x"$D" = "x" ]; then
1527 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1528fi
1529}
1530
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001531RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001532
1533# Collect perfile run-time dependency metadata
1534# Output:
1535# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1536# FILERPROVIDES_filepath_pkg - per file dep
1537#
1538# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1539# FILERDEPENDS_filepath_pkg - per file dep
1540
1541python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001542 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001543 return
1544
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001545 pkgdest = d.getVar('PKGDEST')
1546 packages = d.getVar('PACKAGES')
1547 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001548
1549 def chunks(files, n):
1550 return [files[i:i+n] for i in range(0, len(files), n)]
1551
1552 pkglist = []
1553 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001554 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001555 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001556 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 -05001557 continue
1558 for files in chunks(pkgfiles[pkg], 100):
1559 pkglist.append((pkg, files, rpmdeps, pkgdest))
1560
1561 processed = oe.utils.multiprocess_exec( pkglist, oe.package.filedeprunner)
1562
1563 provides_files = {}
1564 requires_files = {}
1565
1566 for result in processed:
1567 (pkg, provides, requires) = result
1568
1569 if pkg not in provides_files:
1570 provides_files[pkg] = []
1571 if pkg not in requires_files:
1572 requires_files[pkg] = []
1573
1574 for file in provides:
1575 provides_files[pkg].append(file)
1576 key = "FILERPROVIDES_" + file + "_" + pkg
1577 d.setVar(key, " ".join(provides[file]))
1578
1579 for file in requires:
1580 requires_files[pkg].append(file)
1581 key = "FILERDEPENDS_" + file + "_" + pkg
1582 d.setVar(key, " ".join(requires[file]))
1583
1584 for pkg in requires_files:
1585 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1586 for pkg in provides_files:
1587 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1588}
1589
1590SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs2"
1591SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1592
1593python package_do_shlibs() {
1594 import re, pipes
1595 import subprocess as sub
1596
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001597 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001598 if exclude_shlibs:
1599 bb.note("not generating shlibs")
1600 return
1601
1602 lib_re = re.compile("^.*\.so")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001603 libdir_re = re.compile(".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001604
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001605 packages = d.getVar('PACKAGES')
1606 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001607
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001608 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001609
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001610 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001611 if not ver:
1612 msg = "PKGV not defined"
1613 package_qa_handle_error("pkgv-undefined", msg, d)
1614 return
1615
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001616 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001617
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001618 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001619
1620 # Take shared lock since we're only reading, not writing
Brad Bishop316dfdd2018-06-25 12:45:53 -04001621 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001622
1623 def linux_so(file, needed, sonames, renames, pkgver):
1624 needs_ldconfig = False
1625 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001626 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001627 fd = os.popen(cmd)
1628 lines = fd.readlines()
1629 fd.close()
1630 rpath = []
1631 for l in lines:
1632 m = re.match("\s+RPATH\s+([^\s]*)", l)
1633 if m:
1634 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001635 rpath = list(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001636 for l in lines:
1637 m = re.match("\s+NEEDED\s+([^\s]*)", l)
1638 if m:
1639 dep = m.group(1)
1640 if dep not in needed[pkg]:
1641 needed[pkg].append((dep, file, rpath))
1642 m = re.match("\s+SONAME\s+([^\s]*)", l)
1643 if m:
1644 this_soname = m.group(1)
1645 prov = (this_soname, ldir, pkgver)
1646 if not prov in sonames:
1647 # if library is private (only used by package) then do not build shlib for it
1648 if not private_libs or this_soname not in private_libs:
1649 sonames.append(prov)
1650 if libdir_re.match(os.path.dirname(file)):
1651 needs_ldconfig = True
1652 if snap_symlinks and (os.path.basename(file) != this_soname):
1653 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
1654 return needs_ldconfig
1655
1656 def darwin_so(file, needed, sonames, renames, pkgver):
1657 if not os.path.exists(file):
1658 return
1659 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1660
1661 def get_combinations(base):
1662 #
1663 # Given a base library name, find all combinations of this split by "." and "-"
1664 #
1665 combos = []
1666 options = base.split(".")
1667 for i in range(1, len(options) + 1):
1668 combos.append(".".join(options[0:i]))
1669 options = base.split("-")
1670 for i in range(1, len(options) + 1):
1671 combos.append("-".join(options[0:i]))
1672 return combos
1673
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001674 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 -05001675 # Drop suffix
1676 name = os.path.basename(file).rsplit(".",1)[0]
1677 # Find all combinations
1678 combos = get_combinations(name)
1679 for combo in combos:
1680 if not combo in sonames:
1681 prov = (combo, ldir, pkgver)
1682 sonames.append(prov)
1683 if file.endswith('.dylib') or file.endswith('.so'):
1684 rpath = []
1685 p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file],stdout=sub.PIPE,stderr=sub.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001686 out, err = p.communicate()
1687 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001688 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001689 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001690 l = l.strip()
1691 if l.startswith('path '):
1692 rpath.append(l.split()[1])
1693
1694 p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file],stdout=sub.PIPE,stderr=sub.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001695 out, err = p.communicate()
1696 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001697 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001698 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001699 l = l.strip()
1700 if not l or l.endswith(":"):
1701 continue
1702 if "is not an object file" in l:
1703 continue
1704 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1705 if name and name not in needed[pkg]:
1706 needed[pkg].append((name, file, []))
1707
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001708 def mingw_dll(file, needed, sonames, renames, pkgver):
1709 if not os.path.exists(file):
1710 return
1711
1712 if file.endswith(".dll"):
1713 # assume all dlls are shared objects provided by the package
1714 sonames.append((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
1715
1716 if (file.endswith(".dll") or file.endswith(".exe")):
1717 # use objdump to search for "DLL Name: .*\.dll"
1718 p = sub.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout = sub.PIPE, stderr= sub.PIPE)
1719 out, err = p.communicate()
1720 # process the output, grabbing all .dll names
1721 if p.returncode == 0:
1722 for m in re.finditer("DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
1723 dllname = m.group(1)
1724 if dllname:
1725 needed[pkg].append((dllname, file, []))
1726
1727 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001728 snap_symlinks = True
1729 else:
1730 snap_symlinks = False
1731
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001732 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001733
1734 needed = {}
1735 shlib_provider = oe.package.read_shlib_providers(d)
1736
1737 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001738 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001739 private_libs = private_libs.split()
1740 needs_ldconfig = False
1741 bb.debug(2, "calculating shlib provides for %s" % pkg)
1742
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001743 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001744 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001745 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001746 if not pkgver:
1747 pkgver = ver
1748
1749 needed[pkg] = []
1750 sonames = list()
1751 renames = list()
1752 for file in pkgfiles[pkg]:
1753 soname = None
1754 if cpath.islink(file):
1755 continue
1756 if targetos == "darwin" or targetos == "darwin8":
1757 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001758 elif targetos.startswith("mingw"):
1759 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001760 elif os.access(file, os.X_OK) or lib_re.match(file):
1761 ldconfig = linux_so(file, needed, sonames, renames, pkgver)
1762 needs_ldconfig = needs_ldconfig or ldconfig
1763 for (old, new) in renames:
1764 bb.note("Renaming %s to %s" % (old, new))
1765 os.rename(old, new)
1766 pkgfiles[pkg].remove(old)
1767
1768 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1769 if len(sonames):
1770 fd = open(shlibs_file, 'w')
1771 for s in sonames:
1772 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1773 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1774 if old_pkg != pkg:
1775 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))
1776 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1777 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1778 if s[0] not in shlib_provider:
1779 shlib_provider[s[0]] = {}
1780 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1781 fd.close()
1782 if needs_ldconfig and use_ldconfig:
1783 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001784 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001785 if not postinst:
1786 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001787 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001788 d.setVar('pkg_postinst_%s' % pkg, postinst)
1789 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1790
1791 bb.utils.unlockfile(lf)
1792
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001793 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001794 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001795 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001796 for e in assumed_libs.split():
1797 l, dep_pkg = e.split(":")
1798 lib_ver = None
1799 dep_pkg = dep_pkg.rsplit("_", 1)
1800 if len(dep_pkg) == 2:
1801 lib_ver = dep_pkg[1]
1802 dep_pkg = dep_pkg[0]
1803 if l not in shlib_provider:
1804 shlib_provider[l] = {}
1805 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1806
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001807 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001808
1809 for pkg in packages.split():
1810 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1811
Brad Bishop316dfdd2018-06-25 12:45:53 -04001812 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
1813 private_libs = private_libs.split()
1814
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001815 deps = list()
1816 for n in needed[pkg]:
1817 # if n is in private libraries, don't try to search provider for it
1818 # this could cause problem in case some abc.bb provides private
1819 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1820 # but skipping it is still better alternative than providing own
1821 # version and then adding runtime dependency for the same system library
1822 if private_libs and n[0] in private_libs:
1823 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1824 continue
1825 if n[0] in shlib_provider.keys():
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001826 shlib_provider_path = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001827 for k in shlib_provider[n[0]].keys():
1828 shlib_provider_path.append(k)
1829 match = None
1830 for p in n[2] + shlib_provider_path + libsearchpath:
1831 if p in shlib_provider[n[0]]:
1832 match = p
1833 break
1834 if match:
1835 (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
1836
1837 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1838
1839 if dep_pkg == pkg:
1840 continue
1841
1842 if ver_needed:
1843 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1844 else:
1845 dep = dep_pkg
1846 if not dep in deps:
1847 deps.append(dep)
1848 continue
1849 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1850
1851 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1852 if os.path.exists(deps_file):
1853 os.remove(deps_file)
1854 if len(deps):
1855 fd = open(deps_file, 'w')
1856 for dep in deps:
1857 fd.write(dep + '\n')
1858 fd.close()
1859}
1860
1861python package_do_pkgconfig () {
1862 import re
1863
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001864 packages = d.getVar('PACKAGES')
1865 workdir = d.getVar('WORKDIR')
1866 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001867
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001868 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1869 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001870
1871 pc_re = re.compile('(.*)\.pc$')
1872 var_re = re.compile('(.*)=(.*)')
1873 field_re = re.compile('(.*): (.*)')
1874
1875 pkgconfig_provided = {}
1876 pkgconfig_needed = {}
1877 for pkg in packages.split():
1878 pkgconfig_provided[pkg] = []
1879 pkgconfig_needed[pkg] = []
1880 for file in pkgfiles[pkg]:
1881 m = pc_re.match(file)
1882 if m:
1883 pd = bb.data.init()
1884 name = m.group(1)
1885 pkgconfig_provided[pkg].append(name)
1886 if not os.access(file, os.R_OK):
1887 continue
1888 f = open(file, 'r')
1889 lines = f.readlines()
1890 f.close()
1891 for l in lines:
1892 m = var_re.match(l)
1893 if m:
1894 name = m.group(1)
1895 val = m.group(2)
1896 pd.setVar(name, pd.expand(val))
1897 continue
1898 m = field_re.match(l)
1899 if m:
1900 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001901 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001902 if hdr == 'Requires':
1903 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1904
1905 # Take shared lock since we're only reading, not writing
Brad Bishop316dfdd2018-06-25 12:45:53 -04001906 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001907
1908 for pkg in packages.split():
1909 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1910 if pkgconfig_provided[pkg] != []:
1911 f = open(pkgs_file, 'w')
1912 for p in pkgconfig_provided[pkg]:
1913 f.write('%s\n' % p)
1914 f.close()
1915
1916 # Go from least to most specific since the last one found wins
1917 for dir in reversed(shlibs_dirs):
1918 if not os.path.exists(dir):
1919 continue
1920 for file in os.listdir(dir):
1921 m = re.match('^(.*)\.pclist$', file)
1922 if m:
1923 pkg = m.group(1)
1924 fd = open(os.path.join(dir, file))
1925 lines = fd.readlines()
1926 fd.close()
1927 pkgconfig_provided[pkg] = []
1928 for l in lines:
1929 pkgconfig_provided[pkg].append(l.rstrip())
1930
1931 for pkg in packages.split():
1932 deps = []
1933 for n in pkgconfig_needed[pkg]:
1934 found = False
1935 for k in pkgconfig_provided.keys():
1936 if n in pkgconfig_provided[k]:
1937 if k != pkg and not (k in deps):
1938 deps.append(k)
1939 found = True
1940 if found == False:
1941 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1942 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1943 if len(deps):
1944 fd = open(deps_file, 'w')
1945 for dep in deps:
1946 fd.write(dep + '\n')
1947 fd.close()
1948
1949 bb.utils.unlockfile(lf)
1950}
1951
1952def read_libdep_files(d):
1953 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001954 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001955 for pkg in packages:
1956 pkglibdeps[pkg] = {}
1957 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1958 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1959 if os.access(depsfile, os.R_OK):
1960 fd = open(depsfile)
1961 lines = fd.readlines()
1962 fd.close()
1963 for l in lines:
1964 l.rstrip()
1965 deps = bb.utils.explode_dep_versions2(l)
1966 for dep in deps:
1967 if not dep in pkglibdeps[pkg]:
1968 pkglibdeps[pkg][dep] = deps[dep]
1969 return pkglibdeps
1970
1971python read_shlibdeps () {
1972 pkglibdeps = read_libdep_files(d)
1973
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001974 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001975 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001976 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001977 for dep in pkglibdeps[pkg]:
1978 # Add the dep if it's not already there, or if no comparison is set
1979 if dep not in rdepends:
1980 rdepends[dep] = []
1981 for v in pkglibdeps[pkg][dep]:
1982 if v not in rdepends[dep]:
1983 rdepends[dep].append(v)
1984 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1985}
1986
1987python package_depchains() {
1988 """
1989 For a given set of prefix and postfix modifiers, make those packages
1990 RRECOMMENDS on the corresponding packages for its RDEPENDS.
1991
1992 Example: If package A depends upon package B, and A's .bb emits an
1993 A-dev package, this would make A-dev Recommends: B-dev.
1994
1995 If only one of a given suffix is specified, it will take the RRECOMMENDS
1996 based on the RDEPENDS of *all* other packages. If more than one of a given
1997 suffix is specified, its will only use the RDEPENDS of the single parent
1998 package.
1999 """
2000
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002001 packages = d.getVar('PACKAGES')
2002 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2003 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002004
2005 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2006
2007 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002008 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002009
2010 for depend in depends:
2011 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2012 #bb.note("Skipping %s" % depend)
2013 continue
2014 if depend.endswith('-dev'):
2015 depend = depend[:-4]
2016 if depend.endswith('-dbg'):
2017 depend = depend[:-4]
2018 pkgname = getname(depend, suffix)
2019 #bb.note("Adding %s for %s" % (pkgname, depend))
2020 if pkgname not in rreclist and pkgname != pkg:
2021 rreclist[pkgname] = []
2022
2023 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2024 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2025
2026 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2027
2028 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002029 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002030
2031 for depend in rdepends:
2032 if depend.find('virtual-locale-') != -1:
2033 #bb.note("Skipping %s" % depend)
2034 continue
2035 if depend.endswith('-dev'):
2036 depend = depend[:-4]
2037 if depend.endswith('-dbg'):
2038 depend = depend[:-4]
2039 pkgname = getname(depend, suffix)
2040 #bb.note("Adding %s for %s" % (pkgname, depend))
2041 if pkgname not in rreclist and pkgname != pkg:
2042 rreclist[pkgname] = []
2043
2044 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2045 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2046
2047 def add_dep(list, dep):
2048 if dep not in list:
2049 list.append(dep)
2050
2051 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002052 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002053 add_dep(depends, dep)
2054
2055 rdepends = []
2056 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002057 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002058 add_dep(rdepends, dep)
2059
2060 #bb.note('rdepends is %s' % rdepends)
2061
2062 def post_getname(name, suffix):
2063 return '%s%s' % (name, suffix)
2064 def pre_getname(name, suffix):
2065 return '%s%s' % (suffix, name)
2066
2067 pkgs = {}
2068 for pkg in packages.split():
2069 for postfix in postfixes:
2070 if pkg.endswith(postfix):
2071 if not postfix in pkgs:
2072 pkgs[postfix] = {}
2073 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2074
2075 for prefix in prefixes:
2076 if pkg.startswith(prefix):
2077 if not prefix in pkgs:
2078 pkgs[prefix] = {}
2079 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2080
2081 if "-dbg" in pkgs:
2082 pkglibdeps = read_libdep_files(d)
2083 pkglibdeplist = []
2084 for pkg in pkglibdeps:
2085 for k in pkglibdeps[pkg]:
2086 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002087 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002088
2089 for suffix in pkgs:
2090 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002091 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002092 continue
2093 (base, func) = pkgs[suffix][pkg]
2094 if suffix == "-dev":
2095 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2096 elif suffix == "-dbg":
2097 if not dbgdefaultdeps:
2098 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2099 continue
2100 if len(pkgs[suffix]) == 1:
2101 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2102 else:
2103 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002104 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002105 add_dep(rdeps, dep)
2106 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2107}
2108
2109# Since bitbake can't determine which variables are accessed during package
2110# iteration, we need to list them here:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002111PACKAGEVARS = "FILES RDEPENDS RRECOMMENDS SUMMARY DESCRIPTION RSUGGESTS RPROVIDES RCONFLICTS PKG ALLOW_EMPTY pkg_postinst pkg_postrm 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"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002112
2113def gen_packagevar(d):
2114 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002115 pkgs = (d.getVar("PACKAGES") or "").split()
2116 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002117 for p in pkgs:
2118 for v in vars:
2119 ret.append(v + "_" + p)
2120
2121 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2122 # affected recipes.
2123 ret.append('LICENSE_EXCLUSION-%s' % p)
2124 return " ".join(ret)
2125
2126PACKAGE_PREPROCESS_FUNCS ?= ""
2127# Functions for setting up PKGD
2128PACKAGEBUILDPKGD ?= " \
2129 perform_packagecopy \
2130 ${PACKAGE_PREPROCESS_FUNCS} \
2131 split_and_strip_files \
2132 fixup_perms \
2133 "
2134# Functions which split PKGD up into separate packages
2135PACKAGESPLITFUNCS ?= " \
2136 package_do_split_locales \
2137 populate_packages"
2138# Functions which process metadata based on split packages
2139PACKAGEFUNCS += " \
2140 package_fixsymlinks \
2141 package_name_hook \
2142 package_do_filedeps \
2143 package_do_shlibs \
2144 package_do_pkgconfig \
2145 read_shlibdeps \
2146 package_depchains \
2147 emit_pkgdata"
2148
2149python do_package () {
2150 # Change the following version to cause sstate to invalidate the package
2151 # cache. This is useful if an item this class depends on changes in a
2152 # way that the output of this class changes. rpmdeps is a good example
2153 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002154 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002155
2156 # Init cachedpath
2157 global cpath
2158 cpath = oe.cachedpath.CachedPath()
2159
2160 ###########################################################################
2161 # Sanity test the setup
2162 ###########################################################################
2163
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002164 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002165 if len(packages) < 1:
2166 bb.debug(1, "No packages to build, skipping do_package")
2167 return
2168
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002169 workdir = d.getVar('WORKDIR')
2170 outdir = d.getVar('DEPLOY_DIR')
2171 dest = d.getVar('D')
2172 dvar = d.getVar('PKGD')
2173 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002174
2175 if not workdir or not outdir or not dest or not dvar or not pn:
2176 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2177 package_qa_handle_error("var-undefined", msg, d)
2178 return
2179
2180 bb.build.exec_func("package_get_auto_pr", d)
2181
2182 ###########################################################################
2183 # Optimisations
2184 ###########################################################################
2185
2186 # Continually expanding complex expressions is inefficient, particularly
2187 # when we write to the datastore and invalidate the expansion cache. This
2188 # code pre-expands some frequently used variables
2189
2190 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002191 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002192
2193 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2194 expandVar(x, d)
2195
2196 ###########################################################################
2197 # Setup PKGD (from D)
2198 ###########################################################################
2199
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002200 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002201 bb.build.exec_func(f, d)
2202
2203 ###########################################################################
2204 # Split up PKGD into PKGDEST
2205 ###########################################################################
2206
2207 cpath = oe.cachedpath.CachedPath()
2208
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002209 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002210 bb.build.exec_func(f, d)
2211
2212 ###########################################################################
2213 # Process PKGDEST
2214 ###########################################################################
2215
2216 # Build global list of files in each split package
2217 global pkgfiles
2218 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002219 packages = d.getVar('PACKAGES').split()
2220 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002221 for pkg in packages:
2222 pkgfiles[pkg] = []
2223 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2224 for file in files:
2225 pkgfiles[pkg].append(walkroot + os.sep + file)
2226
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002227 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002228 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002229
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002230 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002231 if not qa_sane:
2232 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002233}
2234
2235do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2236do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2237addtask package after do_install
2238
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002239SSTATETASKS += "do_package"
2240do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2241do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002242do_package_setscene[dirs] = "${STAGING_DIR}"
2243
2244python do_package_setscene () {
2245 sstate_setscene(d)
2246}
2247addtask do_package_setscene
2248
2249do_packagedata () {
2250 :
2251}
2252
2253addtask packagedata before do_build after do_package
2254
2255SSTATETASKS += "do_packagedata"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002256# PACKAGELOCK protects readers of PKGDATA_DIR against writes
2257# whilst code is reading in do_package
2258PACKAGELOCK = "${STAGING_DIR}/package-output.lock"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002259do_packagedata[sstate-inputdirs] = "${PKGDESTWORK}"
2260do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002261do_packagedata[sstate-lockfile] = "${PACKAGELOCK}"
2262do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002263
2264python do_packagedata_setscene () {
2265 sstate_setscene(d)
2266}
2267addtask do_packagedata_setscene
2268
2269#
2270# Helper functions for the package writing classes
2271#
2272
2273def mapping_rename_hook(d):
2274 """
2275 Rewrite variables to account for package renaming in things
2276 like debian.bbclass or manual PKG variable name changes
2277 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002278 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002279 runtime_mapping_rename("RDEPENDS", pkg, d)
2280 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2281 runtime_mapping_rename("RSUGGESTS", pkg, d)