blob: 2053d46395a7fe4be34c72d1853dfc21c503a380 [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')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500740 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500741 for conf_file in fs_perms_tables.split():
742 str += " %s" % bb.utils.which(bbpath, conf_file)
743 return str
744
745
746
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500747 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500748
749 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500750 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500751
752 # By default all of the standard directories specified in
753 # bitbake.conf will get 0755 root:root.
754 target_path_vars = [ 'base_prefix',
755 'prefix',
756 'exec_prefix',
757 'base_bindir',
758 'base_sbindir',
759 'base_libdir',
760 'datadir',
761 'sysconfdir',
762 'servicedir',
763 'sharedstatedir',
764 'localstatedir',
765 'infodir',
766 'mandir',
767 'docdir',
768 'bindir',
769 'sbindir',
770 'libexecdir',
771 'libdir',
772 'includedir',
773 'oldincludedir' ]
774
775 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500776 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500777 if dir == "":
778 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500779 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500780
781 # Now we actually load from the configuration files
782 for conf in get_fs_perms_list(d).split():
783 if os.path.exists(conf):
784 f = open(conf)
785 for line in f:
786 if line.startswith('#'):
787 continue
788 lsplit = line.split()
789 if len(lsplit) == 0:
790 continue
791 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
792 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
793 package_qa_handle_error("perm-line", msg, d)
794 continue
795 entry = fs_perms_entry(d.expand(line))
796 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500797 if entry.link:
798 fs_link_table[entry.path] = entry
799 if entry.path in fs_perms_table:
800 fs_perms_table.pop(entry.path)
801 else:
802 fs_perms_table[entry.path] = entry
803 if entry.path in fs_link_table:
804 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500805 f.close()
806
807 # Debug -- list out in-memory table
808 #for dir in fs_perms_table:
809 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500810 #for link in fs_link_table:
811 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500812
813 # We process links first, so we can go back and fixup directory ownership
814 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500815 # Process in sorted order so /run gets created before /run/lock, etc.
816 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
817 link = entry.link
818 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500819 origin = dvar + dir
820 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
821 continue
822
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500823 if link[0] == "/":
824 target = dvar + link
825 ptarget = link
826 else:
827 target = os.path.join(os.path.dirname(origin), link)
828 ptarget = os.path.join(os.path.dirname(dir), link)
829 if os.path.exists(target):
830 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
831 package_qa_handle_error("perm-link", msg, d)
832 continue
833
834 # Create path to move directory to, move it, and then setup the symlink
835 bb.utils.mkdirhier(os.path.dirname(target))
836 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
837 os.rename(origin, target)
838 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
839 os.symlink(link, origin)
840
841 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500842 origin = dvar + dir
843 if not (cpath.exists(origin) and cpath.isdir(origin)):
844 continue
845
846 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
847
848 if fs_perms_table[dir].walk == 'true':
849 for root, dirs, files in os.walk(origin):
850 for dr in dirs:
851 each_dir = os.path.join(root, dr)
852 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
853 for f in files:
854 each_file = os.path.join(root, f)
855 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
856}
857
858python split_and_strip_files () {
859 import stat, errno
860
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500861 dvar = d.getVar('PKGD')
862 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500863
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600864 oldcwd = os.getcwd()
865 os.chdir(dvar)
866
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500867 # We default to '.debug' style
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500868 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 # Single debug-file-directory style debug info
870 debugappend = ".debug"
871 debugdir = ""
872 debuglibdir = "/usr/lib/debug"
873 debugsrcdir = "/usr/src/debug"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500874 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500875 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
876 debugappend = ""
877 debugdir = "/.debug"
878 debuglibdir = ""
879 debugsrcdir = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500880 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
881 debugappend = ""
882 debugdir = "/.debug"
883 debuglibdir = ""
884 debugsrcdir = "/usr/src/debug"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500885 else:
886 # Original OE-core, a.k.a. ".debug", style debug info
887 debugappend = ""
888 debugdir = "/.debug"
889 debuglibdir = ""
890 debugsrcdir = "/usr/src/debug"
891
892 sourcefile = d.expand("${WORKDIR}/debugsources.list")
893 bb.utils.remove(sourcefile)
894
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500895 # Return type (bits):
896 # 0 - not elf
897 # 1 - ELF
898 # 2 - stripped
899 # 4 - executable
900 # 8 - shared library
901 # 16 - kernel module
902 def isELF(path):
903 type = 0
904 ret, result = oe.utils.getstatusoutput("file \"%s\"" % path.replace("\"", "\\\""))
905
906 if ret:
907 msg = "split_and_strip_files: 'file %s' failed" % path
908 package_qa_handle_error("split-strip", msg, d)
909 return type
910
911 # Not stripped
912 if "ELF" in result:
913 type |= 1
914 if "not stripped" not in result:
915 type |= 2
916 if "executable" in result:
917 type |= 4
918 if "shared" in result:
919 type |= 8
920 return type
921
922
923 #
924 # First lets figure out all of the files we may have to process ... do this only once!
925 #
926 elffiles = {}
927 symlinks = {}
928 kernmods = []
929 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500930 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
931 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
932 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
933 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500934 for root, dirs, files in cpath.walk(dvar):
935 for f in files:
936 file = os.path.join(root, f)
937 if file.endswith(".ko") and file.find("/lib/modules/") != -1:
938 kernmods.append(file)
939 continue
940
941 # Skip debug files
942 if debugappend and file.endswith(debugappend):
943 continue
944 if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
945 continue
946
947 try:
948 ltarget = cpath.realpath(file, dvar, False)
949 s = cpath.lstat(ltarget)
950 except OSError as e:
951 (err, strerror) = e.args
952 if err != errno.ENOENT:
953 raise
954 # Skip broken symlinks
955 continue
956 if not s:
957 continue
958 # Check its an excutable
959 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 -0500960 or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500961 # If it's a symlink, and points to an ELF file, we capture the readlink target
962 if cpath.islink(file):
963 target = os.readlink(file)
964 if isELF(ltarget):
965 #bb.note("Sym: %s (%d)" % (ltarget, isELF(ltarget)))
966 symlinks[file] = target
967 continue
968
969 # It's a file (or hardlink), not a link
970 # ...but is it ELF, and is it already stripped?
971 elf_file = isELF(file)
972 if elf_file & 1:
973 if elf_file & 2:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500974 if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500975 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
976 else:
977 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
978 package_qa_handle_error("already-stripped", msg, d)
979 continue
980
981 # At this point we have an unstripped elf file. We need to:
982 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
983 # b) Only strip any hardlinked file once (no races)
984 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
985
986 # Use a reference of device ID and inode number to indentify files
987 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
988 if file_reference in inodes:
989 os.unlink(file)
990 os.link(inodes[file_reference][0], file)
991 inodes[file_reference].append(file)
992 else:
993 inodes[file_reference] = [file]
994 # break hardlink
995 bb.utils.copyfile(file, file)
996 elffiles[file] = elf_file
997 # Modified the file so clear the cache
998 cpath.updatecache(file)
999
1000 #
1001 # First lets process debug splitting
1002 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001003 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001004 for file in elffiles:
1005 src = file[len(dvar):]
1006 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1007 fpath = dvar + dest
1008
1009 # Split the file...
1010 bb.utils.mkdirhier(os.path.dirname(fpath))
1011 #bb.note("Split %s -> %s" % (file, fpath))
1012 # Only store off the hard link reference if we successfully split!
1013 splitdebuginfo(file, fpath, debugsrcdir, sourcefile, d)
1014
1015 # Hardlink our debug symbols to the other hardlink copies
1016 for ref in inodes:
1017 if len(inodes[ref]) == 1:
1018 continue
1019 for file in inodes[ref][1:]:
1020 src = file[len(dvar):]
1021 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1022 fpath = dvar + dest
1023 target = inodes[ref][0][len(dvar):]
1024 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1025 bb.utils.mkdirhier(os.path.dirname(fpath))
1026 #bb.note("Link %s -> %s" % (fpath, ftarget))
1027 os.link(ftarget, fpath)
1028
1029 # Create symlinks for all cases we were able to split symbols
1030 for file in symlinks:
1031 src = file[len(dvar):]
1032 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1033 fpath = dvar + dest
1034 # Skip it if the target doesn't exist
1035 try:
1036 s = os.stat(fpath)
1037 except OSError as e:
1038 (err, strerror) = e.args
1039 if err != errno.ENOENT:
1040 raise
1041 continue
1042
1043 ltarget = symlinks[file]
1044 lpath = os.path.dirname(ltarget)
1045 lbase = os.path.basename(ltarget)
1046 ftarget = ""
1047 if lpath and lpath != ".":
1048 ftarget += lpath + debugdir + "/"
1049 ftarget += lbase + debugappend
1050 if lpath.startswith(".."):
1051 ftarget = os.path.join("..", ftarget)
1052 bb.utils.mkdirhier(os.path.dirname(fpath))
1053 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1054 os.symlink(ftarget, fpath)
1055
1056 # Process the debugsrcdir if requested...
1057 # This copies and places the referenced sources for later debugging...
1058 copydebugsources(debugsrcdir, d)
1059 #
1060 # End of debug splitting
1061 #
1062
1063 #
1064 # Now lets go back over things and strip them
1065 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001066 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1067 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001068 sfiles = []
1069 for file in elffiles:
1070 elf_file = int(elffiles[file])
1071 #bb.note("Strip %s" % file)
1072 sfiles.append((file, elf_file, strip))
1073 for f in kernmods:
1074 sfiles.append((f, 16, strip))
1075
1076 oe.utils.multiprocess_exec(sfiles, oe.package.runstrip)
1077
1078 #
1079 # End of strip
1080 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001081 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001082}
1083
1084python populate_packages () {
1085 import glob, re
1086
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001087 workdir = d.getVar('WORKDIR')
1088 outdir = d.getVar('DEPLOY_DIR')
1089 dvar = d.getVar('PKGD')
1090 packages = d.getVar('PACKAGES')
1091 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001092
1093 bb.utils.mkdirhier(outdir)
1094 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001095
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001096 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001097
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001098 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1099
1100 # If debug-with-srcpkg mode is enabled then the src package is added
1101 # into the package list and the source directory as its main content
1102 if split_source_package:
1103 src_package_name = ('%s-src' % d.getVar('PN'))
1104 packages += (' ' + src_package_name)
1105 d.setVar('FILES_%s' % src_package_name, '/usr/src/debug')
1106
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001107 # Sanity check PACKAGES for duplicates
1108 # Sanity should be moved to sanity.bbclass once we have the infrastucture
1109 package_list = []
1110
1111 for pkg in packages.split():
1112 if pkg in package_list:
1113 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
1114 package_qa_handle_error("packages-list", msg, d)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001115 # If debug-with-srcpkg mode is enabled then the src package will have
1116 # priority over dbg package when assigning the files.
1117 # This allows src package to include source files and remove them from dbg.
1118 elif split_source_package and pkg.endswith("-src"):
1119 package_list.insert(0, pkg)
1120 elif autodebug and pkg.endswith("-dbg") and not split_source_package:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001121 package_list.insert(0, pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001122 else:
1123 package_list.append(pkg)
1124 d.setVar('PACKAGES', ' '.join(package_list))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001125 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001126
1127 seen = []
1128
1129 # os.mkdir masks the permissions with umask so we have to unset it first
1130 oldumask = os.umask(0)
1131
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001132 debug = []
1133 for root, dirs, files in cpath.walk(dvar):
1134 dir = root[len(dvar):]
1135 if not dir:
1136 dir = os.sep
1137 for f in (files + dirs):
1138 path = "." + os.path.join(dir, f)
1139 if "/.debug/" in path or path.endswith("/.debug"):
1140 debug.append(path)
1141
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001142 for pkg in package_list:
1143 root = os.path.join(pkgdest, pkg)
1144 bb.utils.mkdirhier(root)
1145
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001146 filesvar = d.getVar('FILES_%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001147 if "//" in filesvar:
1148 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
1149 package_qa_handle_error("files-invalid", msg, d)
1150 filesvar.replace("//", "/")
1151
1152 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001153 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001154
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001155 if autodebug and pkg.endswith("-dbg"):
1156 files.extend(debug)
1157
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001158 for file in files:
1159 if (not cpath.islink(file)) and (not cpath.exists(file)):
1160 continue
1161 if file in seen:
1162 continue
1163 seen.append(file)
1164
1165 def mkdir(src, dest, p):
1166 src = os.path.join(src, p)
1167 dest = os.path.join(dest, p)
1168 fstat = cpath.stat(src)
1169 os.mkdir(dest, fstat.st_mode)
1170 os.chown(dest, fstat.st_uid, fstat.st_gid)
1171 if p not in seen:
1172 seen.append(p)
1173 cpath.updatecache(dest)
1174
1175 def mkdir_recurse(src, dest, paths):
1176 if cpath.exists(dest + '/' + paths):
1177 return
1178 while paths.startswith("./"):
1179 paths = paths[2:]
1180 p = "."
1181 for c in paths.split("/"):
1182 p = os.path.join(p, c)
1183 if not cpath.exists(os.path.join(dest, p)):
1184 mkdir(src, dest, p)
1185
1186 if cpath.isdir(file) and not cpath.islink(file):
1187 mkdir_recurse(dvar, root, file)
1188 continue
1189
1190 mkdir_recurse(dvar, root, os.path.dirname(file))
1191 fpath = os.path.join(root,file)
1192 if not cpath.islink(file):
1193 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001194 continue
1195 ret = bb.utils.copyfile(file, fpath)
1196 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001197 bb.fatal("File population failed")
1198
1199 # Check if symlink paths exist
1200 for file in symlink_paths:
1201 if not os.path.exists(os.path.join(root,file)):
1202 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1203 "parent directory structure does not exist. One of "
1204 "its parent directories is a symlink whose target "
1205 "directory is not included in the package." %
1206 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001207
1208 os.umask(oldumask)
1209 os.chdir(workdir)
1210
1211 # Handle LICENSE_EXCLUSION
1212 package_list = []
1213 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001214 if d.getVar('LICENSE_EXCLUSION-' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001215 msg = "%s has an incompatible license. Excluding from packaging." % pkg
1216 package_qa_handle_error("incompatible-license", msg, d)
1217 else:
1218 package_list.append(pkg)
1219 d.setVar('PACKAGES', ' '.join(package_list))
1220
1221 unshipped = []
1222 for root, dirs, files in cpath.walk(dvar):
1223 dir = root[len(dvar):]
1224 if not dir:
1225 dir = os.sep
1226 for f in (files + dirs):
1227 path = os.path.join(dir, f)
1228 if ('.' + path) not in seen:
1229 unshipped.append(path)
1230
1231 if unshipped != []:
1232 msg = pn + ": Files/directories were installed but not shipped in any package:"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001233 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001234 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1235 else:
1236 for f in unshipped:
1237 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001238 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"
1239 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001240 package_qa_handle_error("installed-vs-shipped", msg, d)
1241}
1242populate_packages[dirs] = "${D}"
1243
1244python package_fixsymlinks () {
1245 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001246 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001247 packages = d.getVar("PACKAGES", False).split()
1248
1249 dangling_links = {}
1250 pkg_files = {}
1251 for pkg in packages:
1252 dangling_links[pkg] = []
1253 pkg_files[pkg] = []
1254 inst_root = os.path.join(pkgdest, pkg)
1255 for path in pkgfiles[pkg]:
1256 rpath = path[len(inst_root):]
1257 pkg_files[pkg].append(rpath)
1258 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1259 if not cpath.lexists(rtarget):
1260 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1261
1262 newrdepends = {}
1263 for pkg in dangling_links:
1264 for l in dangling_links[pkg]:
1265 found = False
1266 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1267 for p in packages:
1268 if l in pkg_files[p]:
1269 found = True
1270 bb.debug(1, "target found in %s" % p)
1271 if p == pkg:
1272 break
1273 if pkg not in newrdepends:
1274 newrdepends[pkg] = []
1275 newrdepends[pkg].append(p)
1276 break
1277 if found == False:
1278 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1279
1280 for pkg in newrdepends:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001281 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001282 for p in newrdepends[pkg]:
1283 if p not in rdepends:
1284 rdepends[p] = []
1285 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1286}
1287
1288
1289python package_package_name_hook() {
1290 """
1291 A package_name_hook function can be used to rewrite the package names by
1292 changing PKG. For an example, see debian.bbclass.
1293 """
1294 pass
1295}
1296
1297EXPORT_FUNCTIONS package_name_hook
1298
1299
1300PKGDESTWORK = "${WORKDIR}/pkgdata"
1301
1302python emit_pkgdata() {
1303 from glob import glob
1304 import json
1305
1306 def write_if_exists(f, pkg, var):
1307 def encode(str):
1308 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001309 c = codecs.getencoder("unicode_escape")
1310 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001311
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001312 val = d.getVar('%s_%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001313 if val:
1314 f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
1315 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001316 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001317 if val:
1318 f.write('%s: %s\n' % (var, encode(val)))
1319 return val
1320
1321 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1322 for variant in variants:
1323 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1324 fd.write("PACKAGES: %s\n" % ' '.join(
1325 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1326
1327 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1328 for variant in variants:
1329 for pkg in packages.split():
1330 ml_pkg = "%s-%s" % (variant, pkg)
1331 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1332 with open(subdata_file, 'w') as fd:
1333 fd.write("PKG_%s: %s" % (ml_pkg, pkg))
1334
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001335 packages = d.getVar('PACKAGES')
1336 pkgdest = d.getVar('PKGDEST')
1337 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001338
1339 # Take shared lock since we're only reading, not writing
1340 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1341
1342 data_file = pkgdatadir + d.expand("/${PN}" )
1343 f = open(data_file, 'w')
1344 f.write("PACKAGES: %s\n" % packages)
1345 f.close()
1346
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001347 pn = d.getVar('PN')
1348 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1349 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001350
1351 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1352 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1353
1354 if (bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d)):
1355 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1356
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001357 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001358
1359 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001360 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001361 if pkgval is None:
1362 pkgval = pkg
1363 d.setVar('PKG_%s' % pkg, pkg)
1364
1365 pkgdestpkg = os.path.join(pkgdest, pkg)
1366 files = {}
1367 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001368 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001369 for f in pkgfiles[pkg]:
1370 relpth = os.path.relpath(f, pkgdestpkg)
1371 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001372 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001373 if fstat.st_ino not in seen:
1374 seen.add(fstat.st_ino)
1375 total_size += fstat.st_size
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001376 d.setVar('FILES_INFO', json.dumps(files))
1377
1378 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1379 sf = open(subdata_file, 'w')
1380 write_if_exists(sf, pkg, 'PN')
1381 write_if_exists(sf, pkg, 'PE')
1382 write_if_exists(sf, pkg, 'PV')
1383 write_if_exists(sf, pkg, 'PR')
1384 write_if_exists(sf, pkg, 'PKGE')
1385 write_if_exists(sf, pkg, 'PKGV')
1386 write_if_exists(sf, pkg, 'PKGR')
1387 write_if_exists(sf, pkg, 'LICENSE')
1388 write_if_exists(sf, pkg, 'DESCRIPTION')
1389 write_if_exists(sf, pkg, 'SUMMARY')
1390 write_if_exists(sf, pkg, 'RDEPENDS')
1391 rprov = write_if_exists(sf, pkg, 'RPROVIDES')
1392 write_if_exists(sf, pkg, 'RRECOMMENDS')
1393 write_if_exists(sf, pkg, 'RSUGGESTS')
1394 write_if_exists(sf, pkg, 'RREPLACES')
1395 write_if_exists(sf, pkg, 'RCONFLICTS')
1396 write_if_exists(sf, pkg, 'SECTION')
1397 write_if_exists(sf, pkg, 'PKG')
1398 write_if_exists(sf, pkg, 'ALLOW_EMPTY')
1399 write_if_exists(sf, pkg, 'FILES')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001400 write_if_exists(sf, pkg, 'CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001401 write_if_exists(sf, pkg, 'pkg_postinst')
1402 write_if_exists(sf, pkg, 'pkg_postrm')
1403 write_if_exists(sf, pkg, 'pkg_preinst')
1404 write_if_exists(sf, pkg, 'pkg_prerm')
1405 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1406 write_if_exists(sf, pkg, 'FILES_INFO')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001407 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001408 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1409
1410 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001411 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001412 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1413
1414 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
1415 sf.close()
1416
1417 # Symlinks needed for rprovides lookup
1418 if rprov:
1419 for p in rprov.strip().split():
1420 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1421 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1422 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1423
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001424 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001425 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001426 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001427 root = "%s/%s" % (pkgdest, pkg)
1428 os.chdir(root)
1429 g = glob('*')
1430 if g or allow_empty == "1":
1431 # Symlinks needed for reverse lookups (from the final package name)
1432 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1433 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1434
1435 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1436 open(packagedfile, 'w').close()
1437
1438 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1439 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1440
1441 if bb.data.inherits_class('allarch', d) and not bb.data.inherits_class('packagegroup', d):
1442 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1443
1444 bb.utils.unlockfile(lf)
1445}
1446emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1447
1448ldconfig_postinst_fragment() {
1449if [ x"$D" = "x" ]; then
1450 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1451fi
1452}
1453
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001454RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001455
1456# Collect perfile run-time dependency metadata
1457# Output:
1458# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1459# FILERPROVIDES_filepath_pkg - per file dep
1460#
1461# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1462# FILERDEPENDS_filepath_pkg - per file dep
1463
1464python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001465 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001466 return
1467
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001468 pkgdest = d.getVar('PKGDEST')
1469 packages = d.getVar('PACKAGES')
1470 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001471
1472 def chunks(files, n):
1473 return [files[i:i+n] for i in range(0, len(files), n)]
1474
1475 pkglist = []
1476 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001477 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001478 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001479 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 -05001480 continue
1481 for files in chunks(pkgfiles[pkg], 100):
1482 pkglist.append((pkg, files, rpmdeps, pkgdest))
1483
1484 processed = oe.utils.multiprocess_exec( pkglist, oe.package.filedeprunner)
1485
1486 provides_files = {}
1487 requires_files = {}
1488
1489 for result in processed:
1490 (pkg, provides, requires) = result
1491
1492 if pkg not in provides_files:
1493 provides_files[pkg] = []
1494 if pkg not in requires_files:
1495 requires_files[pkg] = []
1496
1497 for file in provides:
1498 provides_files[pkg].append(file)
1499 key = "FILERPROVIDES_" + file + "_" + pkg
1500 d.setVar(key, " ".join(provides[file]))
1501
1502 for file in requires:
1503 requires_files[pkg].append(file)
1504 key = "FILERDEPENDS_" + file + "_" + pkg
1505 d.setVar(key, " ".join(requires[file]))
1506
1507 for pkg in requires_files:
1508 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1509 for pkg in provides_files:
1510 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1511}
1512
1513SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs2"
1514SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1515
1516python package_do_shlibs() {
1517 import re, pipes
1518 import subprocess as sub
1519
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001520 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001521 if exclude_shlibs:
1522 bb.note("not generating shlibs")
1523 return
1524
1525 lib_re = re.compile("^.*\.so")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001526 libdir_re = re.compile(".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001527
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001528 packages = d.getVar('PACKAGES')
1529 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001530
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001531 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001532
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001533 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001534 if not ver:
1535 msg = "PKGV not defined"
1536 package_qa_handle_error("pkgv-undefined", msg, d)
1537 return
1538
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001539 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001540
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001541 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001542
1543 # Take shared lock since we're only reading, not writing
1544 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"))
1545
1546 def linux_so(file, needed, sonames, renames, pkgver):
1547 needs_ldconfig = False
1548 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001549 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001550 fd = os.popen(cmd)
1551 lines = fd.readlines()
1552 fd.close()
1553 rpath = []
1554 for l in lines:
1555 m = re.match("\s+RPATH\s+([^\s]*)", l)
1556 if m:
1557 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001558 rpath = list(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001559 for l in lines:
1560 m = re.match("\s+NEEDED\s+([^\s]*)", l)
1561 if m:
1562 dep = m.group(1)
1563 if dep not in needed[pkg]:
1564 needed[pkg].append((dep, file, rpath))
1565 m = re.match("\s+SONAME\s+([^\s]*)", l)
1566 if m:
1567 this_soname = m.group(1)
1568 prov = (this_soname, ldir, pkgver)
1569 if not prov in sonames:
1570 # if library is private (only used by package) then do not build shlib for it
1571 if not private_libs or this_soname not in private_libs:
1572 sonames.append(prov)
1573 if libdir_re.match(os.path.dirname(file)):
1574 needs_ldconfig = True
1575 if snap_symlinks and (os.path.basename(file) != this_soname):
1576 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
1577 return needs_ldconfig
1578
1579 def darwin_so(file, needed, sonames, renames, pkgver):
1580 if not os.path.exists(file):
1581 return
1582 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1583
1584 def get_combinations(base):
1585 #
1586 # Given a base library name, find all combinations of this split by "." and "-"
1587 #
1588 combos = []
1589 options = base.split(".")
1590 for i in range(1, len(options) + 1):
1591 combos.append(".".join(options[0:i]))
1592 options = base.split("-")
1593 for i in range(1, len(options) + 1):
1594 combos.append("-".join(options[0:i]))
1595 return combos
1596
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001597 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 -05001598 # Drop suffix
1599 name = os.path.basename(file).rsplit(".",1)[0]
1600 # Find all combinations
1601 combos = get_combinations(name)
1602 for combo in combos:
1603 if not combo in sonames:
1604 prov = (combo, ldir, pkgver)
1605 sonames.append(prov)
1606 if file.endswith('.dylib') or file.endswith('.so'):
1607 rpath = []
1608 p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file],stdout=sub.PIPE,stderr=sub.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001609 out, err = p.communicate()
1610 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001611 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001612 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001613 l = l.strip()
1614 if l.startswith('path '):
1615 rpath.append(l.split()[1])
1616
1617 p = sub.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file],stdout=sub.PIPE,stderr=sub.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001618 out, err = p.communicate()
1619 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001620 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001621 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001622 l = l.strip()
1623 if not l or l.endswith(":"):
1624 continue
1625 if "is not an object file" in l:
1626 continue
1627 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1628 if name and name not in needed[pkg]:
1629 needed[pkg].append((name, file, []))
1630
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001631 def mingw_dll(file, needed, sonames, renames, pkgver):
1632 if not os.path.exists(file):
1633 return
1634
1635 if file.endswith(".dll"):
1636 # assume all dlls are shared objects provided by the package
1637 sonames.append((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
1638
1639 if (file.endswith(".dll") or file.endswith(".exe")):
1640 # use objdump to search for "DLL Name: .*\.dll"
1641 p = sub.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout = sub.PIPE, stderr= sub.PIPE)
1642 out, err = p.communicate()
1643 # process the output, grabbing all .dll names
1644 if p.returncode == 0:
1645 for m in re.finditer("DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
1646 dllname = m.group(1)
1647 if dllname:
1648 needed[pkg].append((dllname, file, []))
1649
1650 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001651 snap_symlinks = True
1652 else:
1653 snap_symlinks = False
1654
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001655 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001656
1657 needed = {}
1658 shlib_provider = oe.package.read_shlib_providers(d)
1659
1660 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001661 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001662 private_libs = private_libs.split()
1663 needs_ldconfig = False
1664 bb.debug(2, "calculating shlib provides for %s" % pkg)
1665
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001666 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001667 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001668 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001669 if not pkgver:
1670 pkgver = ver
1671
1672 needed[pkg] = []
1673 sonames = list()
1674 renames = list()
1675 for file in pkgfiles[pkg]:
1676 soname = None
1677 if cpath.islink(file):
1678 continue
1679 if targetos == "darwin" or targetos == "darwin8":
1680 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001681 elif targetos.startswith("mingw"):
1682 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001683 elif os.access(file, os.X_OK) or lib_re.match(file):
1684 ldconfig = linux_so(file, needed, sonames, renames, pkgver)
1685 needs_ldconfig = needs_ldconfig or ldconfig
1686 for (old, new) in renames:
1687 bb.note("Renaming %s to %s" % (old, new))
1688 os.rename(old, new)
1689 pkgfiles[pkg].remove(old)
1690
1691 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1692 if len(sonames):
1693 fd = open(shlibs_file, 'w')
1694 for s in sonames:
1695 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1696 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1697 if old_pkg != pkg:
1698 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))
1699 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1700 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1701 if s[0] not in shlib_provider:
1702 shlib_provider[s[0]] = {}
1703 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1704 fd.close()
1705 if needs_ldconfig and use_ldconfig:
1706 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001707 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001708 if not postinst:
1709 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001710 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001711 d.setVar('pkg_postinst_%s' % pkg, postinst)
1712 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1713
1714 bb.utils.unlockfile(lf)
1715
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001716 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001717 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001718 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001719 for e in assumed_libs.split():
1720 l, dep_pkg = e.split(":")
1721 lib_ver = None
1722 dep_pkg = dep_pkg.rsplit("_", 1)
1723 if len(dep_pkg) == 2:
1724 lib_ver = dep_pkg[1]
1725 dep_pkg = dep_pkg[0]
1726 if l not in shlib_provider:
1727 shlib_provider[l] = {}
1728 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1729
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001730 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001731
1732 for pkg in packages.split():
1733 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1734
1735 deps = list()
1736 for n in needed[pkg]:
1737 # if n is in private libraries, don't try to search provider for it
1738 # this could cause problem in case some abc.bb provides private
1739 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1740 # but skipping it is still better alternative than providing own
1741 # version and then adding runtime dependency for the same system library
1742 if private_libs and n[0] in private_libs:
1743 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1744 continue
1745 if n[0] in shlib_provider.keys():
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001746 shlib_provider_path = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001747 for k in shlib_provider[n[0]].keys():
1748 shlib_provider_path.append(k)
1749 match = None
1750 for p in n[2] + shlib_provider_path + libsearchpath:
1751 if p in shlib_provider[n[0]]:
1752 match = p
1753 break
1754 if match:
1755 (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
1756
1757 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1758
1759 if dep_pkg == pkg:
1760 continue
1761
1762 if ver_needed:
1763 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1764 else:
1765 dep = dep_pkg
1766 if not dep in deps:
1767 deps.append(dep)
1768 continue
1769 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1770
1771 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1772 if os.path.exists(deps_file):
1773 os.remove(deps_file)
1774 if len(deps):
1775 fd = open(deps_file, 'w')
1776 for dep in deps:
1777 fd.write(dep + '\n')
1778 fd.close()
1779}
1780
1781python package_do_pkgconfig () {
1782 import re
1783
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001784 packages = d.getVar('PACKAGES')
1785 workdir = d.getVar('WORKDIR')
1786 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001787
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001788 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1789 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001790
1791 pc_re = re.compile('(.*)\.pc$')
1792 var_re = re.compile('(.*)=(.*)')
1793 field_re = re.compile('(.*): (.*)')
1794
1795 pkgconfig_provided = {}
1796 pkgconfig_needed = {}
1797 for pkg in packages.split():
1798 pkgconfig_provided[pkg] = []
1799 pkgconfig_needed[pkg] = []
1800 for file in pkgfiles[pkg]:
1801 m = pc_re.match(file)
1802 if m:
1803 pd = bb.data.init()
1804 name = m.group(1)
1805 pkgconfig_provided[pkg].append(name)
1806 if not os.access(file, os.R_OK):
1807 continue
1808 f = open(file, 'r')
1809 lines = f.readlines()
1810 f.close()
1811 for l in lines:
1812 m = var_re.match(l)
1813 if m:
1814 name = m.group(1)
1815 val = m.group(2)
1816 pd.setVar(name, pd.expand(val))
1817 continue
1818 m = field_re.match(l)
1819 if m:
1820 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001821 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001822 if hdr == 'Requires':
1823 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1824
1825 # Take shared lock since we're only reading, not writing
1826 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"))
1827
1828 for pkg in packages.split():
1829 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1830 if pkgconfig_provided[pkg] != []:
1831 f = open(pkgs_file, 'w')
1832 for p in pkgconfig_provided[pkg]:
1833 f.write('%s\n' % p)
1834 f.close()
1835
1836 # Go from least to most specific since the last one found wins
1837 for dir in reversed(shlibs_dirs):
1838 if not os.path.exists(dir):
1839 continue
1840 for file in os.listdir(dir):
1841 m = re.match('^(.*)\.pclist$', file)
1842 if m:
1843 pkg = m.group(1)
1844 fd = open(os.path.join(dir, file))
1845 lines = fd.readlines()
1846 fd.close()
1847 pkgconfig_provided[pkg] = []
1848 for l in lines:
1849 pkgconfig_provided[pkg].append(l.rstrip())
1850
1851 for pkg in packages.split():
1852 deps = []
1853 for n in pkgconfig_needed[pkg]:
1854 found = False
1855 for k in pkgconfig_provided.keys():
1856 if n in pkgconfig_provided[k]:
1857 if k != pkg and not (k in deps):
1858 deps.append(k)
1859 found = True
1860 if found == False:
1861 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1862 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1863 if len(deps):
1864 fd = open(deps_file, 'w')
1865 for dep in deps:
1866 fd.write(dep + '\n')
1867 fd.close()
1868
1869 bb.utils.unlockfile(lf)
1870}
1871
1872def read_libdep_files(d):
1873 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001874 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001875 for pkg in packages:
1876 pkglibdeps[pkg] = {}
1877 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1878 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1879 if os.access(depsfile, os.R_OK):
1880 fd = open(depsfile)
1881 lines = fd.readlines()
1882 fd.close()
1883 for l in lines:
1884 l.rstrip()
1885 deps = bb.utils.explode_dep_versions2(l)
1886 for dep in deps:
1887 if not dep in pkglibdeps[pkg]:
1888 pkglibdeps[pkg][dep] = deps[dep]
1889 return pkglibdeps
1890
1891python read_shlibdeps () {
1892 pkglibdeps = read_libdep_files(d)
1893
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001894 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001895 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001896 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001897 for dep in pkglibdeps[pkg]:
1898 # Add the dep if it's not already there, or if no comparison is set
1899 if dep not in rdepends:
1900 rdepends[dep] = []
1901 for v in pkglibdeps[pkg][dep]:
1902 if v not in rdepends[dep]:
1903 rdepends[dep].append(v)
1904 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1905}
1906
1907python package_depchains() {
1908 """
1909 For a given set of prefix and postfix modifiers, make those packages
1910 RRECOMMENDS on the corresponding packages for its RDEPENDS.
1911
1912 Example: If package A depends upon package B, and A's .bb emits an
1913 A-dev package, this would make A-dev Recommends: B-dev.
1914
1915 If only one of a given suffix is specified, it will take the RRECOMMENDS
1916 based on the RDEPENDS of *all* other packages. If more than one of a given
1917 suffix is specified, its will only use the RDEPENDS of the single parent
1918 package.
1919 """
1920
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001921 packages = d.getVar('PACKAGES')
1922 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
1923 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001924
1925 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
1926
1927 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001928 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001929
1930 for depend in depends:
1931 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
1932 #bb.note("Skipping %s" % depend)
1933 continue
1934 if depend.endswith('-dev'):
1935 depend = depend[:-4]
1936 if depend.endswith('-dbg'):
1937 depend = depend[:-4]
1938 pkgname = getname(depend, suffix)
1939 #bb.note("Adding %s for %s" % (pkgname, depend))
1940 if pkgname not in rreclist and pkgname != pkg:
1941 rreclist[pkgname] = []
1942
1943 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
1944 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
1945
1946 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
1947
1948 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001949 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001950
1951 for depend in rdepends:
1952 if depend.find('virtual-locale-') != -1:
1953 #bb.note("Skipping %s" % depend)
1954 continue
1955 if depend.endswith('-dev'):
1956 depend = depend[:-4]
1957 if depend.endswith('-dbg'):
1958 depend = depend[:-4]
1959 pkgname = getname(depend, suffix)
1960 #bb.note("Adding %s for %s" % (pkgname, depend))
1961 if pkgname not in rreclist and pkgname != pkg:
1962 rreclist[pkgname] = []
1963
1964 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
1965 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
1966
1967 def add_dep(list, dep):
1968 if dep not in list:
1969 list.append(dep)
1970
1971 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001972 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001973 add_dep(depends, dep)
1974
1975 rdepends = []
1976 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001977 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001978 add_dep(rdepends, dep)
1979
1980 #bb.note('rdepends is %s' % rdepends)
1981
1982 def post_getname(name, suffix):
1983 return '%s%s' % (name, suffix)
1984 def pre_getname(name, suffix):
1985 return '%s%s' % (suffix, name)
1986
1987 pkgs = {}
1988 for pkg in packages.split():
1989 for postfix in postfixes:
1990 if pkg.endswith(postfix):
1991 if not postfix in pkgs:
1992 pkgs[postfix] = {}
1993 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
1994
1995 for prefix in prefixes:
1996 if pkg.startswith(prefix):
1997 if not prefix in pkgs:
1998 pkgs[prefix] = {}
1999 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2000
2001 if "-dbg" in pkgs:
2002 pkglibdeps = read_libdep_files(d)
2003 pkglibdeplist = []
2004 for pkg in pkglibdeps:
2005 for k in pkglibdeps[pkg]:
2006 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002007 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002008
2009 for suffix in pkgs:
2010 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002011 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002012 continue
2013 (base, func) = pkgs[suffix][pkg]
2014 if suffix == "-dev":
2015 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2016 elif suffix == "-dbg":
2017 if not dbgdefaultdeps:
2018 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2019 continue
2020 if len(pkgs[suffix]) == 1:
2021 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2022 else:
2023 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002024 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002025 add_dep(rdeps, dep)
2026 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2027}
2028
2029# Since bitbake can't determine which variables are accessed during package
2030# iteration, we need to list them here:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002031PACKAGEVARS = "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 -05002032
2033def gen_packagevar(d):
2034 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002035 pkgs = (d.getVar("PACKAGES") or "").split()
2036 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002037 for p in pkgs:
2038 for v in vars:
2039 ret.append(v + "_" + p)
2040
2041 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2042 # affected recipes.
2043 ret.append('LICENSE_EXCLUSION-%s' % p)
2044 return " ".join(ret)
2045
2046PACKAGE_PREPROCESS_FUNCS ?= ""
2047# Functions for setting up PKGD
2048PACKAGEBUILDPKGD ?= " \
2049 perform_packagecopy \
2050 ${PACKAGE_PREPROCESS_FUNCS} \
2051 split_and_strip_files \
2052 fixup_perms \
2053 "
2054# Functions which split PKGD up into separate packages
2055PACKAGESPLITFUNCS ?= " \
2056 package_do_split_locales \
2057 populate_packages"
2058# Functions which process metadata based on split packages
2059PACKAGEFUNCS += " \
2060 package_fixsymlinks \
2061 package_name_hook \
2062 package_do_filedeps \
2063 package_do_shlibs \
2064 package_do_pkgconfig \
2065 read_shlibdeps \
2066 package_depchains \
2067 emit_pkgdata"
2068
2069python do_package () {
2070 # Change the following version to cause sstate to invalidate the package
2071 # cache. This is useful if an item this class depends on changes in a
2072 # way that the output of this class changes. rpmdeps is a good example
2073 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002074 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002075
2076 # Init cachedpath
2077 global cpath
2078 cpath = oe.cachedpath.CachedPath()
2079
2080 ###########################################################################
2081 # Sanity test the setup
2082 ###########################################################################
2083
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002084 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002085 if len(packages) < 1:
2086 bb.debug(1, "No packages to build, skipping do_package")
2087 return
2088
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002089 workdir = d.getVar('WORKDIR')
2090 outdir = d.getVar('DEPLOY_DIR')
2091 dest = d.getVar('D')
2092 dvar = d.getVar('PKGD')
2093 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002094
2095 if not workdir or not outdir or not dest or not dvar or not pn:
2096 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2097 package_qa_handle_error("var-undefined", msg, d)
2098 return
2099
2100 bb.build.exec_func("package_get_auto_pr", d)
2101
2102 ###########################################################################
2103 # Optimisations
2104 ###########################################################################
2105
2106 # Continually expanding complex expressions is inefficient, particularly
2107 # when we write to the datastore and invalidate the expansion cache. This
2108 # code pre-expands some frequently used variables
2109
2110 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002111 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002112
2113 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2114 expandVar(x, d)
2115
2116 ###########################################################################
2117 # Setup PKGD (from D)
2118 ###########################################################################
2119
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002120 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002121 bb.build.exec_func(f, d)
2122
2123 ###########################################################################
2124 # Split up PKGD into PKGDEST
2125 ###########################################################################
2126
2127 cpath = oe.cachedpath.CachedPath()
2128
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002129 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002130 bb.build.exec_func(f, d)
2131
2132 ###########################################################################
2133 # Process PKGDEST
2134 ###########################################################################
2135
2136 # Build global list of files in each split package
2137 global pkgfiles
2138 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002139 packages = d.getVar('PACKAGES').split()
2140 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002141 for pkg in packages:
2142 pkgfiles[pkg] = []
2143 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2144 for file in files:
2145 pkgfiles[pkg].append(walkroot + os.sep + file)
2146
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002147 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002148 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002149
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002150 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002151 if not qa_sane:
2152 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002153}
2154
2155do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2156do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2157addtask package after do_install
2158
2159PACKAGELOCK = "${STAGING_DIR}/package-output.lock"
2160SSTATETASKS += "do_package"
2161do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2162do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
2163do_package[sstate-lockfile-shared] = "${PACKAGELOCK}"
2164do_package_setscene[dirs] = "${STAGING_DIR}"
2165
2166python do_package_setscene () {
2167 sstate_setscene(d)
2168}
2169addtask do_package_setscene
2170
2171do_packagedata () {
2172 :
2173}
2174
2175addtask packagedata before do_build after do_package
2176
2177SSTATETASKS += "do_packagedata"
2178do_packagedata[sstate-inputdirs] = "${PKGDESTWORK}"
2179do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
2180do_packagedata[sstate-lockfile-shared] = "${PACKAGELOCK}"
2181do_packagedata[stamp-extra-info] = "${MACHINE}"
2182
2183python do_packagedata_setscene () {
2184 sstate_setscene(d)
2185}
2186addtask do_packagedata_setscene
2187
2188#
2189# Helper functions for the package writing classes
2190#
2191
2192def mapping_rename_hook(d):
2193 """
2194 Rewrite variables to account for package renaming in things
2195 like debian.bbclass or manual PKG variable name changes
2196 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002197 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002198 runtime_mapping_rename("RDEPENDS", pkg, d)
2199 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2200 runtime_mapping_rename("RSUGGESTS", pkg, d)