blob: a03c05b9f7a1ebe4bcf9823fb1a996a75df97c61 [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
29# depenedencies found. Also stores the package name so anyone else using this library
30# 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
55PACKAGE_DEPENDS += "rpm-native"
56
Brad Bishop6e60e8b2018-02-01 10:27:11 -050057
58# If your postinstall can execute at rootfs creation time rather than on
59# target but depends on a native/cross tool in order to execute, you need to
60# list that tool in PACKAGE_WRITE_DEPENDS. Target package dependencies belong
61# in the package dependencies as normal, this is just for native/cross support
62# tools at rootfs build time.
63PACKAGE_WRITE_DEPS ??= ""
64
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065def legitimize_package_name(s):
66 """
67 Make sure package names are legitimate strings
68 """
69 import re
70
71 def fixutf(m):
72 cp = m.group(1)
73 if cp:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060074 return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075
76 # Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
77 s = re.sub('<U([0-9A-Fa-f]{1,4})>', fixutf, s)
78
79 # Remaining package name validity fixes
80 return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
81
82def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None, allow_links=False, summary=None):
83 """
84 Used in .bb files to split up dynamically generated subpackages of a
85 given package, usually plugins or modules.
86
87 Arguments:
88 root -- the path in which to search
89 file_regex -- regular expression to match searched files. Use
90 parentheses () to mark the part of this expression
91 that should be used to derive the module name (to be
92 substituted where %s is used in other function
93 arguments as noted below)
94 output_pattern -- pattern to use for the package names. Must include %s.
95 description -- description to set for each package. Must include %s.
96 postinst -- postinstall script to use for all packages (as a
97 string)
98 recursive -- True to perform a recursive search - default False
99 hook -- a hook function to be called for every match. The
100 function will be called with the following arguments
101 (in the order listed):
102 f: full path to the file/directory match
103 pkg: the package name
104 file_regex: as above
105 output_pattern: as above
106 modulename: the module name derived using file_regex
107 extra_depends -- extra runtime dependencies (RDEPENDS) to be set for
108 all packages. The default value of None causes a
109 dependency on the main package (${PN}) - if you do
110 not want this, pass '' for this parameter.
111 aux_files_pattern -- extra item(s) to be added to FILES for each
112 package. Can be a single string item or a list of
113 strings for multiple items. Must include %s.
114 postrm -- postrm script to use for all packages (as a string)
115 allow_dirs -- True allow directories to be matched - default False
116 prepend -- if True, prepend created packages to PACKAGES instead
117 of the default False which appends them
118 match_path -- match file_regex on the whole relative path to the
119 root rather than just the file name
120 aux_files_pattern_verbatim -- extra item(s) to be added to FILES for
121 each package, using the actual derived module name
122 rather than converting it to something legal for a
123 package name. Can be a single string item or a list
124 of strings for multiple items. Must include %s.
125 allow_links -- True to allow symlinks to be matched - default False
126 summary -- Summary to set for each package. Must include %s;
127 defaults to description if not set.
128
129 """
130
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500131 dvar = d.getVar('PKGD')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500132 root = d.expand(root)
133 output_pattern = d.expand(output_pattern)
134 extra_depends = d.expand(extra_depends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135
136 # If the root directory doesn't exist, don't error out later but silently do
137 # no splitting.
138 if not os.path.exists(dvar + root):
139 return []
140
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500141 ml = d.getVar("MLPREFIX")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 if ml:
143 if not output_pattern.startswith(ml):
144 output_pattern = ml + output_pattern
145
146 newdeps = []
147 for dep in (extra_depends or "").split():
148 if dep.startswith(ml):
149 newdeps.append(dep)
150 else:
151 newdeps.append(ml + dep)
152 if newdeps:
153 extra_depends = " ".join(newdeps)
154
155
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500156 packages = d.getVar('PACKAGES').split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600157 split_packages = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158
159 if postinst:
160 postinst = '#!/bin/sh\n' + postinst + '\n'
161 if postrm:
162 postrm = '#!/bin/sh\n' + postrm + '\n'
163 if not recursive:
164 objs = os.listdir(dvar + root)
165 else:
166 objs = []
167 for walkroot, dirs, files in os.walk(dvar + root):
168 for file in files:
169 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
170 if relpath:
171 objs.append(relpath)
172
173 if extra_depends == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500174 extra_depends = d.getVar("PN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500175
176 if not summary:
177 summary = description
178
179 for o in sorted(objs):
180 import re, stat
181 if match_path:
182 m = re.match(file_regex, o)
183 else:
184 m = re.match(file_regex, os.path.basename(o))
185
186 if not m:
187 continue
188 f = os.path.join(dvar + root, o)
189 mode = os.lstat(f).st_mode
190 if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))):
191 continue
192 on = legitimize_package_name(m.group(1))
193 pkg = output_pattern % on
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600194 split_packages.add(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 if not pkg in packages:
196 if prepend:
197 packages = [pkg] + packages
198 else:
199 packages.append(pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500200 oldfiles = d.getVar('FILES_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500201 newfile = os.path.join(root, o)
202 # These names will be passed through glob() so if the filename actually
203 # contains * or ? (rare, but possible) we need to handle that specially
204 newfile = newfile.replace('*', '[*]')
205 newfile = newfile.replace('?', '[?]')
206 if not oldfiles:
207 the_files = [newfile]
208 if aux_files_pattern:
209 if type(aux_files_pattern) is list:
210 for fp in aux_files_pattern:
211 the_files.append(fp % on)
212 else:
213 the_files.append(aux_files_pattern % on)
214 if aux_files_pattern_verbatim:
215 if type(aux_files_pattern_verbatim) is list:
216 for fp in aux_files_pattern_verbatim:
217 the_files.append(fp % m.group(1))
218 else:
219 the_files.append(aux_files_pattern_verbatim % m.group(1))
220 d.setVar('FILES_' + pkg, " ".join(the_files))
221 else:
222 d.setVar('FILES_' + pkg, oldfiles + " " + newfile)
223 if extra_depends != '':
224 d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500225 if not d.getVar('DESCRIPTION_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500226 d.setVar('DESCRIPTION_' + pkg, description % on)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500227 if not d.getVar('SUMMARY_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500228 d.setVar('SUMMARY_' + pkg, summary % on)
229 if postinst:
230 d.setVar('pkg_postinst_' + pkg, postinst)
231 if postrm:
232 d.setVar('pkg_postrm_' + pkg, postrm)
233 if callable(hook):
234 hook(f, pkg, file_regex, output_pattern, m.group(1))
235
236 d.setVar('PACKAGES', ' '.join(packages))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600237 return list(split_packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238
239PACKAGE_DEPENDS += "file-native"
240
241python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500242 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500243 deps = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500244 for dep in (d.getVar('PACKAGE_DEPENDS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500245 deps += " %s:do_populate_sysroot" % dep
246 d.appendVarFlag('do_package', 'depends', deps)
247
248 # shlibs requires any DEPENDS to have already packaged for the *.list files
249 d.appendVarFlag('do_package', 'deptask', " do_packagedata")
250}
251
252# Get a list of files from file vars by searching files under current working directory
253# The list contains symlinks, directories and normal files.
254def files_from_filevars(filevars):
255 import os,glob
256 cpath = oe.cachedpath.CachedPath()
257 files = []
258 for f in filevars:
259 if os.path.isabs(f):
260 f = '.' + f
261 if not f.startswith("./"):
262 f = './' + f
263 globbed = glob.glob(f)
264 if globbed:
265 if [ f ] != globbed:
266 files += globbed
267 continue
268 files.append(f)
269
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600270 symlink_paths = []
271 for ind, f in enumerate(files):
272 # Handle directory symlinks. Truncate path to the lowest level symlink
273 parent = ''
274 for dirname in f.split('/')[:-1]:
275 parent = os.path.join(parent, dirname)
276 if dirname == '.':
277 continue
278 if cpath.islink(parent):
279 bb.warn("FILES contains file '%s' which resides under a "
280 "directory symlink. Please fix the recipe and use the "
281 "real path for the file." % f[1:])
282 symlink_paths.append(f)
283 files[ind] = parent
284 f = parent
285 break
286
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500287 if not cpath.islink(f):
288 if cpath.isdir(f):
289 newfiles = [ os.path.join(f,x) for x in os.listdir(f) ]
290 if newfiles:
291 files += newfiles
292
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600293 return files, symlink_paths
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500294
295# Called in package_<rpm,ipk,deb>.bbclass to get the correct list of configuration files
296def get_conffiles(pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500297 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500298 root = os.path.join(pkgdest, pkg)
299 cwd = os.getcwd()
300 os.chdir(root)
301
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500302 conffiles = d.getVar('CONFFILES_%s' % pkg);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500303 if conffiles == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500304 conffiles = d.getVar('CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500305 if conffiles == None:
306 conffiles = ""
307 conffiles = conffiles.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600308 conf_orig_list = files_from_filevars(conffiles)[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500309
310 # Remove links and directories from conf_orig_list to get conf_list which only contains normal files
311 conf_list = []
312 for f in conf_orig_list:
313 if os.path.isdir(f):
314 continue
315 if os.path.islink(f):
316 continue
317 if not os.path.exists(f):
318 continue
319 conf_list.append(f)
320
321 # Remove the leading './'
322 for i in range(0, len(conf_list)):
323 conf_list[i] = conf_list[i][1:]
324
325 os.chdir(cwd)
326 return conf_list
327
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500328def checkbuildpath(file, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500329 tmpdir = d.getVar('TMPDIR')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500330 with open(file) as f:
331 file_content = f.read()
332 if tmpdir in file_content:
333 return True
334
335 return False
336
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500337def splitdebuginfo(file, debugfile, debugsrcdir, sourcefile, d):
338 # Function to split a single file into two components, one is the stripped
339 # target system binary, the other contains any debugging information. The
340 # two files are linked to reference each other.
341 #
342 # sourcefile is also generated containing a list of debugsources
343
344 import stat
345
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500346 dvar = d.getVar('PKGD')
347 objcopy = d.getVar("OBJCOPY")
348 debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/debugedit")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500349
350 # We ignore kernel modules, we don't generate debug info files.
351 if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
352 return 1
353
354 newmode = None
355 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
356 origmode = os.stat(file)[stat.ST_MODE]
357 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
358 os.chmod(file, newmode)
359
360 # We need to extract the debug src information here...
361 if debugsrcdir:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500362 cmd = "'%s' -i -l '%s' '%s'" % (debugedit, sourcefile, file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500363 (retval, output) = oe.utils.getstatusoutput(cmd)
364 if retval:
365 bb.fatal("debugedit failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
366
367 bb.utils.mkdirhier(os.path.dirname(debugfile))
368
369 cmd = "'%s' --only-keep-debug '%s' '%s'" % (objcopy, file, debugfile)
370 (retval, output) = oe.utils.getstatusoutput(cmd)
371 if retval:
372 bb.fatal("objcopy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
373
374 # Set the debuglink to have the view of the file path on the target
375 cmd = "'%s' --add-gnu-debuglink='%s' '%s'" % (objcopy, debugfile, file)
376 (retval, output) = oe.utils.getstatusoutput(cmd)
377 if retval:
378 bb.fatal("objcopy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
379
380 if newmode:
381 os.chmod(file, origmode)
382
383 return 0
384
385def copydebugsources(debugsrcdir, d):
386 # The debug src information written out to sourcefile is further procecessed
387 # and copied to the destination here.
388
389 import stat
390
391 sourcefile = d.expand("${WORKDIR}/debugsources.list")
392 if debugsrcdir and os.path.isfile(sourcefile):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500393 dvar = d.getVar('PKGD')
394 strip = d.getVar("STRIP")
395 objcopy = d.getVar("OBJCOPY")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500396 debugedit = d.expand("${STAGING_LIBDIR_NATIVE}/rpm/bin/debugedit")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500397 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500398 workparentdir = os.path.dirname(os.path.dirname(workdir))
399 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
400
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500401 # If build path exists in sourcefile, it means toolchain did not use
402 # -fdebug-prefix-map to compile
403 if checkbuildpath(sourcefile, d):
404 localsrc_prefix = workparentdir + "/"
405 else:
406 localsrc_prefix = "/usr/src/debug/"
407
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500408 nosuchdir = []
409 basepath = dvar
410 for p in debugsrcdir.split("/"):
411 basepath = basepath + "/" + p
412 if not cpath.exists(basepath):
413 nosuchdir.append(basepath)
414 bb.utils.mkdirhier(basepath)
415 cpath.updatecache(basepath)
416
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500417 # Ignore files from the recipe sysroots (target and native)
418 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500419 # We need to ignore files that are not actually ours
420 # we do this by only paying attention to items from this package
421 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500422 # Remove prefix in the source paths
423 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500424 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
425
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500426 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500427 (retval, output) = oe.utils.getstatusoutput(cmd)
428 # Can "fail" if internal headers/transient sources are attempted
429 #if retval:
430 # bb.fatal("debug source copy failed with exit code %s (cmd was %s)" % (retval, cmd))
431
432 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
433 # Work around this by manually finding and copying any symbolic links that made it through.
434 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)
435 (retval, output) = oe.utils.getstatusoutput(cmd)
436 if retval:
437 bb.fatal("debugsrc symlink fixup failed with exit code %s (cmd was %s)" % (retval, cmd))
438
439 # The copy by cpio may have resulted in some empty directories! Remove these
440 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
441 (retval, output) = oe.utils.getstatusoutput(cmd)
442 if retval:
443 bb.fatal("empty directory removal failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
444
445 # Also remove debugsrcdir if its empty
446 for p in nosuchdir[::-1]:
447 if os.path.exists(p) and not os.listdir(p):
448 os.rmdir(p)
449
450#
451# Package data handling routines
452#
453
454def get_package_mapping (pkg, basepkg, d):
455 import oe.packagedata
456
457 data = oe.packagedata.read_subpkgdata(pkg, d)
458 key = "PKG_%s" % pkg
459
460 if key in data:
461 # Have to avoid undoing the write_extra_pkgs(global_variants...)
462 if bb.data.inherits_class('allarch', d) and data[key] == basepkg:
463 return pkg
464 return data[key]
465
466 return pkg
467
468def get_package_additional_metadata (pkg_type, d):
469 base_key = "PACKAGE_ADD_METADATA"
470 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
471 if d.getVar(key, False) is None:
472 continue
473 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500474 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500475 d.setVarFlag(key, "separator", "\\n")
476 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
477 return "\n".join(metadata_fields).strip()
478
479def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500480 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500481
482 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500483 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500484 for depend in deps:
485 new_depend = get_package_mapping(depend, pkg, d)
486 new_depends[new_depend] = deps[depend]
487
488 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
489
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500490 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500491
492#
493# Package functions suitable for inclusion in PACKAGEFUNCS
494#
495
496python package_get_auto_pr() {
497 import oe.prservice
498 import re
499
500 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500501 pn = d.getVar('PN')
502 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500503 if not (host is None):
504 d.setVar("PRSERV_HOST", host)
505
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500506 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500507
508 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500509 if not d.getVar('PRSERV_HOST'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500510 if 'AUTOINC' in pkgv:
511 d.setVar("PKGV", pkgv.replace("AUTOINC", "0"))
512 return
513
514 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500515 pv = d.getVar("PV")
516 version = d.getVar("PRAUTOINX")
517 pkgarch = d.getVar("PACKAGE_ARCH")
518 checksum = d.getVar("BB_TASKHASH")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500519
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500520 if d.getVar('PRSERV_LOCKDOWN'):
521 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500522 if auto_pr is None:
523 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
524 d.setVar('PRAUTO',str(auto_pr))
525 return
526
527 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500528 conn = d.getVar("__PRSERV_CONN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500529 if conn is None:
530 conn = oe.prservice.prserv_make_conn(d)
531 if conn is not None:
532 if "AUTOINC" in pkgv:
533 srcpv = bb.fetch2.get_srcrev(d)
534 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
535 value = conn.getPR(base_ver, pkgarch, srcpv)
536 d.setVar("PKGV", pkgv.replace("AUTOINC", str(value)))
537
538 auto_pr = conn.getPR(version, pkgarch, checksum)
539 except Exception as e:
540 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
541 if auto_pr is None:
542 bb.fatal("Can NOT get PRAUTO from remote PR service")
543 d.setVar('PRAUTO',str(auto_pr))
544}
545
546LOCALEBASEPN ??= "${PN}"
547
548python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500549 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550 bb.debug(1, "package requested not splitting locales")
551 return
552
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500553 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500554
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500555 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556 if not datadir:
557 bb.note("datadir not defined")
558 return
559
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500560 dvar = d.getVar('PKGD')
561 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500562
563 if pn + '-locale' in packages:
564 packages.remove(pn + '-locale')
565
566 localedir = os.path.join(dvar + datadir, 'locale')
567
568 if not cpath.isdir(localedir):
569 bb.debug(1, "No locale files in this package")
570 return
571
572 locales = os.listdir(localedir)
573
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500574 summary = d.getVar('SUMMARY') or pn
575 description = d.getVar('DESCRIPTION') or ""
576 locale_section = d.getVar('LOCALE_SECTION')
577 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500578 for l in sorted(locales):
579 ln = legitimize_package_name(l)
580 pkg = pn + '-locale-' + ln
581 packages.append(pkg)
582 d.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l))
583 d.setVar('RRECOMMENDS_' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
584 d.setVar('RPROVIDES_' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
585 d.setVar('SUMMARY_' + pkg, '%s - %s translations' % (summary, l))
586 d.setVar('DESCRIPTION_' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
587 if locale_section:
588 d.setVar('SECTION_' + pkg, locale_section)
589
590 d.setVar('PACKAGES', ' '.join(packages))
591
592 # Disabled by RP 18/06/07
593 # Wildcards aren't supported in debian
594 # They break with ipkg since glibc-locale* will mean that
595 # glibc-localedata-translit* won't install as a dependency
596 # for some other package which breaks meta-toolchain
597 # Probably breaks since virtual-locale- isn't provided anywhere
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500598 #rdep = (d.getVar('RDEPENDS_%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500599 #rdep.append('%s-locale*' % pn)
600 #d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep))
601}
602
603python perform_packagecopy () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500604 dest = d.getVar('D')
605 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500606
607 # Start by package population by taking a copy of the installed
608 # files to operate on
609 # Preserve sparse files and hard links
610 cmd = 'tar -cf - -C %s -p . | tar -xf - -C %s' % (dest, dvar)
611 (retval, output) = oe.utils.getstatusoutput(cmd)
612 if retval:
613 bb.fatal("file copy failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else ""))
614
615 # replace RPATHs for the nativesdk binaries, to make them relocatable
616 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
617 rpath_replace (dvar, d)
618}
619perform_packagecopy[cleandirs] = "${PKGD}"
620perform_packagecopy[dirs] = "${PKGD}"
621
622# We generate a master list of directories to process, we start by
623# seeding this list with reasonable defaults, then load from
624# the fs-perms.txt files
625python fixup_perms () {
626 import pwd, grp
627
628 # init using a string with the same format as a line as documented in
629 # the fs-perms.txt file
630 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
631 # <path> link <link target>
632 #
633 # __str__ can be used to print out an entry in the input format
634 #
635 # if fs_perms_entry.path is None:
636 # an error occured
637 # if fs_perms_entry.link, you can retrieve:
638 # fs_perms_entry.path = path
639 # fs_perms_entry.link = target of link
640 # if not fs_perms_entry.link, you can retrieve:
641 # fs_perms_entry.path = path
642 # fs_perms_entry.mode = expected dir mode or None
643 # fs_perms_entry.uid = expected uid or -1
644 # fs_perms_entry.gid = expected gid or -1
645 # fs_perms_entry.walk = 'true' or something else
646 # fs_perms_entry.fmode = expected file mode or None
647 # fs_perms_entry.fuid = expected file uid or -1
648 # fs_perms_entry_fgid = expected file gid or -1
649 class fs_perms_entry():
650 def __init__(self, line):
651 lsplit = line.split()
652 if len(lsplit) == 3 and lsplit[1].lower() == "link":
653 self._setlink(lsplit[0], lsplit[2])
654 elif len(lsplit) == 8:
655 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
656 else:
657 msg = "Fixup Perms: invalid config line %s" % line
658 package_qa_handle_error("perm-config", msg, d)
659 self.path = None
660 self.link = None
661
662 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
663 self.path = os.path.normpath(path)
664 self.link = None
665 self.mode = self._procmode(mode)
666 self.uid = self._procuid(uid)
667 self.gid = self._procgid(gid)
668 self.walk = walk.lower()
669 self.fmode = self._procmode(fmode)
670 self.fuid = self._procuid(fuid)
671 self.fgid = self._procgid(fgid)
672
673 def _setlink(self, path, link):
674 self.path = os.path.normpath(path)
675 self.link = link
676
677 def _procmode(self, mode):
678 if not mode or (mode and mode == "-"):
679 return None
680 else:
681 return int(mode,8)
682
683 # Note uid/gid -1 has special significance in os.lchown
684 def _procuid(self, uid):
685 if uid is None or uid == "-":
686 return -1
687 elif uid.isdigit():
688 return int(uid)
689 else:
690 return pwd.getpwnam(uid).pw_uid
691
692 def _procgid(self, gid):
693 if gid is None or gid == "-":
694 return -1
695 elif gid.isdigit():
696 return int(gid)
697 else:
698 return grp.getgrnam(gid).gr_gid
699
700 # Use for debugging the entries
701 def __str__(self):
702 if self.link:
703 return "%s link %s" % (self.path, self.link)
704 else:
705 mode = "-"
706 if self.mode:
707 mode = "0%o" % self.mode
708 fmode = "-"
709 if self.fmode:
710 fmode = "0%o" % self.fmode
711 uid = self._mapugid(self.uid)
712 gid = self._mapugid(self.gid)
713 fuid = self._mapugid(self.fuid)
714 fgid = self._mapugid(self.fgid)
715 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
716
717 def _mapugid(self, id):
718 if id is None or id == -1:
719 return "-"
720 else:
721 return "%d" % id
722
723 # Fix the permission, owner and group of path
724 def fix_perms(path, mode, uid, gid, dir):
725 if mode and not os.path.islink(path):
726 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
727 os.chmod(path, mode)
728 # -1 is a special value that means don't change the uid/gid
729 # if they are BOTH -1, don't bother to lchown
730 if not (uid == -1 and gid == -1):
731 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
732 os.lchown(path, uid, gid)
733
734 # Return a list of configuration files based on either the default
735 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
736 # paths are resolved via BBPATH
737 def get_fs_perms_list(d):
738 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500739 bbpath = d.getVar('BBPATH')
740 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500741 if not fs_perms_tables:
742 fs_perms_tables = 'files/fs-perms.txt'
743 for conf_file in fs_perms_tables.split():
744 str += " %s" % bb.utils.which(bbpath, conf_file)
745 return str
746
747
748
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500749 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750
751 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500752 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500753
754 # By default all of the standard directories specified in
755 # bitbake.conf will get 0755 root:root.
756 target_path_vars = [ 'base_prefix',
757 'prefix',
758 'exec_prefix',
759 'base_bindir',
760 'base_sbindir',
761 'base_libdir',
762 'datadir',
763 'sysconfdir',
764 'servicedir',
765 'sharedstatedir',
766 'localstatedir',
767 'infodir',
768 'mandir',
769 'docdir',
770 'bindir',
771 'sbindir',
772 'libexecdir',
773 'libdir',
774 'includedir',
775 'oldincludedir' ]
776
777 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500778 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500779 if dir == "":
780 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500781 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500782
783 # Now we actually load from the configuration files
784 for conf in get_fs_perms_list(d).split():
785 if os.path.exists(conf):
786 f = open(conf)
787 for line in f:
788 if line.startswith('#'):
789 continue
790 lsplit = line.split()
791 if len(lsplit) == 0:
792 continue
793 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
794 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
795 package_qa_handle_error("perm-line", msg, d)
796 continue
797 entry = fs_perms_entry(d.expand(line))
798 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500799 if entry.link:
800 fs_link_table[entry.path] = entry
801 if entry.path in fs_perms_table:
802 fs_perms_table.pop(entry.path)
803 else:
804 fs_perms_table[entry.path] = entry
805 if entry.path in fs_link_table:
806 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500807 f.close()
808
809 # Debug -- list out in-memory table
810 #for dir in fs_perms_table:
811 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500812 #for link in fs_link_table:
813 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500814
815 # We process links first, so we can go back and fixup directory ownership
816 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500817 # Process in sorted order so /run gets created before /run/lock, etc.
818 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
819 link = entry.link
820 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500821 origin = dvar + dir
822 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
823 continue
824
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500825 if link[0] == "/":
826 target = dvar + link
827 ptarget = link
828 else:
829 target = os.path.join(os.path.dirname(origin), link)
830 ptarget = os.path.join(os.path.dirname(dir), link)
831 if os.path.exists(target):
832 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
833 package_qa_handle_error("perm-link", msg, d)
834 continue
835
836 # Create path to move directory to, move it, and then setup the symlink
837 bb.utils.mkdirhier(os.path.dirname(target))
838 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
839 os.rename(origin, target)
840 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
841 os.symlink(link, origin)
842
843 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500844 origin = dvar + dir
845 if not (cpath.exists(origin) and cpath.isdir(origin)):
846 continue
847
848 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
849
850 if fs_perms_table[dir].walk == 'true':
851 for root, dirs, files in os.walk(origin):
852 for dr in dirs:
853 each_dir = os.path.join(root, dr)
854 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
855 for f in files:
856 each_file = os.path.join(root, f)
857 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
858}
859
860python split_and_strip_files () {
861 import stat, errno
862
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500863 dvar = d.getVar('PKGD')
864 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500865
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600866 oldcwd = os.getcwd()
867 os.chdir(dvar)
868
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 # We default to '.debug' style
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500870 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500871 # Single debug-file-directory style debug info
872 debugappend = ".debug"
873 debugdir = ""
874 debuglibdir = "/usr/lib/debug"
875 debugsrcdir = "/usr/src/debug"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500876 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500877 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
878 debugappend = ""
879 debugdir = "/.debug"
880 debuglibdir = ""
881 debugsrcdir = ""
882 else:
883 # Original OE-core, a.k.a. ".debug", style debug info
884 debugappend = ""
885 debugdir = "/.debug"
886 debuglibdir = ""
887 debugsrcdir = "/usr/src/debug"
888
889 sourcefile = d.expand("${WORKDIR}/debugsources.list")
890 bb.utils.remove(sourcefile)
891
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500892 # Return type (bits):
893 # 0 - not elf
894 # 1 - ELF
895 # 2 - stripped
896 # 4 - executable
897 # 8 - shared library
898 # 16 - kernel module
899 def isELF(path):
900 type = 0
901 ret, result = oe.utils.getstatusoutput("file \"%s\"" % path.replace("\"", "\\\""))
902
903 if ret:
904 msg = "split_and_strip_files: 'file %s' failed" % path
905 package_qa_handle_error("split-strip", msg, d)
906 return type
907
908 # Not stripped
909 if "ELF" in result:
910 type |= 1
911 if "not stripped" not in result:
912 type |= 2
913 if "executable" in result:
914 type |= 4
915 if "shared" in result:
916 type |= 8
917 return type
918
919
920 #
921 # First lets figure out all of the files we may have to process ... do this only once!
922 #
923 elffiles = {}
924 symlinks = {}
925 kernmods = []
926 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500927 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
928 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
929 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
930 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500931 for root, dirs, files in cpath.walk(dvar):
932 for f in files:
933 file = os.path.join(root, f)
934 if file.endswith(".ko") and file.find("/lib/modules/") != -1:
935 kernmods.append(file)
936 continue
937
938 # Skip debug files
939 if debugappend and file.endswith(debugappend):
940 continue
941 if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
942 continue
943
944 try:
945 ltarget = cpath.realpath(file, dvar, False)
946 s = cpath.lstat(ltarget)
947 except OSError as e:
948 (err, strerror) = e.args
949 if err != errno.ENOENT:
950 raise
951 # Skip broken symlinks
952 continue
953 if not s:
954 continue
955 # Check its an excutable
956 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 -0500957 or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500958 # If it's a symlink, and points to an ELF file, we capture the readlink target
959 if cpath.islink(file):
960 target = os.readlink(file)
961 if isELF(ltarget):
962 #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget)))
963 symlinks[file] = target
964 continue
965
966 # It's a file (or hardlink), not a link
967 # ...but is it ELF, and is it already stripped?
968 elf_file = isELF(file)
969 if elf_file & 1:
970 if elf_file & 2:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500971 if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500972 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
973 else:
974 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
975 package_qa_handle_error("already-stripped", msg, d)
976 continue
977
978 # At this point we have an unstripped elf file. We need to:
979 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
980 # b) Only strip any hardlinked file once (no races)
981 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
982
983 # Use a reference of device ID and inode number to indentify files
984 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
985 if file_reference in inodes:
986 os.unlink(file)
987 os.link(inodes[file_reference][0], file)
988 inodes[file_reference].append(file)
989 else:
990 inodes[file_reference] = [file]
991 # break hardlink
992 bb.utils.copyfile(file, file)
993 elffiles[file] = elf_file
994 # Modified the file so clear the cache
995 cpath.updatecache(file)
996
997 #
998 # First lets process debug splitting
999 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001000 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001001 for file in elffiles:
1002 src = file[len(dvar):]
1003 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1004 fpath = dvar + dest
1005
1006 # Split the file...
1007 bb.utils.mkdirhier(os.path.dirname(fpath))
1008 #bb.note("Split %s -> %s" % (file, fpath))
1009 # Only store off the hard link reference if we successfully split!
1010 splitdebuginfo(file, fpath, debugsrcdir, sourcefile, d)
1011
1012 # Hardlink our debug symbols to the other hardlink copies
1013 for ref in inodes:
1014 if len(inodes[ref]) == 1:
1015 continue
1016 for file in inodes[ref][1:]:
1017 src = file[len(dvar):]
1018 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1019 fpath = dvar + dest
1020 target = inodes[ref][0][len(dvar):]
1021 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1022 bb.utils.mkdirhier(os.path.dirname(fpath))
1023 #bb.note("Link %s -> %s" % (fpath, ftarget))
1024 os.link(ftarget, fpath)
1025
1026 # Create symlinks for all cases we were able to split symbols
1027 for file in symlinks:
1028 src = file[len(dvar):]
1029 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1030 fpath = dvar + dest
1031 # Skip it if the target doesn't exist
1032 try:
1033 s = os.stat(fpath)
1034 except OSError as e:
1035 (err, strerror) = e.args
1036 if err != errno.ENOENT:
1037 raise
1038 continue
1039
1040 ltarget = symlinks[file]
1041 lpath = os.path.dirname(ltarget)
1042 lbase = os.path.basename(ltarget)
1043 ftarget = ""
1044 if lpath and lpath != ".":
1045 ftarget += lpath + debugdir + "/"
1046 ftarget += lbase + debugappend
1047 if lpath.startswith(".."):
1048 ftarget = os.path.join("..", ftarget)
1049 bb.utils.mkdirhier(os.path.dirname(fpath))
1050 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1051 os.symlink(ftarget, fpath)
1052
1053 # Process the debugsrcdir if requested...
1054 # This copies and places the referenced sources for later debugging...
1055 copydebugsources(debugsrcdir, d)
1056 #
1057 # End of debug splitting
1058 #
1059
1060 #
1061 # Now lets go back over things and strip them
1062 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001063 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1064 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001065 sfiles = []
1066 for file in elffiles:
1067 elf_file = int(elffiles[file])
1068 #bb.note("Strip %s" % file)
1069 sfiles.append((file, elf_file, strip))
1070 for f in kernmods:
1071 sfiles.append((f, 16, strip))
1072
1073 oe.utils.multiprocess_exec(sfiles, oe.package.runstrip)
1074
1075 #
1076 # End of strip
1077 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001078 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001079}
1080
1081python populate_packages () {
1082 import glob, re
1083
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001084 workdir = d.getVar('WORKDIR')
1085 outdir = d.getVar('DEPLOY_DIR')
1086 dvar = d.getVar('PKGD')
1087 packages = d.getVar('PACKAGES')
1088 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001089
1090 bb.utils.mkdirhier(outdir)
1091 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001092
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001093 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001094
1095 # Sanity check PACKAGES for duplicates
1096 # Sanity should be moved to sanity.bbclass once we have the infrastucture
1097 package_list = []
1098
1099 for pkg in packages.split():
1100 if pkg in package_list:
1101 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
1102 package_qa_handle_error("packages-list", msg, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001103 elif autodebug and pkg.endswith("-dbg"):
1104 package_list.insert(0, pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001105 else:
1106 package_list.append(pkg)
1107 d.setVar('PACKAGES', ' '.join(package_list))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001108 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001109
1110 seen = []
1111
1112 # os.mkdir masks the permissions with umask so we have to unset it first
1113 oldumask = os.umask(0)
1114
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001115 debug = []
1116 for root, dirs, files in cpath.walk(dvar):
1117 dir = root[len(dvar):]
1118 if not dir:
1119 dir = os.sep
1120 for f in (files + dirs):
1121 path = "." + os.path.join(dir, f)
1122 if "/.debug/" in path or path.endswith("/.debug"):
1123 debug.append(path)
1124
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001125 for pkg in package_list:
1126 root = os.path.join(pkgdest, pkg)
1127 bb.utils.mkdirhier(root)
1128
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001129 filesvar = d.getVar('FILES_%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001130 if "//" in filesvar:
1131 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
1132 package_qa_handle_error("files-invalid", msg, d)
1133 filesvar.replace("//", "/")
1134
1135 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001136 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001137
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001138 if autodebug and pkg.endswith("-dbg"):
1139 files.extend(debug)
1140
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001141 for file in files:
1142 if (not cpath.islink(file)) and (not cpath.exists(file)):
1143 continue
1144 if file in seen:
1145 continue
1146 seen.append(file)
1147
1148 def mkdir(src, dest, p):
1149 src = os.path.join(src, p)
1150 dest = os.path.join(dest, p)
1151 fstat = cpath.stat(src)
1152 os.mkdir(dest, fstat.st_mode)
1153 os.chown(dest, fstat.st_uid, fstat.st_gid)
1154 if p not in seen:
1155 seen.append(p)
1156 cpath.updatecache(dest)
1157
1158 def mkdir_recurse(src, dest, paths):
1159 if cpath.exists(dest + '/' + paths):
1160 return
1161 while paths.startswith("./"):
1162 paths = paths[2:]
1163 p = "."
1164 for c in paths.split("/"):
1165 p = os.path.join(p, c)
1166 if not cpath.exists(os.path.join(dest, p)):
1167 mkdir(src, dest, p)
1168
1169 if cpath.isdir(file) and not cpath.islink(file):
1170 mkdir_recurse(dvar, root, file)
1171 continue
1172
1173 mkdir_recurse(dvar, root, os.path.dirname(file))
1174 fpath = os.path.join(root,file)
1175 if not cpath.islink(file):
1176 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001177 continue
1178 ret = bb.utils.copyfile(file, fpath)
1179 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001180 bb.fatal("File population failed")
1181
1182 # Check if symlink paths exist
1183 for file in symlink_paths:
1184 if not os.path.exists(os.path.join(root,file)):
1185 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1186 "parent directory structure does not exist. One of "
1187 "its parent directories is a symlink whose target "
1188 "directory is not included in the package." %
1189 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001190
1191 os.umask(oldumask)
1192 os.chdir(workdir)
1193
1194 # Handle LICENSE_EXCLUSION
1195 package_list = []
1196 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001197 if d.getVar('LICENSE_EXCLUSION-' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001198 msg = "%s has an incompatible license. Excluding from packaging." % pkg
1199 package_qa_handle_error("incompatible-license", msg, d)
1200 else:
1201 package_list.append(pkg)
1202 d.setVar('PACKAGES', ' '.join(package_list))
1203
1204 unshipped = []
1205 for root, dirs, files in cpath.walk(dvar):
1206 dir = root[len(dvar):]
1207 if not dir:
1208 dir = os.sep
1209 for f in (files + dirs):
1210 path = os.path.join(dir, f)
1211 if ('.' + path) not in seen:
1212 unshipped.append(path)
1213
1214 if unshipped != []:
1215 msg = pn + ": Files/directories were installed but not shipped in any package:"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001216 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001217 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1218 else:
1219 for f in unshipped:
1220 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001221 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"
1222 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001223 package_qa_handle_error("installed-vs-shipped", msg, d)
1224}
1225populate_packages[dirs] = "${D}"
1226
1227python package_fixsymlinks () {
1228 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001229 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001230 packages = d.getVar("PACKAGES", False).split()
1231
1232 dangling_links = {}
1233 pkg_files = {}
1234 for pkg in packages:
1235 dangling_links[pkg] = []
1236 pkg_files[pkg] = []
1237 inst_root = os.path.join(pkgdest, pkg)
1238 for path in pkgfiles[pkg]:
1239 rpath = path[len(inst_root):]
1240 pkg_files[pkg].append(rpath)
1241 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1242 if not cpath.lexists(rtarget):
1243 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1244
1245 newrdepends = {}
1246 for pkg in dangling_links:
1247 for l in dangling_links[pkg]:
1248 found = False
1249 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1250 for p in packages:
1251 if l in pkg_files[p]:
1252 found = True
1253 bb.debug(1, "target found in %s" % p)
1254 if p == pkg:
1255 break
1256 if pkg not in newrdepends:
1257 newrdepends[pkg] = []
1258 newrdepends[pkg].append(p)
1259 break
1260 if found == False:
1261 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1262
1263 for pkg in newrdepends:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001264 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001265 for p in newrdepends[pkg]:
1266 if p not in rdepends:
1267 rdepends[p] = []
1268 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1269}
1270
1271
1272python package_package_name_hook() {
1273 """
1274 A package_name_hook function can be used to rewrite the package names by
1275 changing PKG. For an example, see debian.bbclass.
1276 """
1277 pass
1278}
1279
1280EXPORT_FUNCTIONS package_name_hook
1281
1282
1283PKGDESTWORK = "${WORKDIR}/pkgdata"
1284
1285python emit_pkgdata() {
1286 from glob import glob
1287 import json
1288
1289 def write_if_exists(f, pkg, var):
1290 def encode(str):
1291 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001292 c = codecs.getencoder("unicode_escape")
1293 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001294
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001295 val = d.getVar('%s_%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001296 if val:
1297 f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
1298 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001299 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001300 if val:
1301 f.write('%s: %s\n' % (var, encode(val)))
1302 return val
1303
1304 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1305 for variant in variants:
1306 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1307 fd.write("PACKAGES: %s\n" % ' '.join(
1308 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1309
1310 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1311 for variant in variants:
1312 for pkg in packages.split():
1313 ml_pkg = "%s-%s" % (variant, pkg)
1314 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1315 with open(subdata_file, 'w') as fd:
1316 fd.write("PKG_%s: %s" % (ml_pkg, pkg))
1317
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001318 packages = d.getVar('PACKAGES')
1319 pkgdest = d.getVar('PKGDEST')
1320 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001321
1322 # Take shared lock since we're only reading, not writing
1323 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1324
1325 data_file = pkgdatadir + d.expand("/${PN}" )
1326 f = open(data_file, 'w')
1327 f.write("PACKAGES: %s\n" % packages)
1328 f.close()
1329
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001330 pn = d.getVar('PN')
1331 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1332 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001333
1334 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1335 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1336
1337 if (bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d)):
1338 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1339
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001340 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001341
1342 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001343 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001344 if pkgval is None:
1345 pkgval = pkg
1346 d.setVar('PKG_%s' % pkg, pkg)
1347
1348 pkgdestpkg = os.path.join(pkgdest, pkg)
1349 files = {}
1350 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001351 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001352 for f in pkgfiles[pkg]:
1353 relpth = os.path.relpath(f, pkgdestpkg)
1354 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001355 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001356 if fstat.st_ino not in seen:
1357 seen.add(fstat.st_ino)
1358 total_size += fstat.st_size
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001359 d.setVar('FILES_INFO', json.dumps(files))
1360
1361 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1362 sf = open(subdata_file, 'w')
1363 write_if_exists(sf, pkg, 'PN')
1364 write_if_exists(sf, pkg, 'PE')
1365 write_if_exists(sf, pkg, 'PV')
1366 write_if_exists(sf, pkg, 'PR')
1367 write_if_exists(sf, pkg, 'PKGE')
1368 write_if_exists(sf, pkg, 'PKGV')
1369 write_if_exists(sf, pkg, 'PKGR')
1370 write_if_exists(sf, pkg, 'LICENSE')
1371 write_if_exists(sf, pkg, 'DESCRIPTION')
1372 write_if_exists(sf, pkg, 'SUMMARY')
1373 write_if_exists(sf, pkg, 'RDEPENDS')
1374 rprov = write_if_exists(sf, pkg, 'RPROVIDES')
1375 write_if_exists(sf, pkg, 'RRECOMMENDS')
1376 write_if_exists(sf, pkg, 'RSUGGESTS')
1377 write_if_exists(sf, pkg, 'RREPLACES')
1378 write_if_exists(sf, pkg, 'RCONFLICTS')
1379 write_if_exists(sf, pkg, 'SECTION')
1380 write_if_exists(sf, pkg, 'PKG')
1381 write_if_exists(sf, pkg, 'ALLOW_EMPTY')
1382 write_if_exists(sf, pkg, 'FILES')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001383 write_if_exists(sf, pkg, 'CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001384 write_if_exists(sf, pkg, 'pkg_postinst')
1385 write_if_exists(sf, pkg, 'pkg_postrm')
1386 write_if_exists(sf, pkg, 'pkg_preinst')
1387 write_if_exists(sf, pkg, 'pkg_prerm')
1388 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1389 write_if_exists(sf, pkg, 'FILES_INFO')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001390 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001391 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1392
1393 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001394 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001395 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1396
1397 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
1398 sf.close()
1399
1400 # Symlinks needed for rprovides lookup
1401 if rprov:
1402 for p in rprov.strip().split():
1403 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1404 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1405 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1406
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001407 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001408 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001409 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001410 root = "%s/%s" % (pkgdest, pkg)
1411 os.chdir(root)
1412 g = glob('*')
1413 if g or allow_empty == "1":
1414 # Symlinks needed for reverse lookups (from the final package name)
1415 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1416 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1417
1418 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1419 open(packagedfile, 'w').close()
1420
1421 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1422 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1423
1424 if bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d):
1425 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1426
1427 bb.utils.unlockfile(lf)
1428}
1429emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1430
1431ldconfig_postinst_fragment() {
1432if [ x"$D" = "x" ]; then
1433 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1434fi
1435}
1436
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001437# In Morty and earlier releases, and on master (Rocko), the RPM file
1438# dependencies are always enabled. However, since they were broken with the
1439# release of Pyro and enabling them may cause build problems for some packages,
1440# they are not enabled by default in Pyro. Setting ENABLE_RPM_FILEDEPS_FOR_PYRO
1441# to "1" will enable them again.
1442ENABLE_RPM_FILEDEPS_FOR_PYRO ??= "0"
1443RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps${@' --alldeps' if d.getVar('ENABLE_RPM_FILEDEPS_FOR_PYRO') == '1' else ''}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001444
1445# Collect perfile run-time dependency metadata
1446# Output:
1447# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1448# FILERPROVIDES_filepath_pkg - per file dep
1449#
1450# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1451# FILERDEPENDS_filepath_pkg - per file dep
1452
1453python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001454 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001455 return
1456
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001457 pkgdest = d.getVar('PKGDEST')
1458 packages = d.getVar('PACKAGES')
1459 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001460
1461 def chunks(files, n):
1462 return [files[i:i+n] for i in range(0, len(files), n)]
1463
1464 pkglist = []
1465 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001466 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001467 continue
1468 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-'):
1469 continue
1470 for files in chunks(pkgfiles[pkg], 100):
1471 pkglist.append((pkg, files, rpmdeps, pkgdest))
1472
1473 processed = oe.utils.multiprocess_exec( pkglist, oe.package.filedeprunner)
1474
1475 provides_files = {}
1476 requires_files = {}
1477
1478 for result in processed:
1479 (pkg, provides, requires) = result
1480
1481 if pkg not in provides_files:
1482 provides_files[pkg] = []
1483 if pkg not in requires_files:
1484 requires_files[pkg] = []
1485
1486 for file in provides:
1487 provides_files[pkg].append(file)
1488 key = "FILERPROVIDES_" + file + "_" + pkg
1489 d.setVar(key, " ".join(provides[file]))
1490
1491 for file in requires:
1492 requires_files[pkg].append(file)
1493 key = "FILERDEPENDS_" + file + "_" + pkg
1494 d.setVar(key, " ".join(requires[file]))
1495
1496 for pkg in requires_files:
1497 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1498 for pkg in provides_files:
1499 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1500}
1501
1502SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs2"
1503SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1504
1505python package_do_shlibs() {
1506 import re, pipes
1507 import subprocess as sub
1508
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001509 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001510 if exclude_shlibs:
1511 bb.note("not generating shlibs")
1512 return
1513
1514 lib_re = re.compile("^.*\.so")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001515 libdir_re = re.compile(".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001516
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001517 packages = d.getVar('PACKAGES')
1518 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001519
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001520 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001521
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001522 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001523 if not ver:
1524 msg = "PKGV not defined"
1525 package_qa_handle_error("pkgv-undefined", msg, d)
1526 return
1527
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001528 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001529
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001530 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001531
1532 # Take shared lock since we're only reading, not writing
1533 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"))
1534
1535 def linux_so(file, needed, sonames, renames, pkgver):
1536 needs_ldconfig = False
1537 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001538 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001539 fd = os.popen(cmd)
1540 lines = fd.readlines()
1541 fd.close()
1542 rpath = []
1543 for l in lines:
1544 m = re.match("\s+RPATH\s+([^\s]*)", l)
1545 if m:
1546 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001547 rpath = list(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001548 for l in lines:
1549 m = re.match("\s+NEEDED\s+([^\s]*)", l)
1550 if m:
1551 dep = m.group(1)
1552 if dep not in needed[pkg]:
1553 needed[pkg].append((dep, file, rpath))
1554 m = re.match("\s+SONAME\s+([^\s]*)", l)
1555 if m:
1556 this_soname = m.group(1)
1557 prov = (this_soname, ldir, pkgver)
1558 if not prov in sonames:
1559 # if library is private (only used by package) then do not build shlib for it
1560 if not private_libs or this_soname not in private_libs:
1561 sonames.append(prov)
1562 if libdir_re.match(os.path.dirname(file)):
1563 needs_ldconfig = True
1564 if snap_symlinks and (os.path.basename(file) != this_soname):
1565 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
1566 return needs_ldconfig
1567
1568 def darwin_so(file, needed, sonames, renames, pkgver):
1569 if not os.path.exists(file):
1570 return
1571 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1572
1573 def get_combinations(base):
1574 #
1575 # Given a base library name, find all combinations of this split by "." and "-"
1576 #
1577 combos = []
1578 options = base.split(".")
1579 for i in range(1, len(options) + 1):
1580 combos.append(".".join(options[0:i]))
1581 options = base.split("-")
1582 for i in range(1, len(options) + 1):
1583 combos.append("-".join(options[0:i]))
1584 return combos
1585
1586 if (file.endswith('.dylib') or file.endswith('.so')) and not pkg.endswith('-dev') and not pkg.endswith('-dbg'):
1587 # Drop suffix
1588 name = os.path.basename(file).rsplit(".",1)[0]
1589 # Find all combinations
1590 combos = get_combinations(name)
1591 for combo in combos:
1592 if not combo in sonames:
1593 prov = (combo, ldir, pkgver)
1594 sonames.append(prov)
1595 if file.endswith('.dylib') or file.endswith('.so'):
1596 rpath = []
1597 p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file],stdout=sub.PIPE,stderr=sub.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001598 out, err = p.communicate()
1599 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001600 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001601 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001602 l = l.strip()
1603 if l.startswith('path '):
1604 rpath.append(l.split()[1])
1605
1606 p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file],stdout=sub.PIPE,stderr=sub.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001607 out, err = p.communicate()
1608 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001609 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001610 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001611 l = l.strip()
1612 if not l or l.endswith(":"):
1613 continue
1614 if "is not an object file" in l:
1615 continue
1616 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1617 if name and name not in needed[pkg]:
1618 needed[pkg].append((name, file, []))
1619
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001620 def mingw_dll(file, needed, sonames, renames, pkgver):
1621 if not os.path.exists(file):
1622 return
1623
1624 if file.endswith(".dll"):
1625 # assume all dlls are shared objects provided by the package
1626 sonames.append((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
1627
1628 if (file.endswith(".dll") or file.endswith(".exe")):
1629 # use objdump to search for "DLL Name: .*\.dll"
1630 p = sub.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout = sub.PIPE, stderr= sub.PIPE)
1631 out, err = p.communicate()
1632 # process the output, grabbing all .dll names
1633 if p.returncode == 0:
1634 for m in re.finditer("DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
1635 dllname = m.group(1)
1636 if dllname:
1637 needed[pkg].append((dllname, file, []))
1638
1639 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001640 snap_symlinks = True
1641 else:
1642 snap_symlinks = False
1643
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001644 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001645
1646 needed = {}
1647 shlib_provider = oe.package.read_shlib_providers(d)
1648
1649 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001650 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001651 private_libs = private_libs.split()
1652 needs_ldconfig = False
1653 bb.debug(2, "calculating shlib provides for %s" % pkg)
1654
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001655 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001656 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001657 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001658 if not pkgver:
1659 pkgver = ver
1660
1661 needed[pkg] = []
1662 sonames = list()
1663 renames = list()
1664 for file in pkgfiles[pkg]:
1665 soname = None
1666 if cpath.islink(file):
1667 continue
1668 if targetos == "darwin" or targetos == "darwin8":
1669 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001670 elif targetos.startswith("mingw"):
1671 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001672 elif os.access(file, os.X_OK) or lib_re.match(file):
1673 ldconfig = linux_so(file, needed, sonames, renames, pkgver)
1674 needs_ldconfig = needs_ldconfig or ldconfig
1675 for (old, new) in renames:
1676 bb.note("Renaming %s to %s" % (old, new))
1677 os.rename(old, new)
1678 pkgfiles[pkg].remove(old)
1679
1680 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1681 if len(sonames):
1682 fd = open(shlibs_file, 'w')
1683 for s in sonames:
1684 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1685 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1686 if old_pkg != pkg:
1687 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))
1688 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1689 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1690 if s[0] not in shlib_provider:
1691 shlib_provider[s[0]] = {}
1692 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1693 fd.close()
1694 if needs_ldconfig and use_ldconfig:
1695 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001696 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001697 if not postinst:
1698 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001699 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001700 d.setVar('pkg_postinst_%s' % pkg, postinst)
1701 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1702
1703 bb.utils.unlockfile(lf)
1704
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001705 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001706 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001707 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001708 for e in assumed_libs.split():
1709 l, dep_pkg = e.split(":")
1710 lib_ver = None
1711 dep_pkg = dep_pkg.rsplit("_", 1)
1712 if len(dep_pkg) == 2:
1713 lib_ver = dep_pkg[1]
1714 dep_pkg = dep_pkg[0]
1715 if l not in shlib_provider:
1716 shlib_provider[l] = {}
1717 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1718
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001719 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001720
1721 for pkg in packages.split():
1722 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1723
1724 deps = list()
1725 for n in needed[pkg]:
1726 # if n is in private libraries, don't try to search provider for it
1727 # this could cause problem in case some abc.bb provides private
1728 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1729 # but skipping it is still better alternative than providing own
1730 # version and then adding runtime dependency for the same system library
1731 if private_libs and n[0] in private_libs:
1732 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1733 continue
1734 if n[0] in shlib_provider.keys():
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001735 shlib_provider_path = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001736 for k in shlib_provider[n[0]].keys():
1737 shlib_provider_path.append(k)
1738 match = None
1739 for p in n[2] + shlib_provider_path + libsearchpath:
1740 if p in shlib_provider[n[0]]:
1741 match = p
1742 break
1743 if match:
1744 (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
1745
1746 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1747
1748 if dep_pkg == pkg:
1749 continue
1750
1751 if ver_needed:
1752 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1753 else:
1754 dep = dep_pkg
1755 if not dep in deps:
1756 deps.append(dep)
1757 continue
1758 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1759
1760 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1761 if os.path.exists(deps_file):
1762 os.remove(deps_file)
1763 if len(deps):
1764 fd = open(deps_file, 'w')
1765 for dep in deps:
1766 fd.write(dep + '\n')
1767 fd.close()
1768}
1769
1770python package_do_pkgconfig () {
1771 import re
1772
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001773 packages = d.getVar('PACKAGES')
1774 workdir = d.getVar('WORKDIR')
1775 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001776
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001777 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1778 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001779
1780 pc_re = re.compile('(.*)\.pc$')
1781 var_re = re.compile('(.*)=(.*)')
1782 field_re = re.compile('(.*): (.*)')
1783
1784 pkgconfig_provided = {}
1785 pkgconfig_needed = {}
1786 for pkg in packages.split():
1787 pkgconfig_provided[pkg] = []
1788 pkgconfig_needed[pkg] = []
1789 for file in pkgfiles[pkg]:
1790 m = pc_re.match(file)
1791 if m:
1792 pd = bb.data.init()
1793 name = m.group(1)
1794 pkgconfig_provided[pkg].append(name)
1795 if not os.access(file, os.R_OK):
1796 continue
1797 f = open(file, 'r')
1798 lines = f.readlines()
1799 f.close()
1800 for l in lines:
1801 m = var_re.match(l)
1802 if m:
1803 name = m.group(1)
1804 val = m.group(2)
1805 pd.setVar(name, pd.expand(val))
1806 continue
1807 m = field_re.match(l)
1808 if m:
1809 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001810 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001811 if hdr == 'Requires':
1812 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1813
1814 # Take shared lock since we're only reading, not writing
1815 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"))
1816
1817 for pkg in packages.split():
1818 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1819 if pkgconfig_provided[pkg] != []:
1820 f = open(pkgs_file, 'w')
1821 for p in pkgconfig_provided[pkg]:
1822 f.write('%s\n' % p)
1823 f.close()
1824
1825 # Go from least to most specific since the last one found wins
1826 for dir in reversed(shlibs_dirs):
1827 if not os.path.exists(dir):
1828 continue
1829 for file in os.listdir(dir):
1830 m = re.match('^(.*)\.pclist$', file)
1831 if m:
1832 pkg = m.group(1)
1833 fd = open(os.path.join(dir, file))
1834 lines = fd.readlines()
1835 fd.close()
1836 pkgconfig_provided[pkg] = []
1837 for l in lines:
1838 pkgconfig_provided[pkg].append(l.rstrip())
1839
1840 for pkg in packages.split():
1841 deps = []
1842 for n in pkgconfig_needed[pkg]:
1843 found = False
1844 for k in pkgconfig_provided.keys():
1845 if n in pkgconfig_provided[k]:
1846 if k != pkg and not (k in deps):
1847 deps.append(k)
1848 found = True
1849 if found == False:
1850 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1851 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1852 if len(deps):
1853 fd = open(deps_file, 'w')
1854 for dep in deps:
1855 fd.write(dep + '\n')
1856 fd.close()
1857
1858 bb.utils.unlockfile(lf)
1859}
1860
1861def read_libdep_files(d):
1862 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001863 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001864 for pkg in packages:
1865 pkglibdeps[pkg] = {}
1866 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1867 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1868 if os.access(depsfile, os.R_OK):
1869 fd = open(depsfile)
1870 lines = fd.readlines()
1871 fd.close()
1872 for l in lines:
1873 l.rstrip()
1874 deps = bb.utils.explode_dep_versions2(l)
1875 for dep in deps:
1876 if not dep in pkglibdeps[pkg]:
1877 pkglibdeps[pkg][dep] = deps[dep]
1878 return pkglibdeps
1879
1880python read_shlibdeps () {
1881 pkglibdeps = read_libdep_files(d)
1882
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001883 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001884 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001885 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001886 for dep in pkglibdeps[pkg]:
1887 # Add the dep if it's not already there, or if no comparison is set
1888 if dep not in rdepends:
1889 rdepends[dep] = []
1890 for v in pkglibdeps[pkg][dep]:
1891 if v not in rdepends[dep]:
1892 rdepends[dep].append(v)
1893 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1894}
1895
1896python package_depchains() {
1897 """
1898 For a given set of prefix and postfix modifiers, make those packages
1899 RRECOMMENDS on the corresponding packages for its RDEPENDS.
1900
1901 Example: If package A depends upon package B, and A's .bb emits an
1902 A-dev package, this would make A-dev Recommends: B-dev.
1903
1904 If only one of a given suffix is specified, it will take the RRECOMMENDS
1905 based on the RDEPENDS of *all* other packages. If more than one of a given
1906 suffix is specified, its will only use the RDEPENDS of the single parent
1907 package.
1908 """
1909
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001910 packages = d.getVar('PACKAGES')
1911 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
1912 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001913
1914 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
1915
1916 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001917 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001918
1919 for depend in depends:
1920 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
1921 #bb.note("Skipping %s" % depend)
1922 continue
1923 if depend.endswith('-dev'):
1924 depend = depend[:-4]
1925 if depend.endswith('-dbg'):
1926 depend = depend[:-4]
1927 pkgname = getname(depend, suffix)
1928 #bb.note("Adding %s for %s" % (pkgname, depend))
1929 if pkgname not in rreclist and pkgname != pkg:
1930 rreclist[pkgname] = []
1931
1932 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
1933 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
1934
1935 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
1936
1937 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001938 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001939
1940 for depend in rdepends:
1941 if depend.find('virtual-locale-') != -1:
1942 #bb.note("Skipping %s" % depend)
1943 continue
1944 if depend.endswith('-dev'):
1945 depend = depend[:-4]
1946 if depend.endswith('-dbg'):
1947 depend = depend[:-4]
1948 pkgname = getname(depend, suffix)
1949 #bb.note("Adding %s for %s" % (pkgname, depend))
1950 if pkgname not in rreclist and pkgname != pkg:
1951 rreclist[pkgname] = []
1952
1953 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
1954 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
1955
1956 def add_dep(list, dep):
1957 if dep not in list:
1958 list.append(dep)
1959
1960 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001961 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001962 add_dep(depends, dep)
1963
1964 rdepends = []
1965 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001966 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001967 add_dep(rdepends, dep)
1968
1969 #bb.note('rdepends is %s' % rdepends)
1970
1971 def post_getname(name, suffix):
1972 return '%s%s' % (name, suffix)
1973 def pre_getname(name, suffix):
1974 return '%s%s' % (suffix, name)
1975
1976 pkgs = {}
1977 for pkg in packages.split():
1978 for postfix in postfixes:
1979 if pkg.endswith(postfix):
1980 if not postfix in pkgs:
1981 pkgs[postfix] = {}
1982 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
1983
1984 for prefix in prefixes:
1985 if pkg.startswith(prefix):
1986 if not prefix in pkgs:
1987 pkgs[prefix] = {}
1988 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
1989
1990 if "-dbg" in pkgs:
1991 pkglibdeps = read_libdep_files(d)
1992 pkglibdeplist = []
1993 for pkg in pkglibdeps:
1994 for k in pkglibdeps[pkg]:
1995 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001996 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001997
1998 for suffix in pkgs:
1999 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002000 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002001 continue
2002 (base, func) = pkgs[suffix][pkg]
2003 if suffix == "-dev":
2004 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2005 elif suffix == "-dbg":
2006 if not dbgdefaultdeps:
2007 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2008 continue
2009 if len(pkgs[suffix]) == 1:
2010 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2011 else:
2012 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002013 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002014 add_dep(rdeps, dep)
2015 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2016}
2017
2018# Since bitbake can't determine which variables are accessed during package
2019# iteration, we need to list them here:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002020PACKAGEVARS = "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 -05002021
2022def gen_packagevar(d):
2023 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002024 pkgs = (d.getVar("PACKAGES") or "").split()
2025 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002026 for p in pkgs:
2027 for v in vars:
2028 ret.append(v + "_" + p)
2029
2030 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2031 # affected recipes.
2032 ret.append('LICENSE_EXCLUSION-%s' % p)
2033 return " ".join(ret)
2034
2035PACKAGE_PREPROCESS_FUNCS ?= ""
2036# Functions for setting up PKGD
2037PACKAGEBUILDPKGD ?= " \
2038 perform_packagecopy \
2039 ${PACKAGE_PREPROCESS_FUNCS} \
2040 split_and_strip_files \
2041 fixup_perms \
2042 "
2043# Functions which split PKGD up into separate packages
2044PACKAGESPLITFUNCS ?= " \
2045 package_do_split_locales \
2046 populate_packages"
2047# Functions which process metadata based on split packages
2048PACKAGEFUNCS += " \
2049 package_fixsymlinks \
2050 package_name_hook \
2051 package_do_filedeps \
2052 package_do_shlibs \
2053 package_do_pkgconfig \
2054 read_shlibdeps \
2055 package_depchains \
2056 emit_pkgdata"
2057
2058python do_package () {
2059 # Change the following version to cause sstate to invalidate the package
2060 # cache. This is useful if an item this class depends on changes in a
2061 # way that the output of this class changes. rpmdeps is a good example
2062 # as any change to rpmdeps requires this to be rerun.
2063 # PACKAGE_BBCLASS_VERSION = "1"
2064
2065 # Init cachedpath
2066 global cpath
2067 cpath = oe.cachedpath.CachedPath()
2068
2069 ###########################################################################
2070 # Sanity test the setup
2071 ###########################################################################
2072
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002073 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002074 if len(packages) < 1:
2075 bb.debug(1, "No packages to build, skipping do_package")
2076 return
2077
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002078 workdir = d.getVar('WORKDIR')
2079 outdir = d.getVar('DEPLOY_DIR')
2080 dest = d.getVar('D')
2081 dvar = d.getVar('PKGD')
2082 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002083
2084 if not workdir or not outdir or not dest or not dvar or not pn:
2085 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2086 package_qa_handle_error("var-undefined", msg, d)
2087 return
2088
2089 bb.build.exec_func("package_get_auto_pr", d)
2090
2091 ###########################################################################
2092 # Optimisations
2093 ###########################################################################
2094
2095 # Continually expanding complex expressions is inefficient, particularly
2096 # when we write to the datastore and invalidate the expansion cache. This
2097 # code pre-expands some frequently used variables
2098
2099 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002100 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002101
2102 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2103 expandVar(x, d)
2104
2105 ###########################################################################
2106 # Setup PKGD (from D)
2107 ###########################################################################
2108
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002109 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002110 bb.build.exec_func(f, d)
2111
2112 ###########################################################################
2113 # Split up PKGD into PKGDEST
2114 ###########################################################################
2115
2116 cpath = oe.cachedpath.CachedPath()
2117
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002118 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002119 bb.build.exec_func(f, d)
2120
2121 ###########################################################################
2122 # Process PKGDEST
2123 ###########################################################################
2124
2125 # Build global list of files in each split package
2126 global pkgfiles
2127 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002128 packages = d.getVar('PACKAGES').split()
2129 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002130 for pkg in packages:
2131 pkgfiles[pkg] = []
2132 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2133 for file in files:
2134 pkgfiles[pkg].append(walkroot + os.sep + file)
2135
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002136 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002137 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002138
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002139 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002140 if not qa_sane:
2141 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002142}
2143
2144do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2145do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2146addtask package after do_install
2147
2148PACKAGELOCK = "${STAGING_DIR}/package-output.lock"
2149SSTATETASKS += "do_package"
2150do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2151do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
2152do_package[sstate-lockfile-shared] = "${PACKAGELOCK}"
2153do_package_setscene[dirs] = "${STAGING_DIR}"
2154
2155python do_package_setscene () {
2156 sstate_setscene(d)
2157}
2158addtask do_package_setscene
2159
2160do_packagedata () {
2161 :
2162}
2163
2164addtask packagedata before do_build after do_package
2165
2166SSTATETASKS += "do_packagedata"
2167do_packagedata[sstate-inputdirs] = "${PKGDESTWORK}"
2168do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
2169do_packagedata[sstate-lockfile-shared] = "${PACKAGELOCK}"
2170do_packagedata[stamp-extra-info] = "${MACHINE}"
2171
2172python do_packagedata_setscene () {
2173 sstate_setscene(d)
2174}
2175addtask do_packagedata_setscene
2176
2177#
2178# Helper functions for the package writing classes
2179#
2180
2181def mapping_rename_hook(d):
2182 """
2183 Rewrite variables to account for package renaming in things
2184 like debian.bbclass or manual PKG variable name changes
2185 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002186 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002187 runtime_mapping_rename("RDEPENDS", pkg, d)
2188 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2189 runtime_mapping_rename("RSUGGESTS", pkg, d)