blob: 20d72bba799218985079fc9657f2cd29cefedd78 [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)
Brad Bishop15ae2502019-06-18 21:44:24 -04001008
1009 # Sort results by file path. This ensures that the files are always
1010 # processed in the same order, which is important to make sure builds
1011 # are reproducible when dealing with hardlinks
1012 results.sort(key=lambda x: x[0])
1013
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001014 for (file, elf_file) in results:
1015 # It's a file (or hardlink), not a link
1016 # ...but is it ELF, and is it already stripped?
1017 if elf_file & 1:
1018 if elf_file & 2:
1019 if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
1020 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1021 else:
1022 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
1023 package_qa_handle_error("already-stripped", msg, d)
1024 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001025
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001026 # At this point we have an unstripped elf file. We need to:
1027 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1028 # b) Only strip any hardlinked file once (no races)
1029 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1030
1031 # Use a reference of device ID and inode number to identify files
1032 file_reference = checkelf[file][1]
1033 if file_reference in inodes:
1034 os.unlink(file)
1035 os.link(inodes[file_reference][0], file)
1036 inodes[file_reference].append(file)
1037 else:
1038 inodes[file_reference] = [file]
1039 # break hardlink
1040 bb.utils.break_hardlinks(file)
1041 elffiles[file] = elf_file
1042 # Modified the file so clear the cache
1043 cpath.updatecache(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001044
1045 #
1046 # First lets process debug splitting
1047 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001048 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop19323692019-04-05 15:28:33 -04001049 results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001050
Brad Bishop316dfdd2018-06-25 12:45:53 -04001051 if debugsrcdir and not targetos.startswith("mingw"):
1052 for file in staticlibs:
Brad Bishop19323692019-04-05 15:28:33 -04001053 results.extend(source_info(file, d, fatal=False))
1054
1055 sources = set()
1056 for r in results:
1057 sources.update(r[1])
Brad Bishop316dfdd2018-06-25 12:45:53 -04001058
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001059 # Hardlink our debug symbols to the other hardlink copies
1060 for ref in inodes:
1061 if len(inodes[ref]) == 1:
1062 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001063
1064 target = inodes[ref][0][len(dvar):]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001065 for file in inodes[ref][1:]:
1066 src = file[len(dvar):]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001067 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(target) + debugappend
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001068 fpath = dvar + dest
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001069 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1070 bb.utils.mkdirhier(os.path.dirname(fpath))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001071 # Only one hardlink of separated debug info file in each directory
1072 if not os.access(fpath, os.R_OK):
1073 #bb.note("Link %s -> %s" % (fpath, ftarget))
1074 os.link(ftarget, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001075
1076 # Create symlinks for all cases we were able to split symbols
1077 for file in symlinks:
1078 src = file[len(dvar):]
1079 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1080 fpath = dvar + dest
1081 # Skip it if the target doesn't exist
1082 try:
1083 s = os.stat(fpath)
1084 except OSError as e:
1085 (err, strerror) = e.args
1086 if err != errno.ENOENT:
1087 raise
1088 continue
1089
1090 ltarget = symlinks[file]
1091 lpath = os.path.dirname(ltarget)
1092 lbase = os.path.basename(ltarget)
1093 ftarget = ""
1094 if lpath and lpath != ".":
1095 ftarget += lpath + debugdir + "/"
1096 ftarget += lbase + debugappend
1097 if lpath.startswith(".."):
1098 ftarget = os.path.join("..", ftarget)
1099 bb.utils.mkdirhier(os.path.dirname(fpath))
1100 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1101 os.symlink(ftarget, fpath)
1102
1103 # Process the debugsrcdir if requested...
1104 # This copies and places the referenced sources for later debugging...
Brad Bishop19323692019-04-05 15:28:33 -04001105 copydebugsources(debugsrcdir, sources, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001106 #
1107 # End of debug splitting
1108 #
1109
1110 #
1111 # Now lets go back over things and strip them
1112 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001113 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1114 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001115 sfiles = []
1116 for file in elffiles:
1117 elf_file = int(elffiles[file])
1118 #bb.note("Strip %s" % file)
1119 sfiles.append((file, elf_file, strip))
1120 for f in kernmods:
1121 sfiles.append((f, 16, strip))
1122
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001123 oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001124
1125 #
1126 # End of strip
1127 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001128 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001129}
1130
1131python populate_packages () {
1132 import glob, re
1133
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001134 workdir = d.getVar('WORKDIR')
1135 outdir = d.getVar('DEPLOY_DIR')
1136 dvar = d.getVar('PKGD')
Brad Bishop19323692019-04-05 15:28:33 -04001137 packages = d.getVar('PACKAGES').split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001138 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001139
1140 bb.utils.mkdirhier(outdir)
1141 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001142
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001143 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001144
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001145 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1146
Brad Bishop19323692019-04-05 15:28:33 -04001147 # If debug-with-srcpkg mode is enabled then add the source package if it
1148 # doesn't exist and add the source file contents to the source package.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001149 if split_source_package:
1150 src_package_name = ('%s-src' % d.getVar('PN'))
Brad Bishop19323692019-04-05 15:28:33 -04001151 if not src_package_name in packages:
1152 packages.append(src_package_name)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001153 d.setVar('FILES_%s' % src_package_name, '/usr/src/debug')
1154
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001155 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001156 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001157 package_dict = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001158
Brad Bishop19323692019-04-05 15:28:33 -04001159 for i, pkg in enumerate(packages):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001160 if pkg in package_dict:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001161 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
1162 package_qa_handle_error("packages-list", msg, d)
Brad Bishop19323692019-04-05 15:28:33 -04001163 # Ensure the source package gets the chance to pick up the source files
1164 # before the debug package by ordering it first in PACKAGES. Whether it
1165 # actually picks up any source files is controlled by
1166 # PACKAGE_DEBUG_SPLIT_STYLE.
1167 elif pkg.endswith("-src"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001168 package_dict[pkg] = (10, i)
1169 elif autodebug and pkg.endswith("-dbg"):
1170 package_dict[pkg] = (30, i)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001171 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001172 package_dict[pkg] = (50, i)
Brad Bishop19323692019-04-05 15:28:33 -04001173 packages = sorted(package_dict.keys(), key=package_dict.get)
1174 d.setVar('PACKAGES', ' '.join(packages))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001175 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001176
1177 seen = []
1178
1179 # os.mkdir masks the permissions with umask so we have to unset it first
1180 oldumask = os.umask(0)
1181
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001182 debug = []
1183 for root, dirs, files in cpath.walk(dvar):
1184 dir = root[len(dvar):]
1185 if not dir:
1186 dir = os.sep
1187 for f in (files + dirs):
1188 path = "." + os.path.join(dir, f)
1189 if "/.debug/" in path or path.endswith("/.debug"):
1190 debug.append(path)
1191
Brad Bishop19323692019-04-05 15:28:33 -04001192 for pkg in packages:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001193 root = os.path.join(pkgdest, pkg)
1194 bb.utils.mkdirhier(root)
1195
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001196 filesvar = d.getVar('FILES_%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001197 if "//" in filesvar:
1198 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
1199 package_qa_handle_error("files-invalid", msg, d)
1200 filesvar.replace("//", "/")
1201
1202 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001203 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001204
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001205 if autodebug and pkg.endswith("-dbg"):
1206 files.extend(debug)
1207
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001208 for file in files:
1209 if (not cpath.islink(file)) and (not cpath.exists(file)):
1210 continue
1211 if file in seen:
1212 continue
1213 seen.append(file)
1214
1215 def mkdir(src, dest, p):
1216 src = os.path.join(src, p)
1217 dest = os.path.join(dest, p)
1218 fstat = cpath.stat(src)
1219 os.mkdir(dest, fstat.st_mode)
1220 os.chown(dest, fstat.st_uid, fstat.st_gid)
1221 if p not in seen:
1222 seen.append(p)
1223 cpath.updatecache(dest)
1224
1225 def mkdir_recurse(src, dest, paths):
1226 if cpath.exists(dest + '/' + paths):
1227 return
1228 while paths.startswith("./"):
1229 paths = paths[2:]
1230 p = "."
1231 for c in paths.split("/"):
1232 p = os.path.join(p, c)
1233 if not cpath.exists(os.path.join(dest, p)):
1234 mkdir(src, dest, p)
1235
1236 if cpath.isdir(file) and not cpath.islink(file):
1237 mkdir_recurse(dvar, root, file)
1238 continue
1239
1240 mkdir_recurse(dvar, root, os.path.dirname(file))
1241 fpath = os.path.join(root,file)
1242 if not cpath.islink(file):
1243 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001244 continue
1245 ret = bb.utils.copyfile(file, fpath)
1246 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001247 bb.fatal("File population failed")
1248
1249 # Check if symlink paths exist
1250 for file in symlink_paths:
1251 if not os.path.exists(os.path.join(root,file)):
1252 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1253 "parent directory structure does not exist. One of "
1254 "its parent directories is a symlink whose target "
1255 "directory is not included in the package." %
1256 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001257
1258 os.umask(oldumask)
1259 os.chdir(workdir)
1260
1261 # Handle LICENSE_EXCLUSION
1262 package_list = []
Brad Bishop19323692019-04-05 15:28:33 -04001263 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001264 if d.getVar('LICENSE_EXCLUSION-' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001265 msg = "%s has an incompatible license. Excluding from packaging." % pkg
1266 package_qa_handle_error("incompatible-license", msg, d)
1267 else:
1268 package_list.append(pkg)
1269 d.setVar('PACKAGES', ' '.join(package_list))
1270
1271 unshipped = []
1272 for root, dirs, files in cpath.walk(dvar):
1273 dir = root[len(dvar):]
1274 if not dir:
1275 dir = os.sep
1276 for f in (files + dirs):
1277 path = os.path.join(dir, f)
1278 if ('.' + path) not in seen:
1279 unshipped.append(path)
1280
1281 if unshipped != []:
1282 msg = pn + ": Files/directories were installed but not shipped in any package:"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001283 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001284 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1285 else:
1286 for f in unshipped:
1287 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001288 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"
1289 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001290 package_qa_handle_error("installed-vs-shipped", msg, d)
1291}
1292populate_packages[dirs] = "${D}"
1293
1294python package_fixsymlinks () {
1295 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001296 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001297 packages = d.getVar("PACKAGES", False).split()
1298
1299 dangling_links = {}
1300 pkg_files = {}
1301 for pkg in packages:
1302 dangling_links[pkg] = []
1303 pkg_files[pkg] = []
1304 inst_root = os.path.join(pkgdest, pkg)
1305 for path in pkgfiles[pkg]:
1306 rpath = path[len(inst_root):]
1307 pkg_files[pkg].append(rpath)
1308 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1309 if not cpath.lexists(rtarget):
1310 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1311
1312 newrdepends = {}
1313 for pkg in dangling_links:
1314 for l in dangling_links[pkg]:
1315 found = False
1316 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1317 for p in packages:
1318 if l in pkg_files[p]:
1319 found = True
1320 bb.debug(1, "target found in %s" % p)
1321 if p == pkg:
1322 break
1323 if pkg not in newrdepends:
1324 newrdepends[pkg] = []
1325 newrdepends[pkg].append(p)
1326 break
1327 if found == False:
1328 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1329
1330 for pkg in newrdepends:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001331 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001332 for p in newrdepends[pkg]:
1333 if p not in rdepends:
1334 rdepends[p] = []
1335 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1336}
1337
1338
1339python package_package_name_hook() {
1340 """
1341 A package_name_hook function can be used to rewrite the package names by
1342 changing PKG. For an example, see debian.bbclass.
1343 """
1344 pass
1345}
1346
1347EXPORT_FUNCTIONS package_name_hook
1348
1349
1350PKGDESTWORK = "${WORKDIR}/pkgdata"
1351
Brad Bishop15ae2502019-06-18 21:44:24 -04001352PKGDATA_VARS = "PN PE PV PR PKGE PKGV PKGR LICENSE DESCRIPTION SUMMARY RDEPENDS RPROVIDES RRECOMMENDS RSUGGESTS RREPLACES RCONFLICTS SECTION PKG ALLOW_EMPTY FILES CONFFILES FILES_INFO pkg_postinst pkg_postrm pkg_preinst pkg_prerm"
1353
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001354python emit_pkgdata() {
1355 from glob import glob
1356 import json
1357
Brad Bishop316dfdd2018-06-25 12:45:53 -04001358 def process_postinst_on_target(pkg, mlprefix):
1359 defer_fragment = """
1360if [ -n "$D" ]; then
1361 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1362 exit 0
1363fi
1364""" % (pkg, mlprefix)
1365
1366 postinst = d.getVar('pkg_postinst_%s' % pkg)
1367 postinst_ontarget = d.getVar('pkg_postinst_ontarget_%s' % pkg)
1368
1369 if postinst_ontarget:
1370 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1371 if not postinst:
1372 postinst = '#!/bin/sh\n'
1373 postinst += defer_fragment
1374 postinst += postinst_ontarget
1375 d.setVar('pkg_postinst_%s' % pkg, postinst)
1376
1377 def add_set_e_to_scriptlets(pkg):
1378 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
1379 scriptlet = d.getVar('%s_%s' % (scriptlet_name, pkg))
1380 if scriptlet:
1381 scriptlet_split = scriptlet.split('\n')
1382 if scriptlet_split[0].startswith("#!"):
1383 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1384 else:
1385 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
1386 d.setVar('%s_%s' % (scriptlet_name, pkg), scriptlet)
1387
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001388 def write_if_exists(f, pkg, var):
1389 def encode(str):
1390 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001391 c = codecs.getencoder("unicode_escape")
1392 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001393
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001394 val = d.getVar('%s_%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001395 if val:
1396 f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
1397 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001398 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001399 if val:
1400 f.write('%s: %s\n' % (var, encode(val)))
1401 return val
1402
1403 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1404 for variant in variants:
1405 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1406 fd.write("PACKAGES: %s\n" % ' '.join(
1407 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1408
1409 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1410 for variant in variants:
1411 for pkg in packages.split():
1412 ml_pkg = "%s-%s" % (variant, pkg)
1413 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1414 with open(subdata_file, 'w') as fd:
1415 fd.write("PKG_%s: %s" % (ml_pkg, pkg))
1416
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001417 packages = d.getVar('PACKAGES')
1418 pkgdest = d.getVar('PKGDEST')
1419 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001420
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001421 data_file = pkgdatadir + d.expand("/${PN}" )
1422 f = open(data_file, 'w')
1423 f.write("PACKAGES: %s\n" % packages)
1424 f.close()
1425
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001426 pn = d.getVar('PN')
1427 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1428 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001429
1430 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1431 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1432
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001433 if bb.data.inherits_class('allarch', d) and not variants \
1434 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001435 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1436
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001437 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001438
1439 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001440 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001441 if pkgval is None:
1442 pkgval = pkg
1443 d.setVar('PKG_%s' % pkg, pkg)
1444
1445 pkgdestpkg = os.path.join(pkgdest, pkg)
1446 files = {}
1447 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001448 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001449 for f in pkgfiles[pkg]:
1450 relpth = os.path.relpath(f, pkgdestpkg)
1451 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001452 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001453 if fstat.st_ino not in seen:
1454 seen.add(fstat.st_ino)
1455 total_size += fstat.st_size
Brad Bishop19323692019-04-05 15:28:33 -04001456 d.setVar('FILES_INFO', json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001457
Brad Bishop316dfdd2018-06-25 12:45:53 -04001458 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1459 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001460
Brad Bishop15ae2502019-06-18 21:44:24 -04001461 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1462 with open(subdata_file, 'w') as sf:
1463 for var in (d.getVar('PKGDATA_VARS') or "").split():
1464 val = write_if_exists(sf, pkg, var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001465
Brad Bishop15ae2502019-06-18 21:44:24 -04001466 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1467 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
1468 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1469
1470 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
1471 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
1472 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1473
1474 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001475
1476 # Symlinks needed for rprovides lookup
Brad Bishop15ae2502019-06-18 21:44:24 -04001477 rprov = d.getVar('RPROVIDES_%s' % pkg) or d.getVar('RPROVIDES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001478 if rprov:
1479 for p in rprov.strip().split():
1480 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1481 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1482 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1483
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001484 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001485 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001486 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001487 root = "%s/%s" % (pkgdest, pkg)
1488 os.chdir(root)
1489 g = glob('*')
1490 if g or allow_empty == "1":
1491 # Symlinks needed for reverse lookups (from the final package name)
1492 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1493 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1494
1495 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1496 open(packagedfile, 'w').close()
1497
1498 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1499 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1500
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001501 if bb.data.inherits_class('allarch', d) and not variants \
1502 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001503 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1504
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001505}
1506emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1507
1508ldconfig_postinst_fragment() {
1509if [ x"$D" = "x" ]; then
1510 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1511fi
1512}
1513
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001514RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001515
1516# Collect perfile run-time dependency metadata
1517# Output:
1518# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1519# FILERPROVIDES_filepath_pkg - per file dep
1520#
1521# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1522# FILERDEPENDS_filepath_pkg - per file dep
1523
1524python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001525 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001526 return
1527
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001528 pkgdest = d.getVar('PKGDEST')
1529 packages = d.getVar('PACKAGES')
1530 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001531
1532 def chunks(files, n):
1533 return [files[i:i+n] for i in range(0, len(files), n)]
1534
1535 pkglist = []
1536 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001537 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001538 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001539 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 -05001540 continue
1541 for files in chunks(pkgfiles[pkg], 100):
1542 pkglist.append((pkg, files, rpmdeps, pkgdest))
1543
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001544 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001545
1546 provides_files = {}
1547 requires_files = {}
1548
1549 for result in processed:
1550 (pkg, provides, requires) = result
1551
1552 if pkg not in provides_files:
1553 provides_files[pkg] = []
1554 if pkg not in requires_files:
1555 requires_files[pkg] = []
1556
Brad Bishop19323692019-04-05 15:28:33 -04001557 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001558 provides_files[pkg].append(file)
1559 key = "FILERPROVIDES_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001560 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001561
Brad Bishop19323692019-04-05 15:28:33 -04001562 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001563 requires_files[pkg].append(file)
1564 key = "FILERDEPENDS_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001565 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001566
1567 for pkg in requires_files:
1568 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1569 for pkg in provides_files:
1570 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1571}
1572
1573SHLIBSDIRS = "${PKGDATA_DIR}/${MLPREFIX}shlibs2"
1574SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1575
1576python package_do_shlibs() {
1577 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001578 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001579
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001580 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001581 if exclude_shlibs:
1582 bb.note("not generating shlibs")
1583 return
1584
Brad Bishop19323692019-04-05 15:28:33 -04001585 lib_re = re.compile(r"^.*\.so")
1586 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001587
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001588 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001589
1590 shlib_pkgs = []
1591 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1592 if exclusion_list:
1593 for pkg in packages.split():
1594 if pkg not in exclusion_list.split():
1595 shlib_pkgs.append(pkg)
1596 else:
1597 bb.note("not generating shlibs for %s" % pkg)
1598 else:
1599 shlib_pkgs = packages.split()
1600
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001601 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001602
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001603 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001604
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001605 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001606 if not ver:
1607 msg = "PKGV not defined"
1608 package_qa_handle_error("pkgv-undefined", msg, d)
1609 return
1610
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001611 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001612
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001613 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001614
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001615 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001616 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001617 needed = set()
1618 sonames = set()
1619 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001620 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001621 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001622 fd = os.popen(cmd)
1623 lines = fd.readlines()
1624 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001625 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001626 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001627 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001628 if m:
1629 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001630 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001631 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001632 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001633 if m:
1634 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001635 if dep not in needed:
1636 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001637 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001638 if m:
1639 this_soname = m.group(1)
1640 prov = (this_soname, ldir, pkgver)
1641 if not prov in sonames:
1642 # if library is private (only used by package) then do not build shlib for it
1643 if not private_libs or this_soname not in private_libs:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001644 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001645 if libdir_re.match(os.path.dirname(file)):
1646 needs_ldconfig = True
1647 if snap_symlinks and (os.path.basename(file) != this_soname):
1648 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001649 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001650
1651 def darwin_so(file, needed, sonames, renames, pkgver):
1652 if not os.path.exists(file):
1653 return
1654 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1655
1656 def get_combinations(base):
1657 #
1658 # Given a base library name, find all combinations of this split by "." and "-"
1659 #
1660 combos = []
1661 options = base.split(".")
1662 for i in range(1, len(options) + 1):
1663 combos.append(".".join(options[0:i]))
1664 options = base.split("-")
1665 for i in range(1, len(options) + 1):
1666 combos.append("-".join(options[0:i]))
1667 return combos
1668
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001669 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 -05001670 # Drop suffix
1671 name = os.path.basename(file).rsplit(".",1)[0]
1672 # Find all combinations
1673 combos = get_combinations(name)
1674 for combo in combos:
1675 if not combo in sonames:
1676 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001677 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001678 if file.endswith('.dylib') or file.endswith('.so'):
1679 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001680 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001681 out, err = p.communicate()
1682 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001683 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001684 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001685 l = l.strip()
1686 if l.startswith('path '):
1687 rpath.append(l.split()[1])
1688
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001689 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001690 out, err = p.communicate()
1691 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001692 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001693 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001694 l = l.strip()
1695 if not l or l.endswith(":"):
1696 continue
1697 if "is not an object file" in l:
1698 continue
1699 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1700 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001701 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001702
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001703 def mingw_dll(file, needed, sonames, renames, pkgver):
1704 if not os.path.exists(file):
1705 return
1706
1707 if file.endswith(".dll"):
1708 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001709 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001710
1711 if (file.endswith(".dll") or file.endswith(".exe")):
1712 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001713 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001714 out, err = p.communicate()
1715 # process the output, grabbing all .dll names
1716 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001717 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001718 dllname = m.group(1)
1719 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001720 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001721
1722 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001723 snap_symlinks = True
1724 else:
1725 snap_symlinks = False
1726
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001727 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001728
1729 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001730
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001731 # Take shared lock since we're only reading, not writing
1732 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1733 shlib_provider = oe.package.read_shlib_providers(d)
1734 bb.utils.unlockfile(lf)
1735
1736 for pkg in shlib_pkgs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001737 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001738 private_libs = private_libs.split()
1739 needs_ldconfig = False
1740 bb.debug(2, "calculating shlib provides for %s" % pkg)
1741
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001742 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001743 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001744 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001745 if not pkgver:
1746 pkgver = ver
1747
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001748 needed[pkg] = set()
1749 sonames = set()
1750 renames = []
1751 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001752 for file in pkgfiles[pkg]:
1753 soname = None
1754 if cpath.islink(file):
1755 continue
1756 if targetos == "darwin" or targetos == "darwin8":
1757 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001758 elif targetos.startswith("mingw"):
1759 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001760 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001761 linuxlist.append(file)
1762
1763 if linuxlist:
1764 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1765 for r in results:
1766 ldconfig = r[0]
1767 needed[pkg] |= r[1]
1768 sonames |= r[2]
1769 renames.extend(r[3])
1770 needs_ldconfig = needs_ldconfig or ldconfig
1771
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001772 for (old, new) in renames:
1773 bb.note("Renaming %s to %s" % (old, new))
1774 os.rename(old, new)
1775 pkgfiles[pkg].remove(old)
1776
1777 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1778 if len(sonames):
1779 fd = open(shlibs_file, 'w')
1780 for s in sonames:
1781 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1782 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1783 if old_pkg != pkg:
1784 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))
1785 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1786 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1787 if s[0] not in shlib_provider:
1788 shlib_provider[s[0]] = {}
1789 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1790 fd.close()
1791 if needs_ldconfig and use_ldconfig:
1792 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001793 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001794 if not postinst:
1795 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001796 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001797 d.setVar('pkg_postinst_%s' % pkg, postinst)
1798 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1799
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001800 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001801 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001802 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001803 for e in assumed_libs.split():
1804 l, dep_pkg = e.split(":")
1805 lib_ver = None
1806 dep_pkg = dep_pkg.rsplit("_", 1)
1807 if len(dep_pkg) == 2:
1808 lib_ver = dep_pkg[1]
1809 dep_pkg = dep_pkg[0]
1810 if l not in shlib_provider:
1811 shlib_provider[l] = {}
1812 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1813
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001814 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001815
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001816 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001817 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1818
Brad Bishop316dfdd2018-06-25 12:45:53 -04001819 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
1820 private_libs = private_libs.split()
1821
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001822 deps = list()
1823 for n in needed[pkg]:
1824 # if n is in private libraries, don't try to search provider for it
1825 # this could cause problem in case some abc.bb provides private
1826 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1827 # but skipping it is still better alternative than providing own
1828 # version and then adding runtime dependency for the same system library
1829 if private_libs and n[0] in private_libs:
1830 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1831 continue
1832 if n[0] in shlib_provider.keys():
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001833 shlib_provider_path = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001834 for k in shlib_provider[n[0]].keys():
1835 shlib_provider_path.append(k)
1836 match = None
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001837 for p in list(n[2]) + shlib_provider_path + libsearchpath:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001838 if p in shlib_provider[n[0]]:
1839 match = p
1840 break
1841 if match:
1842 (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
1843
1844 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1845
1846 if dep_pkg == pkg:
1847 continue
1848
1849 if ver_needed:
1850 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1851 else:
1852 dep = dep_pkg
1853 if not dep in deps:
1854 deps.append(dep)
1855 continue
1856 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1857
1858 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1859 if os.path.exists(deps_file):
1860 os.remove(deps_file)
1861 if len(deps):
1862 fd = open(deps_file, 'w')
Brad Bishop19323692019-04-05 15:28:33 -04001863 for dep in sorted(deps):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001864 fd.write(dep + '\n')
1865 fd.close()
1866}
1867
1868python package_do_pkgconfig () {
1869 import re
1870
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001871 packages = d.getVar('PACKAGES')
1872 workdir = d.getVar('WORKDIR')
1873 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001874
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001875 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1876 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001877
Brad Bishop19323692019-04-05 15:28:33 -04001878 pc_re = re.compile(r'(.*)\.pc$')
1879 var_re = re.compile(r'(.*)=(.*)')
1880 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001881
1882 pkgconfig_provided = {}
1883 pkgconfig_needed = {}
1884 for pkg in packages.split():
1885 pkgconfig_provided[pkg] = []
1886 pkgconfig_needed[pkg] = []
1887 for file in pkgfiles[pkg]:
1888 m = pc_re.match(file)
1889 if m:
1890 pd = bb.data.init()
1891 name = m.group(1)
1892 pkgconfig_provided[pkg].append(name)
1893 if not os.access(file, os.R_OK):
1894 continue
1895 f = open(file, 'r')
1896 lines = f.readlines()
1897 f.close()
1898 for l in lines:
1899 m = var_re.match(l)
1900 if m:
1901 name = m.group(1)
1902 val = m.group(2)
1903 pd.setVar(name, pd.expand(val))
1904 continue
1905 m = field_re.match(l)
1906 if m:
1907 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001908 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001909 if hdr == 'Requires':
1910 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1911
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001912 for pkg in packages.split():
1913 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1914 if pkgconfig_provided[pkg] != []:
1915 f = open(pkgs_file, 'w')
1916 for p in pkgconfig_provided[pkg]:
1917 f.write('%s\n' % p)
1918 f.close()
1919
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001920 # Take shared lock since we're only reading, not writing
1921 lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
1922
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001923 # Go from least to most specific since the last one found wins
1924 for dir in reversed(shlibs_dirs):
1925 if not os.path.exists(dir):
1926 continue
1927 for file in os.listdir(dir):
Brad Bishop19323692019-04-05 15:28:33 -04001928 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001929 if m:
1930 pkg = m.group(1)
1931 fd = open(os.path.join(dir, file))
1932 lines = fd.readlines()
1933 fd.close()
1934 pkgconfig_provided[pkg] = []
1935 for l in lines:
1936 pkgconfig_provided[pkg].append(l.rstrip())
1937
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001938 bb.utils.unlockfile(lf)
1939
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001940 for pkg in packages.split():
1941 deps = []
1942 for n in pkgconfig_needed[pkg]:
1943 found = False
1944 for k in pkgconfig_provided.keys():
1945 if n in pkgconfig_provided[k]:
1946 if k != pkg and not (k in deps):
1947 deps.append(k)
1948 found = True
1949 if found == False:
1950 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1951 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1952 if len(deps):
1953 fd = open(deps_file, 'w')
1954 for dep in deps:
1955 fd.write(dep + '\n')
1956 fd.close()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001957}
1958
1959def read_libdep_files(d):
1960 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001961 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001962 for pkg in packages:
1963 pkglibdeps[pkg] = {}
1964 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1965 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1966 if os.access(depsfile, os.R_OK):
1967 fd = open(depsfile)
1968 lines = fd.readlines()
1969 fd.close()
1970 for l in lines:
1971 l.rstrip()
1972 deps = bb.utils.explode_dep_versions2(l)
1973 for dep in deps:
1974 if not dep in pkglibdeps[pkg]:
1975 pkglibdeps[pkg][dep] = deps[dep]
1976 return pkglibdeps
1977
1978python read_shlibdeps () {
1979 pkglibdeps = read_libdep_files(d)
1980
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001981 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001982 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001983 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04001984 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001985 # Add the dep if it's not already there, or if no comparison is set
1986 if dep not in rdepends:
1987 rdepends[dep] = []
1988 for v in pkglibdeps[pkg][dep]:
1989 if v not in rdepends[dep]:
1990 rdepends[dep].append(v)
1991 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1992}
1993
1994python package_depchains() {
1995 """
1996 For a given set of prefix and postfix modifiers, make those packages
1997 RRECOMMENDS on the corresponding packages for its RDEPENDS.
1998
1999 Example: If package A depends upon package B, and A's .bb emits an
2000 A-dev package, this would make A-dev Recommends: B-dev.
2001
2002 If only one of a given suffix is specified, it will take the RRECOMMENDS
2003 based on the RDEPENDS of *all* other packages. If more than one of a given
2004 suffix is specified, its will only use the RDEPENDS of the single parent
2005 package.
2006 """
2007
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002008 packages = d.getVar('PACKAGES')
2009 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2010 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002011
2012 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2013
2014 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002015 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002016
Brad Bishop19323692019-04-05 15:28:33 -04002017 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002018 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2019 #bb.note("Skipping %s" % depend)
2020 continue
2021 if depend.endswith('-dev'):
2022 depend = depend[:-4]
2023 if depend.endswith('-dbg'):
2024 depend = depend[:-4]
2025 pkgname = getname(depend, suffix)
2026 #bb.note("Adding %s for %s" % (pkgname, depend))
2027 if pkgname not in rreclist and pkgname != pkg:
2028 rreclist[pkgname] = []
2029
2030 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2031 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2032
2033 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2034
2035 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002036 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002037
Brad Bishop19323692019-04-05 15:28:33 -04002038 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002039 if depend.find('virtual-locale-') != -1:
2040 #bb.note("Skipping %s" % depend)
2041 continue
2042 if depend.endswith('-dev'):
2043 depend = depend[:-4]
2044 if depend.endswith('-dbg'):
2045 depend = depend[:-4]
2046 pkgname = getname(depend, suffix)
2047 #bb.note("Adding %s for %s" % (pkgname, depend))
2048 if pkgname not in rreclist and pkgname != pkg:
2049 rreclist[pkgname] = []
2050
2051 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2052 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2053
2054 def add_dep(list, dep):
2055 if dep not in list:
2056 list.append(dep)
2057
2058 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002059 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002060 add_dep(depends, dep)
2061
2062 rdepends = []
2063 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002064 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002065 add_dep(rdepends, dep)
2066
2067 #bb.note('rdepends is %s' % rdepends)
2068
2069 def post_getname(name, suffix):
2070 return '%s%s' % (name, suffix)
2071 def pre_getname(name, suffix):
2072 return '%s%s' % (suffix, name)
2073
2074 pkgs = {}
2075 for pkg in packages.split():
2076 for postfix in postfixes:
2077 if pkg.endswith(postfix):
2078 if not postfix in pkgs:
2079 pkgs[postfix] = {}
2080 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2081
2082 for prefix in prefixes:
2083 if pkg.startswith(prefix):
2084 if not prefix in pkgs:
2085 pkgs[prefix] = {}
2086 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2087
2088 if "-dbg" in pkgs:
2089 pkglibdeps = read_libdep_files(d)
2090 pkglibdeplist = []
2091 for pkg in pkglibdeps:
2092 for k in pkglibdeps[pkg]:
2093 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002094 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002095
2096 for suffix in pkgs:
2097 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002098 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002099 continue
2100 (base, func) = pkgs[suffix][pkg]
2101 if suffix == "-dev":
2102 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2103 elif suffix == "-dbg":
2104 if not dbgdefaultdeps:
2105 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2106 continue
2107 if len(pkgs[suffix]) == 1:
2108 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2109 else:
2110 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002111 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002112 add_dep(rdeps, dep)
2113 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2114}
2115
2116# Since bitbake can't determine which variables are accessed during package
2117# iteration, we need to list them here:
Andrew Geissler99467da2019-02-25 18:54:23 -06002118PACKAGEVARS = "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 -05002119
2120def gen_packagevar(d):
2121 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002122 pkgs = (d.getVar("PACKAGES") or "").split()
2123 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002124 for p in pkgs:
2125 for v in vars:
2126 ret.append(v + "_" + p)
2127
2128 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2129 # affected recipes.
2130 ret.append('LICENSE_EXCLUSION-%s' % p)
2131 return " ".join(ret)
2132
2133PACKAGE_PREPROCESS_FUNCS ?= ""
2134# Functions for setting up PKGD
2135PACKAGEBUILDPKGD ?= " \
2136 perform_packagecopy \
2137 ${PACKAGE_PREPROCESS_FUNCS} \
2138 split_and_strip_files \
2139 fixup_perms \
2140 "
2141# Functions which split PKGD up into separate packages
2142PACKAGESPLITFUNCS ?= " \
2143 package_do_split_locales \
2144 populate_packages"
2145# Functions which process metadata based on split packages
2146PACKAGEFUNCS += " \
2147 package_fixsymlinks \
2148 package_name_hook \
2149 package_do_filedeps \
2150 package_do_shlibs \
2151 package_do_pkgconfig \
2152 read_shlibdeps \
2153 package_depchains \
2154 emit_pkgdata"
2155
2156python do_package () {
2157 # Change the following version to cause sstate to invalidate the package
2158 # cache. This is useful if an item this class depends on changes in a
2159 # way that the output of this class changes. rpmdeps is a good example
2160 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002161 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002162
2163 # Init cachedpath
2164 global cpath
2165 cpath = oe.cachedpath.CachedPath()
2166
2167 ###########################################################################
2168 # Sanity test the setup
2169 ###########################################################################
2170
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002171 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002172 if len(packages) < 1:
2173 bb.debug(1, "No packages to build, skipping do_package")
2174 return
2175
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002176 workdir = d.getVar('WORKDIR')
2177 outdir = d.getVar('DEPLOY_DIR')
2178 dest = d.getVar('D')
2179 dvar = d.getVar('PKGD')
2180 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002181
2182 if not workdir or not outdir or not dest or not dvar or not pn:
2183 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2184 package_qa_handle_error("var-undefined", msg, d)
2185 return
2186
2187 bb.build.exec_func("package_get_auto_pr", d)
2188
2189 ###########################################################################
2190 # Optimisations
2191 ###########################################################################
2192
2193 # Continually expanding complex expressions is inefficient, particularly
2194 # when we write to the datastore and invalidate the expansion cache. This
2195 # code pre-expands some frequently used variables
2196
2197 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002198 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002199
2200 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2201 expandVar(x, d)
2202
2203 ###########################################################################
2204 # Setup PKGD (from D)
2205 ###########################################################################
2206
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002207 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002208 bb.build.exec_func(f, d)
2209
2210 ###########################################################################
2211 # Split up PKGD into PKGDEST
2212 ###########################################################################
2213
2214 cpath = oe.cachedpath.CachedPath()
2215
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002216 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002217 bb.build.exec_func(f, d)
2218
2219 ###########################################################################
2220 # Process PKGDEST
2221 ###########################################################################
2222
2223 # Build global list of files in each split package
2224 global pkgfiles
2225 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002226 packages = d.getVar('PACKAGES').split()
2227 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002228 for pkg in packages:
2229 pkgfiles[pkg] = []
2230 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2231 for file in files:
2232 pkgfiles[pkg].append(walkroot + os.sep + file)
2233
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002234 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002235 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002236
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002237 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002238 if not qa_sane:
2239 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002240}
2241
2242do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2243do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2244addtask package after do_install
2245
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002246SSTATETASKS += "do_package"
2247do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2248do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002249do_package_setscene[dirs] = "${STAGING_DIR}"
2250
2251python do_package_setscene () {
2252 sstate_setscene(d)
2253}
2254addtask do_package_setscene
2255
2256do_packagedata () {
2257 :
2258}
2259
2260addtask packagedata before do_build after do_package
2261
2262SSTATETASKS += "do_packagedata"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002263# PACKAGELOCK protects readers of PKGDATA_DIR against writes
2264# whilst code is reading in do_package
2265PACKAGELOCK = "${STAGING_DIR}/package-output.lock"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002266do_packagedata[sstate-inputdirs] = "${PKGDESTWORK}"
2267do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002268do_packagedata[sstate-lockfile] = "${PACKAGELOCK}"
2269do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002270
2271python do_packagedata_setscene () {
2272 sstate_setscene(d)
2273}
2274addtask do_packagedata_setscene
2275
2276#
2277# Helper functions for the package writing classes
2278#
2279
2280def mapping_rename_hook(d):
2281 """
2282 Rewrite variables to account for package renaming in things
2283 like debian.bbclass or manual PKG variable name changes
2284 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002285 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002286 runtime_mapping_rename("RDEPENDS", pkg, d)
2287 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2288 runtime_mapping_rename("RSUGGESTS", pkg, d)