blob: 4c0a85953636c08f5dbd38fdd62181e8e184a979 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# Packaging process
3#
4# Executive summary: This class iterates over the functions listed in PACKAGEFUNCS
5# Taking D and splitting it up into the packages listed in PACKAGES, placing the
6# resulting output in PKGDEST.
7#
8# There are the following default steps but PACKAGEFUNCS can be extended:
9#
10# a) package_get_auto_pr - get PRAUTO from remote PR service
11#
12# b) perform_packagecopy - Copy D into PKGD
13#
14# c) package_do_split_locales - Split out the locale files, updates FILES and PACKAGES
15#
16# d) split_and_strip_files - split the files into runtime and debug and strip them.
17# Debug files include debug info split, and associated sources that end up in -dbg packages
18#
19# e) fixup_perms - Fix up permissions in the package before we split it.
20#
21# f) populate_packages - Split the files in PKGD into separate packages in PKGDEST/<pkgname>
22# Also triggers the binary stripping code to put files in -dbg packages.
23#
24# g) package_do_filedeps - Collect perfile run-time dependency metadata
25# The data is stores in FILER{PROVIDES,DEPENDS}_file_pkg variables with
26# a list of affected files in FILER{PROVIDES,DEPENDS}FLIST_pkg
27#
28# h) package_do_shlibs - Look at the shared libraries generated and autotmatically add any
Brad Bishop316dfdd2018-06-25 12:45:53 -040029# dependencies found. Also stores the package name so anyone else using this library
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030# knows which package to depend on.
31#
32# i) package_do_pkgconfig - Keep track of which packages need and provide which .pc files
33#
34# j) read_shlibdeps - Reads the stored shlibs information into the metadata
35#
36# k) package_depchains - Adds automatic dependencies to -dbg and -dev packages
37#
38# l) emit_pkgdata - saves the packaging data into PKGDATA_DIR for use in later
39# packaging steps
40
41inherit packagedata
Patrick Williamsc124f4f2015-09-15 14:41:29 -050042inherit chrpath
43
44# Need the package_qa_handle_error() in insane.bbclass
45inherit insane
46
47PKGD = "${WORKDIR}/package"
48PKGDEST = "${WORKDIR}/packages-split"
49
50LOCALE_SECTION ?= ''
51
52ALL_MULTILIB_PACKAGE_ARCHS = "${@all_multilib_tune_values(d, 'PACKAGE_ARCHS')}"
53
54# rpm is used for the per-file dependency identification
Brad Bishop316dfdd2018-06-25 12:45:53 -040055# dwarfsrcfiles is used to determine the list of debug source files
56PACKAGE_DEPENDS += "rpm-native dwarfsrcfiles-native"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057
Brad Bishop6e60e8b2018-02-01 10:27:11 -050058
59# If your postinstall can execute at rootfs creation time rather than on
60# target but depends on a native/cross tool in order to execute, you need to
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080061# list that tool in PACKAGE_WRITE_DEPS. Target package dependencies belong
Brad Bishop6e60e8b2018-02-01 10:27:11 -050062# in the package dependencies as normal, this is just for native/cross support
63# tools at rootfs build time.
64PACKAGE_WRITE_DEPS ??= ""
65
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066def legitimize_package_name(s):
67 """
68 Make sure package names are legitimate strings
69 """
70 import re
71
72 def fixutf(m):
73 cp = m.group(1)
74 if cp:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060075 return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076
77 # Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
Brad Bishop19323692019-04-05 15:28:33 -040078 s = re.sub(r'<U([0-9A-Fa-f]{1,4})>', fixutf, s)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050079
80 # Remaining package name validity fixes
81 return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
82
83def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None, allow_links=False, summary=None):
84 """
85 Used in .bb files to split up dynamically generated subpackages of a
86 given package, usually plugins or modules.
87
88 Arguments:
89 root -- the path in which to search
90 file_regex -- regular expression to match searched files. Use
91 parentheses () to mark the part of this expression
92 that should be used to derive the module name (to be
93 substituted where %s is used in other function
94 arguments as noted below)
95 output_pattern -- pattern to use for the package names. Must include %s.
96 description -- description to set for each package. Must include %s.
97 postinst -- postinstall script to use for all packages (as a
98 string)
99 recursive -- True to perform a recursive search - default False
100 hook -- a hook function to be called for every match. The
101 function will be called with the following arguments
102 (in the order listed):
103 f: full path to the file/directory match
104 pkg: the package name
105 file_regex: as above
106 output_pattern: as above
107 modulename: the module name derived using file_regex
108 extra_depends -- extra runtime dependencies (RDEPENDS) to be set for
109 all packages. The default value of None causes a
110 dependency on the main package (${PN}) - if you do
111 not want this, pass '' for this parameter.
112 aux_files_pattern -- extra item(s) to be added to FILES for each
113 package. Can be a single string item or a list of
114 strings for multiple items. Must include %s.
115 postrm -- postrm script to use for all packages (as a string)
116 allow_dirs -- True allow directories to be matched - default False
117 prepend -- if True, prepend created packages to PACKAGES instead
118 of the default False which appends them
119 match_path -- match file_regex on the whole relative path to the
120 root rather than just the file name
121 aux_files_pattern_verbatim -- extra item(s) to be added to FILES for
122 each package, using the actual derived module name
123 rather than converting it to something legal for a
124 package name. Can be a single string item or a list
125 of strings for multiple items. Must include %s.
126 allow_links -- True to allow symlinks to be matched - default False
127 summary -- Summary to set for each package. Must include %s;
128 defaults to description if not set.
129
130 """
131
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500132 dvar = d.getVar('PKGD')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500133 root = d.expand(root)
134 output_pattern = d.expand(output_pattern)
135 extra_depends = d.expand(extra_depends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500136
137 # If the root directory doesn't exist, don't error out later but silently do
138 # no splitting.
139 if not os.path.exists(dvar + root):
140 return []
141
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500142 ml = d.getVar("MLPREFIX")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500143 if ml:
144 if not output_pattern.startswith(ml):
145 output_pattern = ml + output_pattern
146
147 newdeps = []
148 for dep in (extra_depends or "").split():
149 if dep.startswith(ml):
150 newdeps.append(dep)
151 else:
152 newdeps.append(ml + dep)
153 if newdeps:
154 extra_depends = " ".join(newdeps)
155
156
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500157 packages = d.getVar('PACKAGES').split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600158 split_packages = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159
160 if postinst:
161 postinst = '#!/bin/sh\n' + postinst + '\n'
162 if postrm:
163 postrm = '#!/bin/sh\n' + postrm + '\n'
164 if not recursive:
165 objs = os.listdir(dvar + root)
166 else:
167 objs = []
168 for walkroot, dirs, files in os.walk(dvar + root):
169 for file in files:
170 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
171 if relpath:
172 objs.append(relpath)
173
174 if extra_depends == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500175 extra_depends = d.getVar("PN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500176
177 if not summary:
178 summary = description
179
180 for o in sorted(objs):
181 import re, stat
182 if match_path:
183 m = re.match(file_regex, o)
184 else:
185 m = re.match(file_regex, os.path.basename(o))
186
187 if not m:
188 continue
189 f = os.path.join(dvar + root, o)
190 mode = os.lstat(f).st_mode
191 if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))):
192 continue
193 on = legitimize_package_name(m.group(1))
194 pkg = output_pattern % on
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600195 split_packages.add(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500196 if not pkg in packages:
197 if prepend:
198 packages = [pkg] + packages
199 else:
200 packages.append(pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500201 oldfiles = d.getVar('FILES_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500202 newfile = os.path.join(root, o)
203 # These names will be passed through glob() so if the filename actually
204 # contains * or ? (rare, but possible) we need to handle that specially
205 newfile = newfile.replace('*', '[*]')
206 newfile = newfile.replace('?', '[?]')
207 if not oldfiles:
208 the_files = [newfile]
209 if aux_files_pattern:
210 if type(aux_files_pattern) is list:
211 for fp in aux_files_pattern:
212 the_files.append(fp % on)
213 else:
214 the_files.append(aux_files_pattern % on)
215 if aux_files_pattern_verbatim:
216 if type(aux_files_pattern_verbatim) is list:
217 for fp in aux_files_pattern_verbatim:
218 the_files.append(fp % m.group(1))
219 else:
220 the_files.append(aux_files_pattern_verbatim % m.group(1))
221 d.setVar('FILES_' + pkg, " ".join(the_files))
222 else:
223 d.setVar('FILES_' + pkg, oldfiles + " " + newfile)
224 if extra_depends != '':
225 d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500226 if not d.getVar('DESCRIPTION_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500227 d.setVar('DESCRIPTION_' + pkg, description % on)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500228 if not d.getVar('SUMMARY_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229 d.setVar('SUMMARY_' + pkg, summary % on)
230 if postinst:
231 d.setVar('pkg_postinst_' + pkg, postinst)
232 if postrm:
233 d.setVar('pkg_postrm_' + pkg, postrm)
234 if callable(hook):
235 hook(f, pkg, file_regex, output_pattern, m.group(1))
236
237 d.setVar('PACKAGES', ' '.join(packages))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600238 return list(split_packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500239
240PACKAGE_DEPENDS += "file-native"
241
242python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500243 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500244 deps = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500245 for dep in (d.getVar('PACKAGE_DEPENDS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500246 deps += " %s:do_populate_sysroot" % dep
247 d.appendVarFlag('do_package', 'depends', deps)
248
249 # shlibs requires any DEPENDS to have already packaged for the *.list files
250 d.appendVarFlag('do_package', 'deptask', " do_packagedata")
251}
252
253# Get a list of files from file vars by searching files under current working directory
254# The list contains symlinks, directories and normal files.
255def files_from_filevars(filevars):
256 import os,glob
257 cpath = oe.cachedpath.CachedPath()
258 files = []
259 for f in filevars:
260 if os.path.isabs(f):
261 f = '.' + f
262 if not f.startswith("./"):
263 f = './' + f
264 globbed = glob.glob(f)
265 if globbed:
266 if [ f ] != globbed:
267 files += globbed
268 continue
269 files.append(f)
270
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600271 symlink_paths = []
272 for ind, f in enumerate(files):
273 # Handle directory symlinks. Truncate path to the lowest level symlink
274 parent = ''
275 for dirname in f.split('/')[:-1]:
276 parent = os.path.join(parent, dirname)
277 if dirname == '.':
278 continue
279 if cpath.islink(parent):
280 bb.warn("FILES contains file '%s' which resides under a "
281 "directory symlink. Please fix the recipe and use the "
282 "real path for the file." % f[1:])
283 symlink_paths.append(f)
284 files[ind] = parent
285 f = parent
286 break
287
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500288 if not cpath.islink(f):
289 if cpath.isdir(f):
290 newfiles = [ os.path.join(f,x) for x in os.listdir(f) ]
291 if newfiles:
292 files += newfiles
293
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600294 return files, symlink_paths
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500295
296# Called in package_<rpm,ipk,deb>.bbclass to get the correct list of configuration files
297def get_conffiles(pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500298 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500299 root = os.path.join(pkgdest, pkg)
300 cwd = os.getcwd()
301 os.chdir(root)
302
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500303 conffiles = d.getVar('CONFFILES_%s' % pkg);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304 if conffiles == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500305 conffiles = d.getVar('CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500306 if conffiles == None:
307 conffiles = ""
308 conffiles = conffiles.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600309 conf_orig_list = files_from_filevars(conffiles)[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500310
311 # Remove links and directories from conf_orig_list to get conf_list which only contains normal files
312 conf_list = []
313 for f in conf_orig_list:
314 if os.path.isdir(f):
315 continue
316 if os.path.islink(f):
317 continue
318 if not os.path.exists(f):
319 continue
320 conf_list.append(f)
321
322 # Remove the leading './'
323 for i in range(0, len(conf_list)):
324 conf_list[i] = conf_list[i][1:]
325
326 os.chdir(cwd)
327 return conf_list
328
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500329def checkbuildpath(file, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500330 tmpdir = d.getVar('TMPDIR')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500331 with open(file) as f:
332 file_content = f.read()
333 if tmpdir in file_content:
334 return True
335
336 return False
337
Brad Bishop316dfdd2018-06-25 12:45:53 -0400338def parse_debugsources_from_dwarfsrcfiles_output(dwarfsrcfiles_output):
339 debugfiles = {}
340
341 for line in dwarfsrcfiles_output.splitlines():
342 if line.startswith("\t"):
343 debugfiles[os.path.normpath(line.split()[0])] = ""
344
345 return debugfiles.keys()
346
Brad Bishop19323692019-04-05 15:28:33 -0400347def source_info(file, d, fatal=True):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800348 import subprocess
349
350 cmd = ["dwarfsrcfiles", file]
351 try:
352 output = subprocess.check_output(cmd, universal_newlines=True, stderr=subprocess.STDOUT)
353 retval = 0
354 except subprocess.CalledProcessError as exc:
355 output = exc.output
356 retval = exc.returncode
357
Brad Bishop316dfdd2018-06-25 12:45:53 -0400358 # 255 means a specific file wasn't fully parsed to get the debug file list, which is not a fatal failure
359 if retval != 0 and retval != 255:
360 msg = "dwarfsrcfiles failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else "")
361 if fatal:
362 bb.fatal(msg)
363 bb.note(msg)
364
365 debugsources = parse_debugsources_from_dwarfsrcfiles_output(output)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400366
Brad Bishop19323692019-04-05 15:28:33 -0400367 return list(debugsources)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400368
Brad Bishop19323692019-04-05 15:28:33 -0400369def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500370 # Function to split a single file into two components, one is the stripped
371 # target system binary, the other contains any debugging information. The
372 # two files are linked to reference each other.
373 #
Brad Bishop19323692019-04-05 15:28:33 -0400374 # return a mapping of files:debugsources
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500375
376 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800377 import subprocess
378
379 src = file[len(dvar):]
380 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
381 debugfile = dvar + dest
Brad Bishop19323692019-04-05 15:28:33 -0400382 sources = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800383
384 # Split the file...
385 bb.utils.mkdirhier(os.path.dirname(debugfile))
386 #bb.note("Split %s -> %s" % (file, debugfile))
387 # Only store off the hard link reference if we successfully split!
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500388
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500389 dvar = d.getVar('PKGD')
390 objcopy = d.getVar("OBJCOPY")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500391
392 # We ignore kernel modules, we don't generate debug info files.
393 if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
Brad Bishop19323692019-04-05 15:28:33 -0400394 return (file, sources)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500395
396 newmode = None
397 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
398 origmode = os.stat(file)[stat.ST_MODE]
399 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
400 os.chmod(file, newmode)
401
402 # We need to extract the debug src information here...
403 if debugsrcdir:
Brad Bishop19323692019-04-05 15:28:33 -0400404 sources = source_info(file, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500405
406 bb.utils.mkdirhier(os.path.dirname(debugfile))
407
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800408 subprocess.check_output([objcopy, '--only-keep-debug', file, debugfile], stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500409
410 # Set the debuglink to have the view of the file path on the target
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800411 subprocess.check_output([objcopy, '--add-gnu-debuglink', debugfile, file], stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500412
413 if newmode:
414 os.chmod(file, origmode)
415
Brad Bishop19323692019-04-05 15:28:33 -0400416 return (file, sources)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500417
Brad Bishop19323692019-04-05 15:28:33 -0400418def copydebugsources(debugsrcdir, sources, d):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400419 # The debug src information written out to sourcefile is further processed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500420 # and copied to the destination here.
421
422 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800423 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500424
Brad Bishop19323692019-04-05 15:28:33 -0400425 if debugsrcdir and sources:
426 sourcefile = d.expand("${WORKDIR}/debugsources.list")
427 bb.utils.remove(sourcefile)
428
429 # filenames are null-separated - this is an artefact of the previous use
430 # of rpm's debugedit, which was writing them out that way, and the code elsewhere
431 # is still assuming that.
432 debuglistoutput = '\0'.join(sources) + '\0'
433 with open(sourcefile, 'a') as sf:
434 sf.write(debuglistoutput)
435
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500436 dvar = d.getVar('PKGD')
437 strip = d.getVar("STRIP")
438 objcopy = d.getVar("OBJCOPY")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500439 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500440 workparentdir = os.path.dirname(os.path.dirname(workdir))
441 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
442
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500443 # If build path exists in sourcefile, it means toolchain did not use
444 # -fdebug-prefix-map to compile
445 if checkbuildpath(sourcefile, d):
446 localsrc_prefix = workparentdir + "/"
447 else:
448 localsrc_prefix = "/usr/src/debug/"
449
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 nosuchdir = []
451 basepath = dvar
452 for p in debugsrcdir.split("/"):
453 basepath = basepath + "/" + p
454 if not cpath.exists(basepath):
455 nosuchdir.append(basepath)
456 bb.utils.mkdirhier(basepath)
457 cpath.updatecache(basepath)
458
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500459 # Ignore files from the recipe sysroots (target and native)
460 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500461 # We need to ignore files that are not actually ours
462 # we do this by only paying attention to items from this package
463 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500464 # Remove prefix in the source paths
465 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500466 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
467
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500468 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800469 try:
470 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
471 except subprocess.CalledProcessError:
472 # Can "fail" if internal headers/transient sources are attempted
473 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500474
475 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
476 # Work around this by manually finding and copying any symbolic links that made it through.
Brad Bishop19323692019-04-05 15:28:33 -0400477 cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s')" % \
478 (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800479 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500480
481 # The copy by cpio may have resulted in some empty directories! Remove these
482 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800483 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500484
485 # Also remove debugsrcdir if its empty
486 for p in nosuchdir[::-1]:
487 if os.path.exists(p) and not os.listdir(p):
488 os.rmdir(p)
489
490#
491# Package data handling routines
492#
493
494def get_package_mapping (pkg, basepkg, d):
495 import oe.packagedata
496
497 data = oe.packagedata.read_subpkgdata(pkg, d)
498 key = "PKG_%s" % pkg
499
500 if key in data:
501 # Have to avoid undoing the write_extra_pkgs(global_variants...)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800502 if bb.data.inherits_class('allarch', d) and not d.getVar('MULTILIB_VARIANTS') \
503 and data[key] == basepkg:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500504 return pkg
505 return data[key]
506
507 return pkg
508
509def get_package_additional_metadata (pkg_type, d):
510 base_key = "PACKAGE_ADD_METADATA"
511 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
512 if d.getVar(key, False) is None:
513 continue
514 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500515 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500516 d.setVarFlag(key, "separator", "\\n")
517 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
518 return "\n".join(metadata_fields).strip()
519
520def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500521 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500522
523 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500524 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500525 for depend in deps:
526 new_depend = get_package_mapping(depend, pkg, d)
527 new_depends[new_depend] = deps[depend]
528
529 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
530
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500531 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500532
533#
534# Package functions suitable for inclusion in PACKAGEFUNCS
535#
536
537python package_get_auto_pr() {
538 import oe.prservice
539 import re
540
541 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500542 pn = d.getVar('PN')
543 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500544 if not (host is None):
545 d.setVar("PRSERV_HOST", host)
546
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500547 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500548
549 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500550 if not d.getVar('PRSERV_HOST'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500551 if 'AUTOINC' in pkgv:
552 d.setVar("PKGV", pkgv.replace("AUTOINC", "0"))
553 return
554
555 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500556 pv = d.getVar("PV")
557 version = d.getVar("PRAUTOINX")
558 pkgarch = d.getVar("PACKAGE_ARCH")
559 checksum = d.getVar("BB_TASKHASH")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500561 if d.getVar('PRSERV_LOCKDOWN'):
562 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500563 if auto_pr is None:
564 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
565 d.setVar('PRAUTO',str(auto_pr))
566 return
567
568 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500569 conn = d.getVar("__PRSERV_CONN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500570 if conn is None:
571 conn = oe.prservice.prserv_make_conn(d)
572 if conn is not None:
573 if "AUTOINC" in pkgv:
574 srcpv = bb.fetch2.get_srcrev(d)
575 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
576 value = conn.getPR(base_ver, pkgarch, srcpv)
577 d.setVar("PKGV", pkgv.replace("AUTOINC", str(value)))
578
579 auto_pr = conn.getPR(version, pkgarch, checksum)
580 except Exception as e:
581 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
582 if auto_pr is None:
583 bb.fatal("Can NOT get PRAUTO from remote PR service")
584 d.setVar('PRAUTO',str(auto_pr))
585}
586
587LOCALEBASEPN ??= "${PN}"
588
589python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500590 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500591 bb.debug(1, "package requested not splitting locales")
592 return
593
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500594 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500595
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500596 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500597 if not datadir:
598 bb.note("datadir not defined")
599 return
600
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500601 dvar = d.getVar('PKGD')
602 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500603
604 if pn + '-locale' in packages:
605 packages.remove(pn + '-locale')
606
607 localedir = os.path.join(dvar + datadir, 'locale')
608
609 if not cpath.isdir(localedir):
610 bb.debug(1, "No locale files in this package")
611 return
612
613 locales = os.listdir(localedir)
614
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500615 summary = d.getVar('SUMMARY') or pn
616 description = d.getVar('DESCRIPTION') or ""
617 locale_section = d.getVar('LOCALE_SECTION')
618 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500619 for l in sorted(locales):
620 ln = legitimize_package_name(l)
621 pkg = pn + '-locale-' + ln
622 packages.append(pkg)
623 d.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l))
624 d.setVar('RRECOMMENDS_' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
625 d.setVar('RPROVIDES_' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
626 d.setVar('SUMMARY_' + pkg, '%s - %s translations' % (summary, l))
627 d.setVar('DESCRIPTION_' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
628 if locale_section:
629 d.setVar('SECTION_' + pkg, locale_section)
630
631 d.setVar('PACKAGES', ' '.join(packages))
632
633 # Disabled by RP 18/06/07
634 # Wildcards aren't supported in debian
635 # They break with ipkg since glibc-locale* will mean that
636 # glibc-localedata-translit* won't install as a dependency
637 # for some other package which breaks meta-toolchain
638 # Probably breaks since virtual-locale- isn't provided anywhere
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500639 #rdep = (d.getVar('RDEPENDS_%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500640 #rdep.append('%s-locale*' % pn)
641 #d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep))
642}
643
644python perform_packagecopy () {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800645 import subprocess
646
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500647 dest = d.getVar('D')
648 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500649
650 # Start by package population by taking a copy of the installed
651 # files to operate on
652 # Preserve sparse files and hard links
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800653 cmd = 'tar -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar)
654 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500655
656 # replace RPATHs for the nativesdk binaries, to make them relocatable
657 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
658 rpath_replace (dvar, d)
659}
660perform_packagecopy[cleandirs] = "${PKGD}"
661perform_packagecopy[dirs] = "${PKGD}"
662
663# We generate a master list of directories to process, we start by
664# seeding this list with reasonable defaults, then load from
665# the fs-perms.txt files
666python fixup_perms () {
667 import pwd, grp
668
669 # init using a string with the same format as a line as documented in
670 # the fs-perms.txt file
671 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
672 # <path> link <link target>
673 #
674 # __str__ can be used to print out an entry in the input format
675 #
676 # if fs_perms_entry.path is None:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400677 # an error occurred
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500678 # if fs_perms_entry.link, you can retrieve:
679 # fs_perms_entry.path = path
680 # fs_perms_entry.link = target of link
681 # if not fs_perms_entry.link, you can retrieve:
682 # fs_perms_entry.path = path
683 # fs_perms_entry.mode = expected dir mode or None
684 # fs_perms_entry.uid = expected uid or -1
685 # fs_perms_entry.gid = expected gid or -1
686 # fs_perms_entry.walk = 'true' or something else
687 # fs_perms_entry.fmode = expected file mode or None
688 # fs_perms_entry.fuid = expected file uid or -1
689 # fs_perms_entry_fgid = expected file gid or -1
690 class fs_perms_entry():
691 def __init__(self, line):
692 lsplit = line.split()
693 if len(lsplit) == 3 and lsplit[1].lower() == "link":
694 self._setlink(lsplit[0], lsplit[2])
695 elif len(lsplit) == 8:
696 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
697 else:
698 msg = "Fixup Perms: invalid config line %s" % line
699 package_qa_handle_error("perm-config", msg, d)
700 self.path = None
701 self.link = None
702
703 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
704 self.path = os.path.normpath(path)
705 self.link = None
706 self.mode = self._procmode(mode)
707 self.uid = self._procuid(uid)
708 self.gid = self._procgid(gid)
709 self.walk = walk.lower()
710 self.fmode = self._procmode(fmode)
711 self.fuid = self._procuid(fuid)
712 self.fgid = self._procgid(fgid)
713
714 def _setlink(self, path, link):
715 self.path = os.path.normpath(path)
716 self.link = link
717
718 def _procmode(self, mode):
719 if not mode or (mode and mode == "-"):
720 return None
721 else:
722 return int(mode,8)
723
724 # Note uid/gid -1 has special significance in os.lchown
725 def _procuid(self, uid):
726 if uid is None or uid == "-":
727 return -1
728 elif uid.isdigit():
729 return int(uid)
730 else:
731 return pwd.getpwnam(uid).pw_uid
732
733 def _procgid(self, gid):
734 if gid is None or gid == "-":
735 return -1
736 elif gid.isdigit():
737 return int(gid)
738 else:
739 return grp.getgrnam(gid).gr_gid
740
741 # Use for debugging the entries
742 def __str__(self):
743 if self.link:
744 return "%s link %s" % (self.path, self.link)
745 else:
746 mode = "-"
747 if self.mode:
748 mode = "0%o" % self.mode
749 fmode = "-"
750 if self.fmode:
751 fmode = "0%o" % self.fmode
752 uid = self._mapugid(self.uid)
753 gid = self._mapugid(self.gid)
754 fuid = self._mapugid(self.fuid)
755 fgid = self._mapugid(self.fgid)
756 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
757
758 def _mapugid(self, id):
759 if id is None or id == -1:
760 return "-"
761 else:
762 return "%d" % id
763
764 # Fix the permission, owner and group of path
765 def fix_perms(path, mode, uid, gid, dir):
766 if mode and not os.path.islink(path):
767 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
768 os.chmod(path, mode)
769 # -1 is a special value that means don't change the uid/gid
770 # if they are BOTH -1, don't bother to lchown
771 if not (uid == -1 and gid == -1):
772 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
773 os.lchown(path, uid, gid)
774
775 # Return a list of configuration files based on either the default
776 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
777 # paths are resolved via BBPATH
778 def get_fs_perms_list(d):
779 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500780 bbpath = d.getVar('BBPATH')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500781 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500782 for conf_file in fs_perms_tables.split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800783 confpath = bb.utils.which(bbpath, conf_file)
784 if confpath:
785 str += " %s" % bb.utils.which(bbpath, conf_file)
786 else:
787 bb.warn("cannot find %s specified in FILESYSTEM_PERMS_TABLES" % conf_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500788 return str
789
790
791
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500792 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500793
794 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500795 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500796
797 # By default all of the standard directories specified in
798 # bitbake.conf will get 0755 root:root.
799 target_path_vars = [ 'base_prefix',
800 'prefix',
801 'exec_prefix',
802 'base_bindir',
803 'base_sbindir',
804 'base_libdir',
805 'datadir',
806 'sysconfdir',
807 'servicedir',
808 'sharedstatedir',
809 'localstatedir',
810 'infodir',
811 'mandir',
812 'docdir',
813 'bindir',
814 'sbindir',
815 'libexecdir',
816 'libdir',
817 'includedir',
818 'oldincludedir' ]
819
820 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500821 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500822 if dir == "":
823 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500824 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500825
826 # Now we actually load from the configuration files
827 for conf in get_fs_perms_list(d).split():
828 if os.path.exists(conf):
829 f = open(conf)
830 for line in f:
831 if line.startswith('#'):
832 continue
833 lsplit = line.split()
834 if len(lsplit) == 0:
835 continue
836 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
837 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
838 package_qa_handle_error("perm-line", msg, d)
839 continue
840 entry = fs_perms_entry(d.expand(line))
841 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500842 if entry.link:
843 fs_link_table[entry.path] = entry
844 if entry.path in fs_perms_table:
845 fs_perms_table.pop(entry.path)
846 else:
847 fs_perms_table[entry.path] = entry
848 if entry.path in fs_link_table:
849 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500850 f.close()
851
852 # Debug -- list out in-memory table
853 #for dir in fs_perms_table:
854 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500855 #for link in fs_link_table:
856 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500857
858 # We process links first, so we can go back and fixup directory ownership
859 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500860 # Process in sorted order so /run gets created before /run/lock, etc.
861 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
862 link = entry.link
863 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500864 origin = dvar + dir
865 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
866 continue
867
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500868 if link[0] == "/":
869 target = dvar + link
870 ptarget = link
871 else:
872 target = os.path.join(os.path.dirname(origin), link)
873 ptarget = os.path.join(os.path.dirname(dir), link)
874 if os.path.exists(target):
875 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
876 package_qa_handle_error("perm-link", msg, d)
877 continue
878
879 # Create path to move directory to, move it, and then setup the symlink
880 bb.utils.mkdirhier(os.path.dirname(target))
881 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
882 os.rename(origin, target)
883 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
884 os.symlink(link, origin)
885
886 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500887 origin = dvar + dir
888 if not (cpath.exists(origin) and cpath.isdir(origin)):
889 continue
890
891 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
892
893 if fs_perms_table[dir].walk == 'true':
894 for root, dirs, files in os.walk(origin):
895 for dr in dirs:
896 each_dir = os.path.join(root, dr)
897 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
898 for f in files:
899 each_file = os.path.join(root, f)
900 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
901}
902
903python split_and_strip_files () {
904 import stat, errno
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800905 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500906
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500907 dvar = d.getVar('PKGD')
908 pn = d.getVar('PN')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400909 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500910
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600911 oldcwd = os.getcwd()
912 os.chdir(dvar)
913
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500914 # We default to '.debug' style
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500915 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500916 # Single debug-file-directory style debug info
917 debugappend = ".debug"
918 debugdir = ""
919 debuglibdir = "/usr/lib/debug"
920 debugsrcdir = "/usr/src/debug"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500921 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500922 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
923 debugappend = ""
924 debugdir = "/.debug"
925 debuglibdir = ""
926 debugsrcdir = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500927 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
928 debugappend = ""
929 debugdir = "/.debug"
930 debuglibdir = ""
931 debugsrcdir = "/usr/src/debug"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500932 else:
933 # Original OE-core, a.k.a. ".debug", style debug info
934 debugappend = ""
935 debugdir = "/.debug"
936 debuglibdir = ""
937 debugsrcdir = "/usr/src/debug"
938
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500939 #
940 # First lets figure out all of the files we may have to process ... do this only once!
941 #
942 elffiles = {}
943 symlinks = {}
944 kernmods = []
Brad Bishop316dfdd2018-06-25 12:45:53 -0400945 staticlibs = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500946 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500947 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
948 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
Brad Bishop316dfdd2018-06-25 12:45:53 -0400949 skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500950 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
951 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800952 checkelf = {}
953 checkelflinks = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500954 for root, dirs, files in cpath.walk(dvar):
955 for f in files:
956 file = os.path.join(root, f)
957 if file.endswith(".ko") and file.find("/lib/modules/") != -1:
958 kernmods.append(file)
959 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800960 if oe.package.is_static_lib(file):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400961 staticlibs.append(file)
962 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500963
964 # Skip debug files
965 if debugappend and file.endswith(debugappend):
966 continue
967 if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
968 continue
969
Brad Bishop316dfdd2018-06-25 12:45:53 -0400970 if file in skipfiles:
971 continue
972
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500973 try:
974 ltarget = cpath.realpath(file, dvar, False)
975 s = cpath.lstat(ltarget)
976 except OSError as e:
977 (err, strerror) = e.args
978 if err != errno.ENOENT:
979 raise
980 # Skip broken symlinks
981 continue
982 if not s:
983 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -0400984 # Check its an executable
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500985 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 -0500986 or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800987
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500988 if cpath.islink(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800989 checkelflinks[file] = ltarget
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500990 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800991 # Use a reference of device ID and inode number to identify files
992 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
993 checkelf[file] = (file, file_reference)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500994
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800995 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d)
996 results_map = {}
997 for (ltarget, elf_file) in results:
998 results_map[ltarget] = elf_file
999 for file in checkelflinks:
1000 ltarget = checkelflinks[file]
1001 # If it's a symlink, and points to an ELF file, we capture the readlink target
1002 if results_map[ltarget]:
1003 target = os.readlink(file)
1004 #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget]))
1005 symlinks[file] = target
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001006
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001007 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d)
1008 for (file, elf_file) in results:
1009 # It's a file (or hardlink), not a link
1010 # ...but is it ELF, and is it already stripped?
1011 if elf_file & 1:
1012 if elf_file & 2:
1013 if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
1014 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1015 else:
1016 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
1017 package_qa_handle_error("already-stripped", msg, d)
1018 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001019
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001020 # At this point we have an unstripped elf file. We need to:
1021 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1022 # b) Only strip any hardlinked file once (no races)
1023 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1024
1025 # Use a reference of device ID and inode number to identify files
1026 file_reference = checkelf[file][1]
1027 if file_reference in inodes:
1028 os.unlink(file)
1029 os.link(inodes[file_reference][0], file)
1030 inodes[file_reference].append(file)
1031 else:
1032 inodes[file_reference] = [file]
1033 # break hardlink
1034 bb.utils.break_hardlinks(file)
1035 elffiles[file] = elf_file
1036 # Modified the file so clear the cache
1037 cpath.updatecache(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001038
1039 #
1040 # First lets process debug splitting
1041 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001042 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop19323692019-04-05 15:28:33 -04001043 results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001044
Brad Bishop316dfdd2018-06-25 12:45:53 -04001045 if debugsrcdir and not targetos.startswith("mingw"):
1046 for file in staticlibs:
Brad Bishop19323692019-04-05 15:28:33 -04001047 results.extend(source_info(file, d, fatal=False))
1048
1049 sources = set()
1050 for r in results:
1051 sources.update(r[1])
Brad Bishop316dfdd2018-06-25 12:45:53 -04001052
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001053 # Hardlink our debug symbols to the other hardlink copies
1054 for ref in inodes:
1055 if len(inodes[ref]) == 1:
1056 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001057
1058 target = inodes[ref][0][len(dvar):]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001059 for file in inodes[ref][1:]:
1060 src = file[len(dvar):]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001061 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(target) + debugappend
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001062 fpath = dvar + dest
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001063 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1064 bb.utils.mkdirhier(os.path.dirname(fpath))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001065 # Only one hardlink of separated debug info file in each directory
1066 if not os.access(fpath, os.R_OK):
1067 #bb.note("Link %s -> %s" % (fpath, ftarget))
1068 os.link(ftarget, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001069
1070 # Create symlinks for all cases we were able to split symbols
1071 for file in symlinks:
1072 src = file[len(dvar):]
1073 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1074 fpath = dvar + dest
1075 # Skip it if the target doesn't exist
1076 try:
1077 s = os.stat(fpath)
1078 except OSError as e:
1079 (err, strerror) = e.args
1080 if err != errno.ENOENT:
1081 raise
1082 continue
1083
1084 ltarget = symlinks[file]
1085 lpath = os.path.dirname(ltarget)
1086 lbase = os.path.basename(ltarget)
1087 ftarget = ""
1088 if lpath and lpath != ".":
1089 ftarget += lpath + debugdir + "/"
1090 ftarget += lbase + debugappend
1091 if lpath.startswith(".."):
1092 ftarget = os.path.join("..", ftarget)
1093 bb.utils.mkdirhier(os.path.dirname(fpath))
1094 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1095 os.symlink(ftarget, fpath)
1096
1097 # Process the debugsrcdir if requested...
1098 # This copies and places the referenced sources for later debugging...
Brad Bishop19323692019-04-05 15:28:33 -04001099 copydebugsources(debugsrcdir, sources, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001100 #
1101 # End of debug splitting
1102 #
1103
1104 #
1105 # Now lets go back over things and strip them
1106 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001107 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1108 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001109 sfiles = []
1110 for file in elffiles:
1111 elf_file = int(elffiles[file])
1112 #bb.note("Strip %s" % file)
1113 sfiles.append((file, elf_file, strip))
1114 for f in kernmods:
1115 sfiles.append((f, 16, strip))
1116
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001117 oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001118
1119 #
1120 # End of strip
1121 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001122 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001123}
1124
1125python populate_packages () {
1126 import glob, re
1127
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001128 workdir = d.getVar('WORKDIR')
1129 outdir = d.getVar('DEPLOY_DIR')
1130 dvar = d.getVar('PKGD')
Brad Bishop19323692019-04-05 15:28:33 -04001131 packages = d.getVar('PACKAGES').split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001132 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001133
1134 bb.utils.mkdirhier(outdir)
1135 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001136
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001137 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001138
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001139 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1140
Brad Bishop19323692019-04-05 15:28:33 -04001141 # If debug-with-srcpkg mode is enabled then add the source package if it
1142 # doesn't exist and add the source file contents to the source package.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001143 if split_source_package:
1144 src_package_name = ('%s-src' % d.getVar('PN'))
Brad Bishop19323692019-04-05 15:28:33 -04001145 if not src_package_name in packages:
1146 packages.append(src_package_name)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001147 d.setVar('FILES_%s' % src_package_name, '/usr/src/debug')
1148
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001149 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001150 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001151 package_dict = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001152
Brad Bishop19323692019-04-05 15:28:33 -04001153 for i, pkg in enumerate(packages):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001154 if pkg in package_dict:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001155 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
1156 package_qa_handle_error("packages-list", msg, d)
Brad Bishop19323692019-04-05 15:28:33 -04001157 # Ensure the source package gets the chance to pick up the source files
1158 # before the debug package by ordering it first in PACKAGES. Whether it
1159 # actually picks up any source files is controlled by
1160 # PACKAGE_DEBUG_SPLIT_STYLE.
1161 elif pkg.endswith("-src"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001162 package_dict[pkg] = (10, i)
1163 elif autodebug and pkg.endswith("-dbg"):
1164 package_dict[pkg] = (30, i)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001165 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001166 package_dict[pkg] = (50, i)
Brad Bishop19323692019-04-05 15:28:33 -04001167 packages = sorted(package_dict.keys(), key=package_dict.get)
1168 d.setVar('PACKAGES', ' '.join(packages))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001169 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001170
1171 seen = []
1172
1173 # os.mkdir masks the permissions with umask so we have to unset it first
1174 oldumask = os.umask(0)
1175
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001176 debug = []
1177 for root, dirs, files in cpath.walk(dvar):
1178 dir = root[len(dvar):]
1179 if not dir:
1180 dir = os.sep
1181 for f in (files + dirs):
1182 path = "." + os.path.join(dir, f)
1183 if "/.debug/" in path or path.endswith("/.debug"):
1184 debug.append(path)
1185
Brad Bishop19323692019-04-05 15:28:33 -04001186 for pkg in packages:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001187 root = os.path.join(pkgdest, pkg)
1188 bb.utils.mkdirhier(root)
1189
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001190 filesvar = d.getVar('FILES_%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001191 if "//" in filesvar:
1192 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
1193 package_qa_handle_error("files-invalid", msg, d)
1194 filesvar.replace("//", "/")
1195
1196 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001197 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001198
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001199 if autodebug and pkg.endswith("-dbg"):
1200 files.extend(debug)
1201
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001202 for file in files:
1203 if (not cpath.islink(file)) and (not cpath.exists(file)):
1204 continue
1205 if file in seen:
1206 continue
1207 seen.append(file)
1208
1209 def mkdir(src, dest, p):
1210 src = os.path.join(src, p)
1211 dest = os.path.join(dest, p)
1212 fstat = cpath.stat(src)
1213 os.mkdir(dest, fstat.st_mode)
1214 os.chown(dest, fstat.st_uid, fstat.st_gid)
1215 if p not in seen:
1216 seen.append(p)
1217 cpath.updatecache(dest)
1218
1219 def mkdir_recurse(src, dest, paths):
1220 if cpath.exists(dest + '/' + paths):
1221 return
1222 while paths.startswith("./"):
1223 paths = paths[2:]
1224 p = "."
1225 for c in paths.split("/"):
1226 p = os.path.join(p, c)
1227 if not cpath.exists(os.path.join(dest, p)):
1228 mkdir(src, dest, p)
1229
1230 if cpath.isdir(file) and not cpath.islink(file):
1231 mkdir_recurse(dvar, root, file)
1232 continue
1233
1234 mkdir_recurse(dvar, root, os.path.dirname(file))
1235 fpath = os.path.join(root,file)
1236 if not cpath.islink(file):
1237 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001238 continue
1239 ret = bb.utils.copyfile(file, fpath)
1240 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001241 bb.fatal("File population failed")
1242
1243 # Check if symlink paths exist
1244 for file in symlink_paths:
1245 if not os.path.exists(os.path.join(root,file)):
1246 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1247 "parent directory structure does not exist. One of "
1248 "its parent directories is a symlink whose target "
1249 "directory is not included in the package." %
1250 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001251
1252 os.umask(oldumask)
1253 os.chdir(workdir)
1254
1255 # Handle LICENSE_EXCLUSION
1256 package_list = []
Brad Bishop19323692019-04-05 15:28:33 -04001257 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001258 if d.getVar('LICENSE_EXCLUSION-' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001259 msg = "%s has an incompatible license. Excluding from packaging." % pkg
1260 package_qa_handle_error("incompatible-license", msg, d)
1261 else:
1262 package_list.append(pkg)
1263 d.setVar('PACKAGES', ' '.join(package_list))
1264
1265 unshipped = []
1266 for root, dirs, files in cpath.walk(dvar):
1267 dir = root[len(dvar):]
1268 if not dir:
1269 dir = os.sep
1270 for f in (files + dirs):
1271 path = os.path.join(dir, f)
1272 if ('.' + path) not in seen:
1273 unshipped.append(path)
1274
1275 if unshipped != []:
1276 msg = pn + ": Files/directories were installed but not shipped in any package:"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001277 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001278 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1279 else:
1280 for f in unshipped:
1281 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001282 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"
1283 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001284 package_qa_handle_error("installed-vs-shipped", msg, d)
1285}
1286populate_packages[dirs] = "${D}"
1287
1288python package_fixsymlinks () {
1289 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001290 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001291 packages = d.getVar("PACKAGES", False).split()
1292
1293 dangling_links = {}
1294 pkg_files = {}
1295 for pkg in packages:
1296 dangling_links[pkg] = []
1297 pkg_files[pkg] = []
1298 inst_root = os.path.join(pkgdest, pkg)
1299 for path in pkgfiles[pkg]:
1300 rpath = path[len(inst_root):]
1301 pkg_files[pkg].append(rpath)
1302 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1303 if not cpath.lexists(rtarget):
1304 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1305
1306 newrdepends = {}
1307 for pkg in dangling_links:
1308 for l in dangling_links[pkg]:
1309 found = False
1310 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1311 for p in packages:
1312 if l in pkg_files[p]:
1313 found = True
1314 bb.debug(1, "target found in %s" % p)
1315 if p == pkg:
1316 break
1317 if pkg not in newrdepends:
1318 newrdepends[pkg] = []
1319 newrdepends[pkg].append(p)
1320 break
1321 if found == False:
1322 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1323
1324 for pkg in newrdepends:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001325 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001326 for p in newrdepends[pkg]:
1327 if p not in rdepends:
1328 rdepends[p] = []
1329 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1330}
1331
1332
1333python package_package_name_hook() {
1334 """
1335 A package_name_hook function can be used to rewrite the package names by
1336 changing PKG. For an example, see debian.bbclass.
1337 """
1338 pass
1339}
1340
1341EXPORT_FUNCTIONS package_name_hook
1342
1343
1344PKGDESTWORK = "${WORKDIR}/pkgdata"
1345
1346python emit_pkgdata() {
1347 from glob import glob
1348 import json
1349
Brad Bishop316dfdd2018-06-25 12:45:53 -04001350 def process_postinst_on_target(pkg, mlprefix):
1351 defer_fragment = """
1352if [ -n "$D" ]; then
1353 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1354 exit 0
1355fi
1356""" % (pkg, mlprefix)
1357
1358 postinst = d.getVar('pkg_postinst_%s' % pkg)
1359 postinst_ontarget = d.getVar('pkg_postinst_ontarget_%s' % pkg)
1360
1361 if postinst_ontarget:
1362 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1363 if not postinst:
1364 postinst = '#!/bin/sh\n'
1365 postinst += defer_fragment
1366 postinst += postinst_ontarget
1367 d.setVar('pkg_postinst_%s' % pkg, postinst)
1368
1369 def add_set_e_to_scriptlets(pkg):
1370 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
1371 scriptlet = d.getVar('%s_%s' % (scriptlet_name, pkg))
1372 if scriptlet:
1373 scriptlet_split = scriptlet.split('\n')
1374 if scriptlet_split[0].startswith("#!"):
1375 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1376 else:
1377 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
1378 d.setVar('%s_%s' % (scriptlet_name, pkg), scriptlet)
1379
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001380 def write_if_exists(f, pkg, var):
1381 def encode(str):
1382 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001383 c = codecs.getencoder("unicode_escape")
1384 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001385
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001386 val = d.getVar('%s_%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001387 if val:
1388 f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
1389 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001390 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001391 if val:
1392 f.write('%s: %s\n' % (var, encode(val)))
1393 return val
1394
1395 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1396 for variant in variants:
1397 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1398 fd.write("PACKAGES: %s\n" % ' '.join(
1399 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1400
1401 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1402 for variant in variants:
1403 for pkg in packages.split():
1404 ml_pkg = "%s-%s" % (variant, pkg)
1405 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1406 with open(subdata_file, 'w') as fd:
1407 fd.write("PKG_%s: %s" % (ml_pkg, pkg))
1408
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001409 packages = d.getVar('PACKAGES')
1410 pkgdest = d.getVar('PKGDEST')
1411 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001412
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001413 data_file = pkgdatadir + d.expand("/${PN}" )
1414 f = open(data_file, 'w')
1415 f.write("PACKAGES: %s\n" % packages)
1416 f.close()
1417
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001418 pn = d.getVar('PN')
1419 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1420 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001421
1422 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1423 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1424
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001425 if bb.data.inherits_class('allarch', d) and not variants \
1426 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001427 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1428
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001429 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001430
1431 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001432 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001433 if pkgval is None:
1434 pkgval = pkg
1435 d.setVar('PKG_%s' % pkg, pkg)
1436
1437 pkgdestpkg = os.path.join(pkgdest, pkg)
1438 files = {}
1439 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001440 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001441 for f in pkgfiles[pkg]:
1442 relpth = os.path.relpath(f, pkgdestpkg)
1443 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001444 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001445 if fstat.st_ino not in seen:
1446 seen.add(fstat.st_ino)
1447 total_size += fstat.st_size
Brad Bishop19323692019-04-05 15:28:33 -04001448 d.setVar('FILES_INFO', json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001449
1450 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1451 sf = open(subdata_file, 'w')
1452 write_if_exists(sf, pkg, 'PN')
1453 write_if_exists(sf, pkg, 'PE')
1454 write_if_exists(sf, pkg, 'PV')
1455 write_if_exists(sf, pkg, 'PR')
1456 write_if_exists(sf, pkg, 'PKGE')
1457 write_if_exists(sf, pkg, 'PKGV')
1458 write_if_exists(sf, pkg, 'PKGR')
1459 write_if_exists(sf, pkg, 'LICENSE')
1460 write_if_exists(sf, pkg, 'DESCRIPTION')
1461 write_if_exists(sf, pkg, 'SUMMARY')
1462 write_if_exists(sf, pkg, 'RDEPENDS')
1463 rprov = write_if_exists(sf, pkg, 'RPROVIDES')
1464 write_if_exists(sf, pkg, 'RRECOMMENDS')
1465 write_if_exists(sf, pkg, 'RSUGGESTS')
1466 write_if_exists(sf, pkg, 'RREPLACES')
1467 write_if_exists(sf, pkg, 'RCONFLICTS')
1468 write_if_exists(sf, pkg, 'SECTION')
1469 write_if_exists(sf, pkg, 'PKG')
1470 write_if_exists(sf, pkg, 'ALLOW_EMPTY')
1471 write_if_exists(sf, pkg, 'FILES')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001472 write_if_exists(sf, pkg, 'CONFFILES')
Brad Bishop316dfdd2018-06-25 12:45:53 -04001473 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1474 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001475 write_if_exists(sf, pkg, 'pkg_postinst')
1476 write_if_exists(sf, pkg, 'pkg_postrm')
1477 write_if_exists(sf, pkg, 'pkg_preinst')
1478 write_if_exists(sf, pkg, 'pkg_prerm')
1479 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1480 write_if_exists(sf, pkg, 'FILES_INFO')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001481 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001482 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1483
1484 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001485 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001486 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1487
1488 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
1489 sf.close()
1490
1491 # Symlinks needed for rprovides lookup
1492 if rprov:
1493 for p in rprov.strip().split():
1494 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1495 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1496 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1497
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001498 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001499 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001500 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001501 root = "%s/%s" % (pkgdest, pkg)
1502 os.chdir(root)
1503 g = glob('*')
1504 if g or allow_empty == "1":
1505 # Symlinks needed for reverse lookups (from the final package name)
1506 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1507 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1508
1509 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1510 open(packagedfile, 'w').close()
1511
1512 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1513 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1514
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001515 if bb.data.inherits_class('allarch', d) and not variants \
1516 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001517 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1518
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001519}
1520emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1521
1522ldconfig_postinst_fragment() {
1523if [ x"$D" = "x" ]; then
1524 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1525fi
1526}
1527
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001528RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001529
1530# Collect perfile run-time dependency metadata
1531# Output:
1532# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1533# FILERPROVIDES_filepath_pkg - per file dep
1534#
1535# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1536# FILERDEPENDS_filepath_pkg - per file dep
1537
1538python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001539 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001540 return
1541
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001542 pkgdest = d.getVar('PKGDEST')
1543 packages = d.getVar('PACKAGES')
1544 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001545
1546 def chunks(files, n):
1547 return [files[i:i+n] for i in range(0, len(files), n)]
1548
1549 pkglist = []
1550 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001551 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001552 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001553 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 -05001554 continue
1555 for files in chunks(pkgfiles[pkg], 100):
1556 pkglist.append((pkg, files, rpmdeps, pkgdest))
1557
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001558 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001559
1560 provides_files = {}
1561 requires_files = {}
1562
1563 for result in processed:
1564 (pkg, provides, requires) = result
1565
1566 if pkg not in provides_files:
1567 provides_files[pkg] = []
1568 if pkg not in requires_files:
1569 requires_files[pkg] = []
1570
Brad Bishop19323692019-04-05 15:28:33 -04001571 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001572 provides_files[pkg].append(file)
1573 key = "FILERPROVIDES_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001574 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001575
Brad Bishop19323692019-04-05 15:28:33 -04001576 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001577 requires_files[pkg].append(file)
1578 key = "FILERDEPENDS_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001579 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001580
1581 for pkg in requires_files:
1582 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1583 for pkg in provides_files:
1584 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1585}
1586
1587SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs2"
1588SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1589
1590python package_do_shlibs() {
1591 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001592 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001593
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001594 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001595 if exclude_shlibs:
1596 bb.note("not generating shlibs")
1597 return
1598
Brad Bishop19323692019-04-05 15:28:33 -04001599 lib_re = re.compile(r"^.*\.so")
1600 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001601
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001602 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001603
1604 shlib_pkgs = []
1605 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1606 if exclusion_list:
1607 for pkg in packages.split():
1608 if pkg not in exclusion_list.split():
1609 shlib_pkgs.append(pkg)
1610 else:
1611 bb.note("not generating shlibs for %s" % pkg)
1612 else:
1613 shlib_pkgs = packages.split()
1614
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001615 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001616
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001617 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001618
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001619 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001620 if not ver:
1621 msg = "PKGV not defined"
1622 package_qa_handle_error("pkgv-undefined", msg, d)
1623 return
1624
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001625 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001626
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001627 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001628
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001629 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001630 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001631 needed = set()
1632 sonames = set()
1633 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001634 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001635 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001636 fd = os.popen(cmd)
1637 lines = fd.readlines()
1638 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001639 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001640 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001641 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001642 if m:
1643 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001644 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001645 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001646 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001647 if m:
1648 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001649 if dep not in needed:
1650 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001651 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001652 if m:
1653 this_soname = m.group(1)
1654 prov = (this_soname, ldir, pkgver)
1655 if not prov in sonames:
1656 # if library is private (only used by package) then do not build shlib for it
1657 if not private_libs or this_soname not in private_libs:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001658 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001659 if libdir_re.match(os.path.dirname(file)):
1660 needs_ldconfig = True
1661 if snap_symlinks and (os.path.basename(file) != this_soname):
1662 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001663 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001664
1665 def darwin_so(file, needed, sonames, renames, pkgver):
1666 if not os.path.exists(file):
1667 return
1668 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1669
1670 def get_combinations(base):
1671 #
1672 # Given a base library name, find all combinations of this split by "." and "-"
1673 #
1674 combos = []
1675 options = base.split(".")
1676 for i in range(1, len(options) + 1):
1677 combos.append(".".join(options[0:i]))
1678 options = base.split("-")
1679 for i in range(1, len(options) + 1):
1680 combos.append("-".join(options[0:i]))
1681 return combos
1682
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001683 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 -05001684 # Drop suffix
1685 name = os.path.basename(file).rsplit(".",1)[0]
1686 # Find all combinations
1687 combos = get_combinations(name)
1688 for combo in combos:
1689 if not combo in sonames:
1690 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001691 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001692 if file.endswith('.dylib') or file.endswith('.so'):
1693 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001694 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001695 out, err = p.communicate()
1696 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001697 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001698 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001699 l = l.strip()
1700 if l.startswith('path '):
1701 rpath.append(l.split()[1])
1702
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001703 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001704 out, err = p.communicate()
1705 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001706 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001707 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001708 l = l.strip()
1709 if not l or l.endswith(":"):
1710 continue
1711 if "is not an object file" in l:
1712 continue
1713 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1714 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001715 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001716
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001717 def mingw_dll(file, needed, sonames, renames, pkgver):
1718 if not os.path.exists(file):
1719 return
1720
1721 if file.endswith(".dll"):
1722 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001723 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001724
1725 if (file.endswith(".dll") or file.endswith(".exe")):
1726 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001727 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001728 out, err = p.communicate()
1729 # process the output, grabbing all .dll names
1730 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001731 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001732 dllname = m.group(1)
1733 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001734 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001735
1736 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001737 snap_symlinks = True
1738 else:
1739 snap_symlinks = False
1740
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001741 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001742
1743 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001744
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001745 # Take shared lock since we're only reading, not writing
1746 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1747 shlib_provider = oe.package.read_shlib_providers(d)
1748 bb.utils.unlockfile(lf)
1749
1750 for pkg in shlib_pkgs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001751 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001752 private_libs = private_libs.split()
1753 needs_ldconfig = False
1754 bb.debug(2, "calculating shlib provides for %s" % pkg)
1755
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001756 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001757 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001758 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001759 if not pkgver:
1760 pkgver = ver
1761
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001762 needed[pkg] = set()
1763 sonames = set()
1764 renames = []
1765 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001766 for file in pkgfiles[pkg]:
1767 soname = None
1768 if cpath.islink(file):
1769 continue
1770 if targetos == "darwin" or targetos == "darwin8":
1771 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001772 elif targetos.startswith("mingw"):
1773 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001774 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001775 linuxlist.append(file)
1776
1777 if linuxlist:
1778 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1779 for r in results:
1780 ldconfig = r[0]
1781 needed[pkg] |= r[1]
1782 sonames |= r[2]
1783 renames.extend(r[3])
1784 needs_ldconfig = needs_ldconfig or ldconfig
1785
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001786 for (old, new) in renames:
1787 bb.note("Renaming %s to %s" % (old, new))
1788 os.rename(old, new)
1789 pkgfiles[pkg].remove(old)
1790
1791 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1792 if len(sonames):
1793 fd = open(shlibs_file, 'w')
1794 for s in sonames:
1795 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1796 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1797 if old_pkg != pkg:
1798 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))
1799 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1800 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1801 if s[0] not in shlib_provider:
1802 shlib_provider[s[0]] = {}
1803 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1804 fd.close()
1805 if needs_ldconfig and use_ldconfig:
1806 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001807 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001808 if not postinst:
1809 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001810 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001811 d.setVar('pkg_postinst_%s' % pkg, postinst)
1812 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1813
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001814 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001815 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001816 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001817 for e in assumed_libs.split():
1818 l, dep_pkg = e.split(":")
1819 lib_ver = None
1820 dep_pkg = dep_pkg.rsplit("_", 1)
1821 if len(dep_pkg) == 2:
1822 lib_ver = dep_pkg[1]
1823 dep_pkg = dep_pkg[0]
1824 if l not in shlib_provider:
1825 shlib_provider[l] = {}
1826 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1827
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001828 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001829
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001830 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001831 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1832
Brad Bishop316dfdd2018-06-25 12:45:53 -04001833 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
1834 private_libs = private_libs.split()
1835
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001836 deps = list()
1837 for n in needed[pkg]:
1838 # if n is in private libraries, don't try to search provider for it
1839 # this could cause problem in case some abc.bb provides private
1840 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1841 # but skipping it is still better alternative than providing own
1842 # version and then adding runtime dependency for the same system library
1843 if private_libs and n[0] in private_libs:
1844 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1845 continue
1846 if n[0] in shlib_provider.keys():
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001847 shlib_provider_path = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001848 for k in shlib_provider[n[0]].keys():
1849 shlib_provider_path.append(k)
1850 match = None
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001851 for p in list(n[2]) + shlib_provider_path + libsearchpath:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001852 if p in shlib_provider[n[0]]:
1853 match = p
1854 break
1855 if match:
1856 (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
1857
1858 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1859
1860 if dep_pkg == pkg:
1861 continue
1862
1863 if ver_needed:
1864 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1865 else:
1866 dep = dep_pkg
1867 if not dep in deps:
1868 deps.append(dep)
1869 continue
1870 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1871
1872 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1873 if os.path.exists(deps_file):
1874 os.remove(deps_file)
1875 if len(deps):
1876 fd = open(deps_file, 'w')
Brad Bishop19323692019-04-05 15:28:33 -04001877 for dep in sorted(deps):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001878 fd.write(dep + '\n')
1879 fd.close()
1880}
1881
1882python package_do_pkgconfig () {
1883 import re
1884
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001885 packages = d.getVar('PACKAGES')
1886 workdir = d.getVar('WORKDIR')
1887 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001888
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001889 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1890 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001891
Brad Bishop19323692019-04-05 15:28:33 -04001892 pc_re = re.compile(r'(.*)\.pc$')
1893 var_re = re.compile(r'(.*)=(.*)')
1894 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001895
1896 pkgconfig_provided = {}
1897 pkgconfig_needed = {}
1898 for pkg in packages.split():
1899 pkgconfig_provided[pkg] = []
1900 pkgconfig_needed[pkg] = []
1901 for file in pkgfiles[pkg]:
1902 m = pc_re.match(file)
1903 if m:
1904 pd = bb.data.init()
1905 name = m.group(1)
1906 pkgconfig_provided[pkg].append(name)
1907 if not os.access(file, os.R_OK):
1908 continue
1909 f = open(file, 'r')
1910 lines = f.readlines()
1911 f.close()
1912 for l in lines:
1913 m = var_re.match(l)
1914 if m:
1915 name = m.group(1)
1916 val = m.group(2)
1917 pd.setVar(name, pd.expand(val))
1918 continue
1919 m = field_re.match(l)
1920 if m:
1921 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001922 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001923 if hdr == 'Requires':
1924 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1925
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001926 for pkg in packages.split():
1927 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1928 if pkgconfig_provided[pkg] != []:
1929 f = open(pkgs_file, 'w')
1930 for p in pkgconfig_provided[pkg]:
1931 f.write('%s\n' % p)
1932 f.close()
1933
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001934 # Take shared lock since we're only reading, not writing
1935 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1936
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001937 # Go from least to most specific since the last one found wins
1938 for dir in reversed(shlibs_dirs):
1939 if not os.path.exists(dir):
1940 continue
1941 for file in os.listdir(dir):
Brad Bishop19323692019-04-05 15:28:33 -04001942 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001943 if m:
1944 pkg = m.group(1)
1945 fd = open(os.path.join(dir, file))
1946 lines = fd.readlines()
1947 fd.close()
1948 pkgconfig_provided[pkg] = []
1949 for l in lines:
1950 pkgconfig_provided[pkg].append(l.rstrip())
1951
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001952 bb.utils.unlockfile(lf)
1953
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001954 for pkg in packages.split():
1955 deps = []
1956 for n in pkgconfig_needed[pkg]:
1957 found = False
1958 for k in pkgconfig_provided.keys():
1959 if n in pkgconfig_provided[k]:
1960 if k != pkg and not (k in deps):
1961 deps.append(k)
1962 found = True
1963 if found == False:
1964 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1965 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1966 if len(deps):
1967 fd = open(deps_file, 'w')
1968 for dep in deps:
1969 fd.write(dep + '\n')
1970 fd.close()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001971}
1972
1973def read_libdep_files(d):
1974 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001975 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001976 for pkg in packages:
1977 pkglibdeps[pkg] = {}
1978 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1979 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1980 if os.access(depsfile, os.R_OK):
1981 fd = open(depsfile)
1982 lines = fd.readlines()
1983 fd.close()
1984 for l in lines:
1985 l.rstrip()
1986 deps = bb.utils.explode_dep_versions2(l)
1987 for dep in deps:
1988 if not dep in pkglibdeps[pkg]:
1989 pkglibdeps[pkg][dep] = deps[dep]
1990 return pkglibdeps
1991
1992python read_shlibdeps () {
1993 pkglibdeps = read_libdep_files(d)
1994
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001995 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001996 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001997 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04001998 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001999 # Add the dep if it's not already there, or if no comparison is set
2000 if dep not in rdepends:
2001 rdepends[dep] = []
2002 for v in pkglibdeps[pkg][dep]:
2003 if v not in rdepends[dep]:
2004 rdepends[dep].append(v)
2005 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
2006}
2007
2008python package_depchains() {
2009 """
2010 For a given set of prefix and postfix modifiers, make those packages
2011 RRECOMMENDS on the corresponding packages for its RDEPENDS.
2012
2013 Example: If package A depends upon package B, and A's .bb emits an
2014 A-dev package, this would make A-dev Recommends: B-dev.
2015
2016 If only one of a given suffix is specified, it will take the RRECOMMENDS
2017 based on the RDEPENDS of *all* other packages. If more than one of a given
2018 suffix is specified, its will only use the RDEPENDS of the single parent
2019 package.
2020 """
2021
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002022 packages = d.getVar('PACKAGES')
2023 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2024 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002025
2026 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2027
2028 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002029 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002030
Brad Bishop19323692019-04-05 15:28:33 -04002031 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002032 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2033 #bb.note("Skipping %s" % depend)
2034 continue
2035 if depend.endswith('-dev'):
2036 depend = depend[:-4]
2037 if depend.endswith('-dbg'):
2038 depend = depend[:-4]
2039 pkgname = getname(depend, suffix)
2040 #bb.note("Adding %s for %s" % (pkgname, depend))
2041 if pkgname not in rreclist and pkgname != pkg:
2042 rreclist[pkgname] = []
2043
2044 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2045 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2046
2047 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2048
2049 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002050 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002051
Brad Bishop19323692019-04-05 15:28:33 -04002052 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002053 if depend.find('virtual-locale-') != -1:
2054 #bb.note("Skipping %s" % depend)
2055 continue
2056 if depend.endswith('-dev'):
2057 depend = depend[:-4]
2058 if depend.endswith('-dbg'):
2059 depend = depend[:-4]
2060 pkgname = getname(depend, suffix)
2061 #bb.note("Adding %s for %s" % (pkgname, depend))
2062 if pkgname not in rreclist and pkgname != pkg:
2063 rreclist[pkgname] = []
2064
2065 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2066 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2067
2068 def add_dep(list, dep):
2069 if dep not in list:
2070 list.append(dep)
2071
2072 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002073 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002074 add_dep(depends, dep)
2075
2076 rdepends = []
2077 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002078 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002079 add_dep(rdepends, dep)
2080
2081 #bb.note('rdepends is %s' % rdepends)
2082
2083 def post_getname(name, suffix):
2084 return '%s%s' % (name, suffix)
2085 def pre_getname(name, suffix):
2086 return '%s%s' % (suffix, name)
2087
2088 pkgs = {}
2089 for pkg in packages.split():
2090 for postfix in postfixes:
2091 if pkg.endswith(postfix):
2092 if not postfix in pkgs:
2093 pkgs[postfix] = {}
2094 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2095
2096 for prefix in prefixes:
2097 if pkg.startswith(prefix):
2098 if not prefix in pkgs:
2099 pkgs[prefix] = {}
2100 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2101
2102 if "-dbg" in pkgs:
2103 pkglibdeps = read_libdep_files(d)
2104 pkglibdeplist = []
2105 for pkg in pkglibdeps:
2106 for k in pkglibdeps[pkg]:
2107 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002108 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002109
2110 for suffix in pkgs:
2111 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002112 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002113 continue
2114 (base, func) = pkgs[suffix][pkg]
2115 if suffix == "-dev":
2116 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2117 elif suffix == "-dbg":
2118 if not dbgdefaultdeps:
2119 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2120 continue
2121 if len(pkgs[suffix]) == 1:
2122 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2123 else:
2124 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002125 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002126 add_dep(rdeps, dep)
2127 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2128}
2129
2130# Since bitbake can't determine which variables are accessed during package
2131# iteration, we need to list them here:
Andrew Geissler99467da2019-02-25 18:54:23 -06002132PACKAGEVARS = "FILES RDEPENDS RRECOMMENDS SUMMARY DESCRIPTION RSUGGESTS RPROVIDES RCONFLICTS PKG ALLOW_EMPTY pkg_postinst pkg_postrm pkg_postinst_ontarget INITSCRIPT_NAME INITSCRIPT_PARAMS DEBIAN_NOAUTONAME ALTERNATIVE PKGE PKGV PKGR USERADD_PARAM GROUPADD_PARAM CONFFILES SYSTEMD_SERVICE LICENSE SECTION pkg_preinst pkg_prerm RREPLACES GROUPMEMS_PARAM SYSTEMD_AUTO_ENABLE SKIP_FILEDEPS PRIVATE_LIBS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002133
2134def gen_packagevar(d):
2135 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002136 pkgs = (d.getVar("PACKAGES") or "").split()
2137 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002138 for p in pkgs:
2139 for v in vars:
2140 ret.append(v + "_" + p)
2141
2142 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2143 # affected recipes.
2144 ret.append('LICENSE_EXCLUSION-%s' % p)
2145 return " ".join(ret)
2146
2147PACKAGE_PREPROCESS_FUNCS ?= ""
2148# Functions for setting up PKGD
2149PACKAGEBUILDPKGD ?= " \
2150 perform_packagecopy \
2151 ${PACKAGE_PREPROCESS_FUNCS} \
2152 split_and_strip_files \
2153 fixup_perms \
2154 "
2155# Functions which split PKGD up into separate packages
2156PACKAGESPLITFUNCS ?= " \
2157 package_do_split_locales \
2158 populate_packages"
2159# Functions which process metadata based on split packages
2160PACKAGEFUNCS += " \
2161 package_fixsymlinks \
2162 package_name_hook \
2163 package_do_filedeps \
2164 package_do_shlibs \
2165 package_do_pkgconfig \
2166 read_shlibdeps \
2167 package_depchains \
2168 emit_pkgdata"
2169
2170python do_package () {
2171 # Change the following version to cause sstate to invalidate the package
2172 # cache. This is useful if an item this class depends on changes in a
2173 # way that the output of this class changes. rpmdeps is a good example
2174 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002175 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002176
2177 # Init cachedpath
2178 global cpath
2179 cpath = oe.cachedpath.CachedPath()
2180
2181 ###########################################################################
2182 # Sanity test the setup
2183 ###########################################################################
2184
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002185 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002186 if len(packages) < 1:
2187 bb.debug(1, "No packages to build, skipping do_package")
2188 return
2189
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002190 workdir = d.getVar('WORKDIR')
2191 outdir = d.getVar('DEPLOY_DIR')
2192 dest = d.getVar('D')
2193 dvar = d.getVar('PKGD')
2194 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002195
2196 if not workdir or not outdir or not dest or not dvar or not pn:
2197 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2198 package_qa_handle_error("var-undefined", msg, d)
2199 return
2200
2201 bb.build.exec_func("package_get_auto_pr", d)
2202
2203 ###########################################################################
2204 # Optimisations
2205 ###########################################################################
2206
2207 # Continually expanding complex expressions is inefficient, particularly
2208 # when we write to the datastore and invalidate the expansion cache. This
2209 # code pre-expands some frequently used variables
2210
2211 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002212 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002213
2214 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2215 expandVar(x, d)
2216
2217 ###########################################################################
2218 # Setup PKGD (from D)
2219 ###########################################################################
2220
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002221 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002222 bb.build.exec_func(f, d)
2223
2224 ###########################################################################
2225 # Split up PKGD into PKGDEST
2226 ###########################################################################
2227
2228 cpath = oe.cachedpath.CachedPath()
2229
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002230 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002231 bb.build.exec_func(f, d)
2232
2233 ###########################################################################
2234 # Process PKGDEST
2235 ###########################################################################
2236
2237 # Build global list of files in each split package
2238 global pkgfiles
2239 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002240 packages = d.getVar('PACKAGES').split()
2241 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002242 for pkg in packages:
2243 pkgfiles[pkg] = []
2244 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2245 for file in files:
2246 pkgfiles[pkg].append(walkroot + os.sep + file)
2247
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002248 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002249 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002250
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002251 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002252 if not qa_sane:
2253 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002254}
2255
2256do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2257do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2258addtask package after do_install
2259
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002260SSTATETASKS += "do_package"
2261do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2262do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002263do_package_setscene[dirs] = "${STAGING_DIR}"
2264
2265python do_package_setscene () {
2266 sstate_setscene(d)
2267}
2268addtask do_package_setscene
2269
2270do_packagedata () {
2271 :
2272}
2273
2274addtask packagedata before do_build after do_package
2275
2276SSTATETASKS += "do_packagedata"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002277# PACKAGELOCK protects readers of PKGDATA_DIR against writes
2278# whilst code is reading in do_package
2279PACKAGELOCK = "${STAGING_DIR}/package-output.lock"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002280do_packagedata[sstate-inputdirs] = "${PKGDESTWORK}"
2281do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002282do_packagedata[sstate-lockfile] = "${PACKAGELOCK}"
2283do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002284
2285python do_packagedata_setscene () {
2286 sstate_setscene(d)
2287}
2288addtask do_packagedata_setscene
2289
2290#
2291# Helper functions for the package writing classes
2292#
2293
2294def mapping_rename_hook(d):
2295 """
2296 Rewrite variables to account for package renaming in things
2297 like debian.bbclass or manual PKG variable name changes
2298 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002299 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002300 runtime_mapping_rename("RDEPENDS", pkg, d)
2301 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2302 runtime_mapping_rename("RSUGGESTS", pkg, d)