blob: aa8451ffe8b0f7c86aaada4d0ea2fef4476787cd [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
Brad Bishop96ff1982019-08-19 13:50:42 -040043inherit package_pkgdata
Patrick Williamsc124f4f2015-09-15 14:41:29 -050044
45# Need the package_qa_handle_error() in insane.bbclass
46inherit insane
47
48PKGD = "${WORKDIR}/package"
49PKGDEST = "${WORKDIR}/packages-split"
50
51LOCALE_SECTION ?= ''
52
53ALL_MULTILIB_PACKAGE_ARCHS = "${@all_multilib_tune_values(d, 'PACKAGE_ARCHS')}"
54
55# rpm is used for the per-file dependency identification
Brad Bishop316dfdd2018-06-25 12:45:53 -040056# dwarfsrcfiles is used to determine the list of debug source files
57PACKAGE_DEPENDS += "rpm-native dwarfsrcfiles-native"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058
Brad Bishop6e60e8b2018-02-01 10:27:11 -050059
60# If your postinstall can execute at rootfs creation time rather than on
61# target but depends on a native/cross tool in order to execute, you need to
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080062# list that tool in PACKAGE_WRITE_DEPS. Target package dependencies belong
Brad Bishop6e60e8b2018-02-01 10:27:11 -050063# in the package dependencies as normal, this is just for native/cross support
64# tools at rootfs build time.
65PACKAGE_WRITE_DEPS ??= ""
66
Patrick Williamsc124f4f2015-09-15 14:41:29 -050067def legitimize_package_name(s):
68 """
69 Make sure package names are legitimate strings
70 """
71 import re
72
73 def fixutf(m):
74 cp = m.group(1)
75 if cp:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060076 return ('\\u%s' % cp).encode('latin-1').decode('unicode_escape')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077
78 # Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
Brad Bishop19323692019-04-05 15:28:33 -040079 s = re.sub(r'<U([0-9A-Fa-f]{1,4})>', fixutf, s)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050080
81 # Remaining package name validity fixes
82 return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
83
84def 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):
85 """
86 Used in .bb files to split up dynamically generated subpackages of a
87 given package, usually plugins or modules.
88
89 Arguments:
90 root -- the path in which to search
91 file_regex -- regular expression to match searched files. Use
92 parentheses () to mark the part of this expression
93 that should be used to derive the module name (to be
94 substituted where %s is used in other function
95 arguments as noted below)
96 output_pattern -- pattern to use for the package names. Must include %s.
97 description -- description to set for each package. Must include %s.
98 postinst -- postinstall script to use for all packages (as a
99 string)
100 recursive -- True to perform a recursive search - default False
101 hook -- a hook function to be called for every match. The
102 function will be called with the following arguments
103 (in the order listed):
104 f: full path to the file/directory match
105 pkg: the package name
106 file_regex: as above
107 output_pattern: as above
108 modulename: the module name derived using file_regex
109 extra_depends -- extra runtime dependencies (RDEPENDS) to be set for
110 all packages. The default value of None causes a
111 dependency on the main package (${PN}) - if you do
112 not want this, pass '' for this parameter.
113 aux_files_pattern -- extra item(s) to be added to FILES for each
114 package. Can be a single string item or a list of
115 strings for multiple items. Must include %s.
116 postrm -- postrm script to use for all packages (as a string)
117 allow_dirs -- True allow directories to be matched - default False
118 prepend -- if True, prepend created packages to PACKAGES instead
119 of the default False which appends them
120 match_path -- match file_regex on the whole relative path to the
121 root rather than just the file name
122 aux_files_pattern_verbatim -- extra item(s) to be added to FILES for
123 each package, using the actual derived module name
124 rather than converting it to something legal for a
125 package name. Can be a single string item or a list
126 of strings for multiple items. Must include %s.
127 allow_links -- True to allow symlinks to be matched - default False
128 summary -- Summary to set for each package. Must include %s;
129 defaults to description if not set.
130
131 """
132
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500133 dvar = d.getVar('PKGD')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500134 root = d.expand(root)
135 output_pattern = d.expand(output_pattern)
136 extra_depends = d.expand(extra_depends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500137
138 # If the root directory doesn't exist, don't error out later but silently do
139 # no splitting.
140 if not os.path.exists(dvar + root):
141 return []
142
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500143 ml = d.getVar("MLPREFIX")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500144 if ml:
145 if not output_pattern.startswith(ml):
146 output_pattern = ml + output_pattern
147
148 newdeps = []
149 for dep in (extra_depends or "").split():
150 if dep.startswith(ml):
151 newdeps.append(dep)
152 else:
153 newdeps.append(ml + dep)
154 if newdeps:
155 extra_depends = " ".join(newdeps)
156
157
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500158 packages = d.getVar('PACKAGES').split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600159 split_packages = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500160
161 if postinst:
162 postinst = '#!/bin/sh\n' + postinst + '\n'
163 if postrm:
164 postrm = '#!/bin/sh\n' + postrm + '\n'
165 if not recursive:
166 objs = os.listdir(dvar + root)
167 else:
168 objs = []
169 for walkroot, dirs, files in os.walk(dvar + root):
170 for file in files:
171 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
172 if relpath:
173 objs.append(relpath)
174
175 if extra_depends == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500176 extra_depends = d.getVar("PN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500177
178 if not summary:
179 summary = description
180
181 for o in sorted(objs):
182 import re, stat
183 if match_path:
184 m = re.match(file_regex, o)
185 else:
186 m = re.match(file_regex, os.path.basename(o))
187
188 if not m:
189 continue
190 f = os.path.join(dvar + root, o)
191 mode = os.lstat(f).st_mode
192 if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))):
193 continue
194 on = legitimize_package_name(m.group(1))
195 pkg = output_pattern % on
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600196 split_packages.add(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500197 if not pkg in packages:
198 if prepend:
199 packages = [pkg] + packages
200 else:
201 packages.append(pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500202 oldfiles = d.getVar('FILES_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500203 newfile = os.path.join(root, o)
204 # These names will be passed through glob() so if the filename actually
205 # contains * or ? (rare, but possible) we need to handle that specially
206 newfile = newfile.replace('*', '[*]')
207 newfile = newfile.replace('?', '[?]')
208 if not oldfiles:
209 the_files = [newfile]
210 if aux_files_pattern:
211 if type(aux_files_pattern) is list:
212 for fp in aux_files_pattern:
213 the_files.append(fp % on)
214 else:
215 the_files.append(aux_files_pattern % on)
216 if aux_files_pattern_verbatim:
217 if type(aux_files_pattern_verbatim) is list:
218 for fp in aux_files_pattern_verbatim:
219 the_files.append(fp % m.group(1))
220 else:
221 the_files.append(aux_files_pattern_verbatim % m.group(1))
222 d.setVar('FILES_' + pkg, " ".join(the_files))
223 else:
224 d.setVar('FILES_' + pkg, oldfiles + " " + newfile)
225 if extra_depends != '':
226 d.appendVar('RDEPENDS_' + pkg, ' ' + extra_depends)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500227 if not d.getVar('DESCRIPTION_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500228 d.setVar('DESCRIPTION_' + pkg, description % on)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500229 if not d.getVar('SUMMARY_' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500230 d.setVar('SUMMARY_' + pkg, summary % on)
231 if postinst:
232 d.setVar('pkg_postinst_' + pkg, postinst)
233 if postrm:
234 d.setVar('pkg_postrm_' + pkg, postrm)
235 if callable(hook):
236 hook(f, pkg, file_regex, output_pattern, m.group(1))
237
238 d.setVar('PACKAGES', ' '.join(packages))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600239 return list(split_packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500240
241PACKAGE_DEPENDS += "file-native"
242
243python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500244 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500245 deps = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500246 for dep in (d.getVar('PACKAGE_DEPENDS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500247 deps += " %s:do_populate_sysroot" % dep
248 d.appendVarFlag('do_package', 'depends', deps)
249
250 # shlibs requires any DEPENDS to have already packaged for the *.list files
251 d.appendVarFlag('do_package', 'deptask', " do_packagedata")
252}
253
254# Get a list of files from file vars by searching files under current working directory
255# The list contains symlinks, directories and normal files.
256def files_from_filevars(filevars):
257 import os,glob
258 cpath = oe.cachedpath.CachedPath()
259 files = []
260 for f in filevars:
261 if os.path.isabs(f):
262 f = '.' + f
263 if not f.startswith("./"):
264 f = './' + f
265 globbed = glob.glob(f)
266 if globbed:
267 if [ f ] != globbed:
268 files += globbed
269 continue
270 files.append(f)
271
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600272 symlink_paths = []
273 for ind, f in enumerate(files):
274 # Handle directory symlinks. Truncate path to the lowest level symlink
275 parent = ''
276 for dirname in f.split('/')[:-1]:
277 parent = os.path.join(parent, dirname)
278 if dirname == '.':
279 continue
280 if cpath.islink(parent):
281 bb.warn("FILES contains file '%s' which resides under a "
282 "directory symlink. Please fix the recipe and use the "
283 "real path for the file." % f[1:])
284 symlink_paths.append(f)
285 files[ind] = parent
286 f = parent
287 break
288
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500289 if not cpath.islink(f):
290 if cpath.isdir(f):
291 newfiles = [ os.path.join(f,x) for x in os.listdir(f) ]
292 if newfiles:
293 files += newfiles
294
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600295 return files, symlink_paths
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500296
297# Called in package_<rpm,ipk,deb>.bbclass to get the correct list of configuration files
298def get_conffiles(pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500299 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500300 root = os.path.join(pkgdest, pkg)
301 cwd = os.getcwd()
302 os.chdir(root)
303
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500304 conffiles = d.getVar('CONFFILES_%s' % pkg);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500305 if conffiles == None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500306 conffiles = d.getVar('CONFFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500307 if conffiles == None:
308 conffiles = ""
309 conffiles = conffiles.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600310 conf_orig_list = files_from_filevars(conffiles)[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311
312 # Remove links and directories from conf_orig_list to get conf_list which only contains normal files
313 conf_list = []
314 for f in conf_orig_list:
315 if os.path.isdir(f):
316 continue
317 if os.path.islink(f):
318 continue
319 if not os.path.exists(f):
320 continue
321 conf_list.append(f)
322
323 # Remove the leading './'
324 for i in range(0, len(conf_list)):
325 conf_list[i] = conf_list[i][1:]
326
327 os.chdir(cwd)
328 return conf_list
329
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500330def checkbuildpath(file, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500331 tmpdir = d.getVar('TMPDIR')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500332 with open(file) as f:
333 file_content = f.read()
334 if tmpdir in file_content:
335 return True
336
337 return False
338
Brad Bishop316dfdd2018-06-25 12:45:53 -0400339def parse_debugsources_from_dwarfsrcfiles_output(dwarfsrcfiles_output):
340 debugfiles = {}
341
342 for line in dwarfsrcfiles_output.splitlines():
343 if line.startswith("\t"):
344 debugfiles[os.path.normpath(line.split()[0])] = ""
345
346 return debugfiles.keys()
347
Brad Bishop19323692019-04-05 15:28:33 -0400348def source_info(file, d, fatal=True):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800349 import subprocess
350
351 cmd = ["dwarfsrcfiles", file]
352 try:
353 output = subprocess.check_output(cmd, universal_newlines=True, stderr=subprocess.STDOUT)
354 retval = 0
355 except subprocess.CalledProcessError as exc:
356 output = exc.output
357 retval = exc.returncode
358
Brad Bishop316dfdd2018-06-25 12:45:53 -0400359 # 255 means a specific file wasn't fully parsed to get the debug file list, which is not a fatal failure
360 if retval != 0 and retval != 255:
361 msg = "dwarfsrcfiles failed with exit code %s (cmd was %s)%s" % (retval, cmd, ":\n%s" % output if output else "")
362 if fatal:
363 bb.fatal(msg)
364 bb.note(msg)
365
366 debugsources = parse_debugsources_from_dwarfsrcfiles_output(output)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400367
Brad Bishop19323692019-04-05 15:28:33 -0400368 return list(debugsources)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400369
Brad Bishop19323692019-04-05 15:28:33 -0400370def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500371 # Function to split a single file into two components, one is the stripped
372 # target system binary, the other contains any debugging information. The
373 # two files are linked to reference each other.
374 #
Brad Bishop19323692019-04-05 15:28:33 -0400375 # return a mapping of files:debugsources
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376
377 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800378 import subprocess
379
380 src = file[len(dvar):]
381 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
382 debugfile = dvar + dest
Brad Bishop19323692019-04-05 15:28:33 -0400383 sources = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800384
385 # Split the file...
386 bb.utils.mkdirhier(os.path.dirname(debugfile))
387 #bb.note("Split %s -> %s" % (file, debugfile))
388 # Only store off the hard link reference if we successfully split!
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500389
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500390 dvar = d.getVar('PKGD')
391 objcopy = d.getVar("OBJCOPY")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500392
393 # We ignore kernel modules, we don't generate debug info files.
394 if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
Brad Bishop19323692019-04-05 15:28:33 -0400395 return (file, sources)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500396
397 newmode = None
398 if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
399 origmode = os.stat(file)[stat.ST_MODE]
400 newmode = origmode | stat.S_IWRITE | stat.S_IREAD
401 os.chmod(file, newmode)
402
403 # We need to extract the debug src information here...
404 if debugsrcdir:
Brad Bishop19323692019-04-05 15:28:33 -0400405 sources = source_info(file, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406
407 bb.utils.mkdirhier(os.path.dirname(debugfile))
408
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800409 subprocess.check_output([objcopy, '--only-keep-debug', file, debugfile], stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500410
411 # Set the debuglink to have the view of the file path on the target
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800412 subprocess.check_output([objcopy, '--add-gnu-debuglink', debugfile, file], stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500413
414 if newmode:
415 os.chmod(file, origmode)
416
Brad Bishop19323692019-04-05 15:28:33 -0400417 return (file, sources)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500418
Brad Bishop19323692019-04-05 15:28:33 -0400419def copydebugsources(debugsrcdir, sources, d):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400420 # The debug src information written out to sourcefile is further processed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500421 # and copied to the destination here.
422
423 import stat
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800424 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500425
Brad Bishop19323692019-04-05 15:28:33 -0400426 if debugsrcdir and sources:
427 sourcefile = d.expand("${WORKDIR}/debugsources.list")
428 bb.utils.remove(sourcefile)
429
430 # filenames are null-separated - this is an artefact of the previous use
431 # of rpm's debugedit, which was writing them out that way, and the code elsewhere
432 # is still assuming that.
433 debuglistoutput = '\0'.join(sources) + '\0'
434 with open(sourcefile, 'a') as sf:
435 sf.write(debuglistoutput)
436
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500437 dvar = d.getVar('PKGD')
438 strip = d.getVar("STRIP")
439 objcopy = d.getVar("OBJCOPY")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500440 workdir = d.getVar("WORKDIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500441 workparentdir = os.path.dirname(os.path.dirname(workdir))
442 workbasedir = os.path.basename(os.path.dirname(workdir)) + "/" + os.path.basename(workdir)
443
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500444 # If build path exists in sourcefile, it means toolchain did not use
445 # -fdebug-prefix-map to compile
446 if checkbuildpath(sourcefile, d):
447 localsrc_prefix = workparentdir + "/"
448 else:
449 localsrc_prefix = "/usr/src/debug/"
450
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500451 nosuchdir = []
452 basepath = dvar
453 for p in debugsrcdir.split("/"):
454 basepath = basepath + "/" + p
455 if not cpath.exists(basepath):
456 nosuchdir.append(basepath)
457 bb.utils.mkdirhier(basepath)
458 cpath.updatecache(basepath)
459
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500460 # Ignore files from the recipe sysroots (target and native)
461 processdebugsrc = "LC_ALL=C ; sort -z -u '%s' | egrep -v -z '((<internal>|<built-in>)$|/.*recipe-sysroot.*/)' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500462 # We need to ignore files that are not actually ours
463 # we do this by only paying attention to items from this package
464 processdebugsrc += "fgrep -zw '%s' | "
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500465 # Remove prefix in the source paths
466 processdebugsrc += "sed 's#%s##g' | "
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500467 processdebugsrc += "(cd '%s' ; cpio -pd0mlL --no-preserve-owner '%s%s' 2>/dev/null)"
468
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500469 cmd = processdebugsrc % (sourcefile, workbasedir, localsrc_prefix, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800470 try:
471 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
472 except subprocess.CalledProcessError:
473 # Can "fail" if internal headers/transient sources are attempted
474 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500475
476 # cpio seems to have a bug with -lL together and symbolic links are just copied, not dereferenced.
477 # Work around this by manually finding and copying any symbolic links that made it through.
Brad Bishop19323692019-04-05 15:28:33 -0400478 cmd = "find %s%s -type l -print0 -delete | sed s#%s%s/##g | (cd '%s' ; cpio -pd0mL --no-preserve-owner '%s%s')" % \
479 (dvar, debugsrcdir, dvar, debugsrcdir, workparentdir, dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800480 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500481
482 # The copy by cpio may have resulted in some empty directories! Remove these
483 cmd = "find %s%s -empty -type d -delete" % (dvar, debugsrcdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800484 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500485
486 # Also remove debugsrcdir if its empty
487 for p in nosuchdir[::-1]:
488 if os.path.exists(p) and not os.listdir(p):
489 os.rmdir(p)
490
491#
492# Package data handling routines
493#
494
495def get_package_mapping (pkg, basepkg, d):
496 import oe.packagedata
497
498 data = oe.packagedata.read_subpkgdata(pkg, d)
499 key = "PKG_%s" % pkg
500
501 if key in data:
502 # Have to avoid undoing the write_extra_pkgs(global_variants...)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800503 if bb.data.inherits_class('allarch', d) and not d.getVar('MULTILIB_VARIANTS') \
504 and data[key] == basepkg:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500505 return pkg
506 return data[key]
507
508 return pkg
509
510def get_package_additional_metadata (pkg_type, d):
511 base_key = "PACKAGE_ADD_METADATA"
512 for key in ("%s_%s" % (base_key, pkg_type.upper()), base_key):
513 if d.getVar(key, False) is None:
514 continue
515 d.setVarFlag(key, "type", "list")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500516 if d.getVarFlag(key, "separator") is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500517 d.setVarFlag(key, "separator", "\\n")
518 metadata_fields = [field.strip() for field in oe.data.typed_value(key, d)]
519 return "\n".join(metadata_fields).strip()
520
521def runtime_mapping_rename (varname, pkg, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500522 #bb.note("%s before: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500523
524 new_depends = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500525 deps = bb.utils.explode_dep_versions2(d.getVar(varname) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500526 for depend in deps:
527 new_depend = get_package_mapping(depend, pkg, d)
528 new_depends[new_depend] = deps[depend]
529
530 d.setVar(varname, bb.utils.join_deps(new_depends, commasep=False))
531
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500532 #bb.note("%s after: %s" % (varname, d.getVar(varname)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500533
534#
535# Package functions suitable for inclusion in PACKAGEFUNCS
536#
537
538python package_get_auto_pr() {
539 import oe.prservice
540 import re
541
542 # Support per recipe PRSERV_HOST
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500543 pn = d.getVar('PN')
544 host = d.getVar("PRSERV_HOST_" + pn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500545 if not (host is None):
546 d.setVar("PRSERV_HOST", host)
547
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500548 pkgv = d.getVar("PKGV")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500549
550 # PR Server not active, handle AUTOINC
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500551 if not d.getVar('PRSERV_HOST'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500552 if 'AUTOINC' in pkgv:
553 d.setVar("PKGV", pkgv.replace("AUTOINC", "0"))
554 return
555
556 auto_pr = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500557 pv = d.getVar("PV")
558 version = d.getVar("PRAUTOINX")
559 pkgarch = d.getVar("PACKAGE_ARCH")
560 checksum = d.getVar("BB_TASKHASH")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500561
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500562 if d.getVar('PRSERV_LOCKDOWN'):
563 auto_pr = d.getVar('PRAUTO_' + version + '_' + pkgarch) or d.getVar('PRAUTO_' + version) or None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500564 if auto_pr is None:
565 bb.fatal("Can NOT get PRAUTO from lockdown exported file")
566 d.setVar('PRAUTO',str(auto_pr))
567 return
568
569 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500570 conn = d.getVar("__PRSERV_CONN")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500571 if conn is None:
572 conn = oe.prservice.prserv_make_conn(d)
573 if conn is not None:
574 if "AUTOINC" in pkgv:
575 srcpv = bb.fetch2.get_srcrev(d)
576 base_ver = "AUTOINC-%s" % version[:version.find(srcpv)]
577 value = conn.getPR(base_ver, pkgarch, srcpv)
578 d.setVar("PKGV", pkgv.replace("AUTOINC", str(value)))
579
580 auto_pr = conn.getPR(version, pkgarch, checksum)
581 except Exception as e:
582 bb.fatal("Can NOT get PRAUTO, exception %s" % str(e))
583 if auto_pr is None:
584 bb.fatal("Can NOT get PRAUTO from remote PR service")
585 d.setVar('PRAUTO',str(auto_pr))
586}
587
588LOCALEBASEPN ??= "${PN}"
589
590python package_do_split_locales() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500591 if (d.getVar('PACKAGE_NO_LOCALE') == '1'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500592 bb.debug(1, "package requested not splitting locales")
593 return
594
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500595 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500596
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500597 datadir = d.getVar('datadir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500598 if not datadir:
599 bb.note("datadir not defined")
600 return
601
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500602 dvar = d.getVar('PKGD')
603 pn = d.getVar('LOCALEBASEPN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500604
605 if pn + '-locale' in packages:
606 packages.remove(pn + '-locale')
607
608 localedir = os.path.join(dvar + datadir, 'locale')
609
610 if not cpath.isdir(localedir):
611 bb.debug(1, "No locale files in this package")
612 return
613
614 locales = os.listdir(localedir)
615
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500616 summary = d.getVar('SUMMARY') or pn
617 description = d.getVar('DESCRIPTION') or ""
618 locale_section = d.getVar('LOCALE_SECTION')
619 mlprefix = d.getVar('MLPREFIX') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500620 for l in sorted(locales):
621 ln = legitimize_package_name(l)
622 pkg = pn + '-locale-' + ln
623 packages.append(pkg)
624 d.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l))
625 d.setVar('RRECOMMENDS_' + pkg, '%svirtual-locale-%s' % (mlprefix, ln))
626 d.setVar('RPROVIDES_' + pkg, '%s-locale %s%s-translation' % (pn, mlprefix, ln))
627 d.setVar('SUMMARY_' + pkg, '%s - %s translations' % (summary, l))
628 d.setVar('DESCRIPTION_' + pkg, '%s This package contains language translation files for the %s locale.' % (description, l))
629 if locale_section:
630 d.setVar('SECTION_' + pkg, locale_section)
631
632 d.setVar('PACKAGES', ' '.join(packages))
633
634 # Disabled by RP 18/06/07
635 # Wildcards aren't supported in debian
636 # They break with ipkg since glibc-locale* will mean that
637 # glibc-localedata-translit* won't install as a dependency
638 # for some other package which breaks meta-toolchain
639 # Probably breaks since virtual-locale- isn't provided anywhere
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500640 #rdep = (d.getVar('RDEPENDS_%s' % pn) or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641 #rdep.append('%s-locale*' % pn)
642 #d.setVar('RDEPENDS_%s' % pn, ' '.join(rdep))
643}
644
645python perform_packagecopy () {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800646 import subprocess
647
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500648 dest = d.getVar('D')
649 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500650
651 # Start by package population by taking a copy of the installed
652 # files to operate on
653 # Preserve sparse files and hard links
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800654 cmd = 'tar -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar)
655 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500656
657 # replace RPATHs for the nativesdk binaries, to make them relocatable
658 if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d):
659 rpath_replace (dvar, d)
660}
661perform_packagecopy[cleandirs] = "${PKGD}"
662perform_packagecopy[dirs] = "${PKGD}"
663
664# We generate a master list of directories to process, we start by
665# seeding this list with reasonable defaults, then load from
666# the fs-perms.txt files
667python fixup_perms () {
668 import pwd, grp
669
670 # init using a string with the same format as a line as documented in
671 # the fs-perms.txt file
672 # <path> <mode> <uid> <gid> <walk> <fmode> <fuid> <fgid>
673 # <path> link <link target>
674 #
675 # __str__ can be used to print out an entry in the input format
676 #
677 # if fs_perms_entry.path is None:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400678 # an error occurred
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500679 # if fs_perms_entry.link, you can retrieve:
680 # fs_perms_entry.path = path
681 # fs_perms_entry.link = target of link
682 # if not fs_perms_entry.link, you can retrieve:
683 # fs_perms_entry.path = path
684 # fs_perms_entry.mode = expected dir mode or None
685 # fs_perms_entry.uid = expected uid or -1
686 # fs_perms_entry.gid = expected gid or -1
687 # fs_perms_entry.walk = 'true' or something else
688 # fs_perms_entry.fmode = expected file mode or None
689 # fs_perms_entry.fuid = expected file uid or -1
690 # fs_perms_entry_fgid = expected file gid or -1
691 class fs_perms_entry():
692 def __init__(self, line):
693 lsplit = line.split()
694 if len(lsplit) == 3 and lsplit[1].lower() == "link":
695 self._setlink(lsplit[0], lsplit[2])
696 elif len(lsplit) == 8:
697 self._setdir(lsplit[0], lsplit[1], lsplit[2], lsplit[3], lsplit[4], lsplit[5], lsplit[6], lsplit[7])
698 else:
699 msg = "Fixup Perms: invalid config line %s" % line
700 package_qa_handle_error("perm-config", msg, d)
701 self.path = None
702 self.link = None
703
704 def _setdir(self, path, mode, uid, gid, walk, fmode, fuid, fgid):
705 self.path = os.path.normpath(path)
706 self.link = None
707 self.mode = self._procmode(mode)
708 self.uid = self._procuid(uid)
709 self.gid = self._procgid(gid)
710 self.walk = walk.lower()
711 self.fmode = self._procmode(fmode)
712 self.fuid = self._procuid(fuid)
713 self.fgid = self._procgid(fgid)
714
715 def _setlink(self, path, link):
716 self.path = os.path.normpath(path)
717 self.link = link
718
719 def _procmode(self, mode):
720 if not mode or (mode and mode == "-"):
721 return None
722 else:
723 return int(mode,8)
724
725 # Note uid/gid -1 has special significance in os.lchown
726 def _procuid(self, uid):
727 if uid is None or uid == "-":
728 return -1
729 elif uid.isdigit():
730 return int(uid)
731 else:
732 return pwd.getpwnam(uid).pw_uid
733
734 def _procgid(self, gid):
735 if gid is None or gid == "-":
736 return -1
737 elif gid.isdigit():
738 return int(gid)
739 else:
740 return grp.getgrnam(gid).gr_gid
741
742 # Use for debugging the entries
743 def __str__(self):
744 if self.link:
745 return "%s link %s" % (self.path, self.link)
746 else:
747 mode = "-"
748 if self.mode:
749 mode = "0%o" % self.mode
750 fmode = "-"
751 if self.fmode:
752 fmode = "0%o" % self.fmode
753 uid = self._mapugid(self.uid)
754 gid = self._mapugid(self.gid)
755 fuid = self._mapugid(self.fuid)
756 fgid = self._mapugid(self.fgid)
757 return "%s %s %s %s %s %s %s %s" % (self.path, mode, uid, gid, self.walk, fmode, fuid, fgid)
758
759 def _mapugid(self, id):
760 if id is None or id == -1:
761 return "-"
762 else:
763 return "%d" % id
764
765 # Fix the permission, owner and group of path
766 def fix_perms(path, mode, uid, gid, dir):
767 if mode and not os.path.islink(path):
768 #bb.note("Fixup Perms: chmod 0%o %s" % (mode, dir))
769 os.chmod(path, mode)
770 # -1 is a special value that means don't change the uid/gid
771 # if they are BOTH -1, don't bother to lchown
772 if not (uid == -1 and gid == -1):
773 #bb.note("Fixup Perms: lchown %d:%d %s" % (uid, gid, dir))
774 os.lchown(path, uid, gid)
775
776 # Return a list of configuration files based on either the default
777 # files/fs-perms.txt or the contents of FILESYSTEM_PERMS_TABLES
778 # paths are resolved via BBPATH
779 def get_fs_perms_list(d):
780 str = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500781 bbpath = d.getVar('BBPATH')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500782 fs_perms_tables = d.getVar('FILESYSTEM_PERMS_TABLES') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500783 for conf_file in fs_perms_tables.split():
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800784 confpath = bb.utils.which(bbpath, conf_file)
785 if confpath:
786 str += " %s" % bb.utils.which(bbpath, conf_file)
787 else:
788 bb.warn("cannot find %s specified in FILESYSTEM_PERMS_TABLES" % conf_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500789 return str
790
791
792
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500793 dvar = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500794
795 fs_perms_table = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500796 fs_link_table = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500797
798 # By default all of the standard directories specified in
799 # bitbake.conf will get 0755 root:root.
800 target_path_vars = [ 'base_prefix',
801 'prefix',
802 'exec_prefix',
803 'base_bindir',
804 'base_sbindir',
805 'base_libdir',
806 'datadir',
807 'sysconfdir',
808 'servicedir',
809 'sharedstatedir',
810 'localstatedir',
811 'infodir',
812 'mandir',
813 'docdir',
814 'bindir',
815 'sbindir',
816 'libexecdir',
817 'libdir',
818 'includedir',
819 'oldincludedir' ]
820
821 for path in target_path_vars:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500822 dir = d.getVar(path) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500823 if dir == "":
824 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500825 fs_perms_table[dir] = fs_perms_entry(d.expand("%s 0755 root root false - - -" % (dir)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500826
827 # Now we actually load from the configuration files
828 for conf in get_fs_perms_list(d).split():
829 if os.path.exists(conf):
830 f = open(conf)
831 for line in f:
832 if line.startswith('#'):
833 continue
834 lsplit = line.split()
835 if len(lsplit) == 0:
836 continue
837 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
838 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
839 package_qa_handle_error("perm-line", msg, d)
840 continue
841 entry = fs_perms_entry(d.expand(line))
842 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500843 if entry.link:
844 fs_link_table[entry.path] = entry
845 if entry.path in fs_perms_table:
846 fs_perms_table.pop(entry.path)
847 else:
848 fs_perms_table[entry.path] = entry
849 if entry.path in fs_link_table:
850 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500851 f.close()
852
853 # Debug -- list out in-memory table
854 #for dir in fs_perms_table:
855 # bb.note("Fixup Perms: %s: %s" % (dir, str(fs_perms_table[dir])))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500856 #for link in fs_link_table:
857 # bb.note("Fixup Perms: %s: %s" % (link, str(fs_link_table[link])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500858
859 # We process links first, so we can go back and fixup directory ownership
860 # for any newly created directories
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500861 # Process in sorted order so /run gets created before /run/lock, etc.
862 for entry in sorted(fs_link_table.values(), key=lambda x: x.link):
863 link = entry.link
864 dir = entry.path
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500865 origin = dvar + dir
866 if not (cpath.exists(origin) and cpath.isdir(origin) and not cpath.islink(origin)):
867 continue
868
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 if link[0] == "/":
870 target = dvar + link
871 ptarget = link
872 else:
873 target = os.path.join(os.path.dirname(origin), link)
874 ptarget = os.path.join(os.path.dirname(dir), link)
875 if os.path.exists(target):
876 msg = "Fixup Perms: Unable to correct directory link, target already exists: %s -> %s" % (dir, ptarget)
877 package_qa_handle_error("perm-link", msg, d)
878 continue
879
880 # Create path to move directory to, move it, and then setup the symlink
881 bb.utils.mkdirhier(os.path.dirname(target))
882 #bb.note("Fixup Perms: Rename %s -> %s" % (dir, ptarget))
883 os.rename(origin, target)
884 #bb.note("Fixup Perms: Link %s -> %s" % (dir, link))
885 os.symlink(link, origin)
886
887 for dir in fs_perms_table:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500888 origin = dvar + dir
889 if not (cpath.exists(origin) and cpath.isdir(origin)):
890 continue
891
892 fix_perms(origin, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
893
894 if fs_perms_table[dir].walk == 'true':
895 for root, dirs, files in os.walk(origin):
896 for dr in dirs:
897 each_dir = os.path.join(root, dr)
898 fix_perms(each_dir, fs_perms_table[dir].mode, fs_perms_table[dir].uid, fs_perms_table[dir].gid, dir)
899 for f in files:
900 each_file = os.path.join(root, f)
901 fix_perms(each_file, fs_perms_table[dir].fmode, fs_perms_table[dir].fuid, fs_perms_table[dir].fgid, dir)
902}
903
904python split_and_strip_files () {
905 import stat, errno
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800906 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500907
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500908 dvar = d.getVar('PKGD')
909 pn = d.getVar('PN')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400910 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500911
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600912 oldcwd = os.getcwd()
913 os.chdir(dvar)
914
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500915 # We default to '.debug' style
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500916 if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500917 # Single debug-file-directory style debug info
918 debugappend = ".debug"
919 debugdir = ""
920 debuglibdir = "/usr/lib/debug"
921 debugsrcdir = "/usr/src/debug"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500922 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500923 # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
924 debugappend = ""
925 debugdir = "/.debug"
926 debuglibdir = ""
927 debugsrcdir = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500928 elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
929 debugappend = ""
930 debugdir = "/.debug"
931 debuglibdir = ""
932 debugsrcdir = "/usr/src/debug"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500933 else:
934 # Original OE-core, a.k.a. ".debug", style debug info
935 debugappend = ""
936 debugdir = "/.debug"
937 debuglibdir = ""
938 debugsrcdir = "/usr/src/debug"
939
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500940 #
941 # First lets figure out all of the files we may have to process ... do this only once!
942 #
943 elffiles = {}
944 symlinks = {}
945 kernmods = []
Brad Bishop316dfdd2018-06-25 12:45:53 -0400946 staticlibs = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500947 inodes = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500948 libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
949 baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
Brad Bishop316dfdd2018-06-25 12:45:53 -0400950 skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500951 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
952 d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800953 checkelf = {}
954 checkelflinks = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500955 for root, dirs, files in cpath.walk(dvar):
956 for f in files:
957 file = os.path.join(root, f)
958 if file.endswith(".ko") and file.find("/lib/modules/") != -1:
959 kernmods.append(file)
960 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800961 if oe.package.is_static_lib(file):
Brad Bishop316dfdd2018-06-25 12:45:53 -0400962 staticlibs.append(file)
963 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500964
965 # Skip debug files
966 if debugappend and file.endswith(debugappend):
967 continue
968 if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
969 continue
970
Brad Bishop316dfdd2018-06-25 12:45:53 -0400971 if file in skipfiles:
972 continue
973
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500974 try:
975 ltarget = cpath.realpath(file, dvar, False)
976 s = cpath.lstat(ltarget)
977 except OSError as e:
978 (err, strerror) = e.args
979 if err != errno.ENOENT:
980 raise
981 # Skip broken symlinks
982 continue
983 if not s:
984 continue
Brad Bishop316dfdd2018-06-25 12:45:53 -0400985 # Check its an executable
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500986 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 -0500987 or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800988
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500989 if cpath.islink(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800990 checkelflinks[file] = ltarget
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500991 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800992 # Use a reference of device ID and inode number to identify files
993 file_reference = "%d_%d" % (s.st_dev, s.st_ino)
994 checkelf[file] = (file, file_reference)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500995
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800996 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d)
997 results_map = {}
998 for (ltarget, elf_file) in results:
999 results_map[ltarget] = elf_file
1000 for file in checkelflinks:
1001 ltarget = checkelflinks[file]
1002 # If it's a symlink, and points to an ELF file, we capture the readlink target
1003 if results_map[ltarget]:
1004 target = os.readlink(file)
1005 #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget]))
1006 symlinks[file] = target
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001007
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001008 results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d)
Brad Bishop15ae2502019-06-18 21:44:24 -04001009
1010 # Sort results by file path. This ensures that the files are always
1011 # processed in the same order, which is important to make sure builds
1012 # are reproducible when dealing with hardlinks
1013 results.sort(key=lambda x: x[0])
1014
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001015 for (file, elf_file) in results:
1016 # It's a file (or hardlink), not a link
1017 # ...but is it ELF, and is it already stripped?
1018 if elf_file & 1:
1019 if elf_file & 2:
1020 if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
1021 bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
1022 else:
1023 msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
1024 package_qa_handle_error("already-stripped", msg, d)
1025 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001026
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001027 # At this point we have an unstripped elf file. We need to:
1028 # a) Make sure any file we strip is not hardlinked to anything else outside this tree
1029 # b) Only strip any hardlinked file once (no races)
1030 # c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
1031
1032 # Use a reference of device ID and inode number to identify files
1033 file_reference = checkelf[file][1]
1034 if file_reference in inodes:
1035 os.unlink(file)
1036 os.link(inodes[file_reference][0], file)
1037 inodes[file_reference].append(file)
1038 else:
1039 inodes[file_reference] = [file]
1040 # break hardlink
1041 bb.utils.break_hardlinks(file)
1042 elffiles[file] = elf_file
1043 # Modified the file so clear the cache
1044 cpath.updatecache(file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001045
1046 #
1047 # First lets process debug splitting
1048 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001049 if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
Brad Bishop19323692019-04-05 15:28:33 -04001050 results = oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001051
Brad Bishop316dfdd2018-06-25 12:45:53 -04001052 if debugsrcdir and not targetos.startswith("mingw"):
1053 for file in staticlibs:
Brad Bishop19323692019-04-05 15:28:33 -04001054 results.extend(source_info(file, d, fatal=False))
1055
1056 sources = set()
1057 for r in results:
1058 sources.update(r[1])
Brad Bishop316dfdd2018-06-25 12:45:53 -04001059
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001060 # Hardlink our debug symbols to the other hardlink copies
1061 for ref in inodes:
1062 if len(inodes[ref]) == 1:
1063 continue
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001064
1065 target = inodes[ref][0][len(dvar):]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001066 for file in inodes[ref][1:]:
1067 src = file[len(dvar):]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001068 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(target) + debugappend
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001069 fpath = dvar + dest
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001070 ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
1071 bb.utils.mkdirhier(os.path.dirname(fpath))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001072 # Only one hardlink of separated debug info file in each directory
1073 if not os.access(fpath, os.R_OK):
1074 #bb.note("Link %s -> %s" % (fpath, ftarget))
1075 os.link(ftarget, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001076
1077 # Create symlinks for all cases we were able to split symbols
1078 for file in symlinks:
1079 src = file[len(dvar):]
1080 dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
1081 fpath = dvar + dest
1082 # Skip it if the target doesn't exist
1083 try:
1084 s = os.stat(fpath)
1085 except OSError as e:
1086 (err, strerror) = e.args
1087 if err != errno.ENOENT:
1088 raise
1089 continue
1090
1091 ltarget = symlinks[file]
1092 lpath = os.path.dirname(ltarget)
1093 lbase = os.path.basename(ltarget)
1094 ftarget = ""
1095 if lpath and lpath != ".":
1096 ftarget += lpath + debugdir + "/"
1097 ftarget += lbase + debugappend
1098 if lpath.startswith(".."):
1099 ftarget = os.path.join("..", ftarget)
1100 bb.utils.mkdirhier(os.path.dirname(fpath))
1101 #bb.note("Symlink %s -> %s" % (fpath, ftarget))
1102 os.symlink(ftarget, fpath)
1103
1104 # Process the debugsrcdir if requested...
1105 # This copies and places the referenced sources for later debugging...
Brad Bishop19323692019-04-05 15:28:33 -04001106 copydebugsources(debugsrcdir, sources, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001107 #
1108 # End of debug splitting
1109 #
1110
1111 #
1112 # Now lets go back over things and strip them
1113 #
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001114 if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
1115 strip = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001116 sfiles = []
1117 for file in elffiles:
1118 elf_file = int(elffiles[file])
1119 #bb.note("Strip %s" % file)
1120 sfiles.append((file, elf_file, strip))
1121 for f in kernmods:
1122 sfiles.append((f, 16, strip))
1123
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001124 oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001125
1126 #
1127 # End of strip
1128 #
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001129 os.chdir(oldcwd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001130}
1131
1132python populate_packages () {
1133 import glob, re
1134
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001135 workdir = d.getVar('WORKDIR')
1136 outdir = d.getVar('DEPLOY_DIR')
1137 dvar = d.getVar('PKGD')
Brad Bishop19323692019-04-05 15:28:33 -04001138 packages = d.getVar('PACKAGES').split()
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001139 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001140
1141 bb.utils.mkdirhier(outdir)
1142 os.chdir(dvar)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001143
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001144 autodebug = not (d.getVar("NOAUTOPACKAGEDEBUG") or False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001145
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001146 split_source_package = (d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg')
1147
Brad Bishop19323692019-04-05 15:28:33 -04001148 # If debug-with-srcpkg mode is enabled then add the source package if it
1149 # doesn't exist and add the source file contents to the source package.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001150 if split_source_package:
1151 src_package_name = ('%s-src' % d.getVar('PN'))
Brad Bishop19323692019-04-05 15:28:33 -04001152 if not src_package_name in packages:
1153 packages.append(src_package_name)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001154 d.setVar('FILES_%s' % src_package_name, '/usr/src/debug')
1155
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001156 # Sanity check PACKAGES for duplicates
Brad Bishop316dfdd2018-06-25 12:45:53 -04001157 # Sanity should be moved to sanity.bbclass once we have the infrastructure
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001158 package_dict = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001159
Brad Bishop19323692019-04-05 15:28:33 -04001160 for i, pkg in enumerate(packages):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001161 if pkg in package_dict:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001162 msg = "%s is listed in PACKAGES multiple times, this leads to packaging errors." % pkg
1163 package_qa_handle_error("packages-list", msg, d)
Brad Bishop19323692019-04-05 15:28:33 -04001164 # Ensure the source package gets the chance to pick up the source files
1165 # before the debug package by ordering it first in PACKAGES. Whether it
1166 # actually picks up any source files is controlled by
1167 # PACKAGE_DEBUG_SPLIT_STYLE.
1168 elif pkg.endswith("-src"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001169 package_dict[pkg] = (10, i)
1170 elif autodebug and pkg.endswith("-dbg"):
1171 package_dict[pkg] = (30, i)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001172 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001173 package_dict[pkg] = (50, i)
Brad Bishop19323692019-04-05 15:28:33 -04001174 packages = sorted(package_dict.keys(), key=package_dict.get)
1175 d.setVar('PACKAGES', ' '.join(packages))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001176 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001177
1178 seen = []
1179
1180 # os.mkdir masks the permissions with umask so we have to unset it first
1181 oldumask = os.umask(0)
1182
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001183 debug = []
1184 for root, dirs, files in cpath.walk(dvar):
1185 dir = root[len(dvar):]
1186 if not dir:
1187 dir = os.sep
1188 for f in (files + dirs):
1189 path = "." + os.path.join(dir, f)
1190 if "/.debug/" in path or path.endswith("/.debug"):
1191 debug.append(path)
1192
Brad Bishop19323692019-04-05 15:28:33 -04001193 for pkg in packages:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001194 root = os.path.join(pkgdest, pkg)
1195 bb.utils.mkdirhier(root)
1196
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001197 filesvar = d.getVar('FILES_%s' % pkg) or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001198 if "//" in filesvar:
1199 msg = "FILES variable for package %s contains '//' which is invalid. Attempting to fix this but you should correct the metadata.\n" % pkg
1200 package_qa_handle_error("files-invalid", msg, d)
1201 filesvar.replace("//", "/")
1202
1203 origfiles = filesvar.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001204 files, symlink_paths = files_from_filevars(origfiles)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001205
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001206 if autodebug and pkg.endswith("-dbg"):
1207 files.extend(debug)
1208
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001209 for file in files:
1210 if (not cpath.islink(file)) and (not cpath.exists(file)):
1211 continue
1212 if file in seen:
1213 continue
1214 seen.append(file)
1215
1216 def mkdir(src, dest, p):
1217 src = os.path.join(src, p)
1218 dest = os.path.join(dest, p)
1219 fstat = cpath.stat(src)
Brad Bishop96ff1982019-08-19 13:50:42 -04001220 os.mkdir(dest)
1221 os.chmod(dest, fstat.st_mode)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001222 os.chown(dest, fstat.st_uid, fstat.st_gid)
1223 if p not in seen:
1224 seen.append(p)
1225 cpath.updatecache(dest)
1226
1227 def mkdir_recurse(src, dest, paths):
1228 if cpath.exists(dest + '/' + paths):
1229 return
1230 while paths.startswith("./"):
1231 paths = paths[2:]
1232 p = "."
1233 for c in paths.split("/"):
1234 p = os.path.join(p, c)
1235 if not cpath.exists(os.path.join(dest, p)):
1236 mkdir(src, dest, p)
1237
1238 if cpath.isdir(file) and not cpath.islink(file):
1239 mkdir_recurse(dvar, root, file)
1240 continue
1241
1242 mkdir_recurse(dvar, root, os.path.dirname(file))
1243 fpath = os.path.join(root,file)
1244 if not cpath.islink(file):
1245 os.link(file, fpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001246 continue
1247 ret = bb.utils.copyfile(file, fpath)
1248 if ret is False or ret == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001249 bb.fatal("File population failed")
1250
1251 # Check if symlink paths exist
1252 for file in symlink_paths:
1253 if not os.path.exists(os.path.join(root,file)):
1254 bb.fatal("File '%s' cannot be packaged into '%s' because its "
1255 "parent directory structure does not exist. One of "
1256 "its parent directories is a symlink whose target "
1257 "directory is not included in the package." %
1258 (file, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001259
1260 os.umask(oldumask)
1261 os.chdir(workdir)
1262
1263 # Handle LICENSE_EXCLUSION
1264 package_list = []
Brad Bishop19323692019-04-05 15:28:33 -04001265 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001266 if d.getVar('LICENSE_EXCLUSION-' + pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001267 msg = "%s has an incompatible license. Excluding from packaging." % pkg
1268 package_qa_handle_error("incompatible-license", msg, d)
1269 else:
1270 package_list.append(pkg)
1271 d.setVar('PACKAGES', ' '.join(package_list))
1272
1273 unshipped = []
1274 for root, dirs, files in cpath.walk(dvar):
1275 dir = root[len(dvar):]
1276 if not dir:
1277 dir = os.sep
1278 for f in (files + dirs):
1279 path = os.path.join(dir, f)
1280 if ('.' + path) not in seen:
1281 unshipped.append(path)
1282
1283 if unshipped != []:
1284 msg = pn + ": Files/directories were installed but not shipped in any package:"
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001285 if "installed-vs-shipped" in (d.getVar('INSANE_SKIP_' + pn) or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001286 bb.note("Package %s skipping QA tests: installed-vs-shipped" % pn)
1287 else:
1288 for f in unshipped:
1289 msg = msg + "\n " + f
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001290 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"
1291 msg = msg + "%s: %d installed and not shipped files." % (pn, len(unshipped))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001292 package_qa_handle_error("installed-vs-shipped", msg, d)
1293}
1294populate_packages[dirs] = "${D}"
1295
1296python package_fixsymlinks () {
1297 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001298 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001299 packages = d.getVar("PACKAGES", False).split()
1300
1301 dangling_links = {}
1302 pkg_files = {}
1303 for pkg in packages:
1304 dangling_links[pkg] = []
1305 pkg_files[pkg] = []
1306 inst_root = os.path.join(pkgdest, pkg)
1307 for path in pkgfiles[pkg]:
1308 rpath = path[len(inst_root):]
1309 pkg_files[pkg].append(rpath)
1310 rtarget = cpath.realpath(path, inst_root, True, assume_dir = True)
1311 if not cpath.lexists(rtarget):
1312 dangling_links[pkg].append(os.path.normpath(rtarget[len(inst_root):]))
1313
1314 newrdepends = {}
1315 for pkg in dangling_links:
1316 for l in dangling_links[pkg]:
1317 found = False
1318 bb.debug(1, "%s contains dangling link %s" % (pkg, l))
1319 for p in packages:
1320 if l in pkg_files[p]:
1321 found = True
1322 bb.debug(1, "target found in %s" % p)
1323 if p == pkg:
1324 break
1325 if pkg not in newrdepends:
1326 newrdepends[pkg] = []
1327 newrdepends[pkg].append(p)
1328 break
1329 if found == False:
1330 bb.note("%s contains dangling symlink to %s" % (pkg, l))
1331
1332 for pkg in newrdepends:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001333 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001334 for p in newrdepends[pkg]:
1335 if p not in rdepends:
1336 rdepends[p] = []
1337 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1338}
1339
1340
1341python package_package_name_hook() {
1342 """
1343 A package_name_hook function can be used to rewrite the package names by
1344 changing PKG. For an example, see debian.bbclass.
1345 """
1346 pass
1347}
1348
1349EXPORT_FUNCTIONS package_name_hook
1350
1351
1352PKGDESTWORK = "${WORKDIR}/pkgdata"
1353
Brad Bishop15ae2502019-06-18 21:44:24 -04001354PKGDATA_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"
1355
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001356python emit_pkgdata() {
1357 from glob import glob
1358 import json
1359
Brad Bishop316dfdd2018-06-25 12:45:53 -04001360 def process_postinst_on_target(pkg, mlprefix):
Brad Bishop96ff1982019-08-19 13:50:42 -04001361 pkgval = d.getVar('PKG_%s' % pkg)
1362 if pkgval is None:
1363 pkgval = pkg
1364
Brad Bishop316dfdd2018-06-25 12:45:53 -04001365 defer_fragment = """
1366if [ -n "$D" ]; then
1367 $INTERCEPT_DIR/postinst_intercept delay_to_first_boot %s mlprefix=%s
1368 exit 0
1369fi
Brad Bishop96ff1982019-08-19 13:50:42 -04001370""" % (pkgval, mlprefix)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001371
1372 postinst = d.getVar('pkg_postinst_%s' % pkg)
1373 postinst_ontarget = d.getVar('pkg_postinst_ontarget_%s' % pkg)
1374
1375 if postinst_ontarget:
1376 bb.debug(1, 'adding deferred pkg_postinst_ontarget() to pkg_postinst() for %s' % pkg)
1377 if not postinst:
1378 postinst = '#!/bin/sh\n'
1379 postinst += defer_fragment
1380 postinst += postinst_ontarget
1381 d.setVar('pkg_postinst_%s' % pkg, postinst)
1382
1383 def add_set_e_to_scriptlets(pkg):
1384 for scriptlet_name in ('pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm'):
1385 scriptlet = d.getVar('%s_%s' % (scriptlet_name, pkg))
1386 if scriptlet:
1387 scriptlet_split = scriptlet.split('\n')
1388 if scriptlet_split[0].startswith("#!"):
1389 scriptlet = scriptlet_split[0] + "\nset -e\n" + "\n".join(scriptlet_split[1:])
1390 else:
1391 scriptlet = "set -e\n" + "\n".join(scriptlet_split[0:])
1392 d.setVar('%s_%s' % (scriptlet_name, pkg), scriptlet)
1393
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001394 def write_if_exists(f, pkg, var):
1395 def encode(str):
1396 import codecs
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001397 c = codecs.getencoder("unicode_escape")
1398 return c(str)[0].decode("latin1")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001399
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001400 val = d.getVar('%s_%s' % (var, pkg))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001401 if val:
1402 f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
1403 return val
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001404 val = d.getVar('%s' % (var))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001405 if val:
1406 f.write('%s: %s\n' % (var, encode(val)))
1407 return val
1408
1409 def write_extra_pkgs(variants, pn, packages, pkgdatadir):
1410 for variant in variants:
1411 with open("%s/%s-%s" % (pkgdatadir, variant, pn), 'w') as fd:
1412 fd.write("PACKAGES: %s\n" % ' '.join(
1413 map(lambda pkg: '%s-%s' % (variant, pkg), packages.split())))
1414
1415 def write_extra_runtime_pkgs(variants, packages, pkgdatadir):
1416 for variant in variants:
1417 for pkg in packages.split():
1418 ml_pkg = "%s-%s" % (variant, pkg)
1419 subdata_file = "%s/runtime/%s" % (pkgdatadir, ml_pkg)
1420 with open(subdata_file, 'w') as fd:
1421 fd.write("PKG_%s: %s" % (ml_pkg, pkg))
1422
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001423 packages = d.getVar('PACKAGES')
1424 pkgdest = d.getVar('PKGDEST')
1425 pkgdatadir = d.getVar('PKGDESTWORK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001426
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001427 data_file = pkgdatadir + d.expand("/${PN}" )
1428 f = open(data_file, 'w')
1429 f.write("PACKAGES: %s\n" % packages)
1430 f.close()
1431
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001432 pn = d.getVar('PN')
1433 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1434 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001435
1436 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1437 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1438
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001439 if bb.data.inherits_class('allarch', d) and not variants \
1440 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001441 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1442
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001443 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001444
1445 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001446 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001447 if pkgval is None:
1448 pkgval = pkg
1449 d.setVar('PKG_%s' % pkg, pkg)
1450
1451 pkgdestpkg = os.path.join(pkgdest, pkg)
1452 files = {}
1453 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001454 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001455 for f in pkgfiles[pkg]:
1456 relpth = os.path.relpath(f, pkgdestpkg)
1457 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001458 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001459 if fstat.st_ino not in seen:
1460 seen.add(fstat.st_ino)
1461 total_size += fstat.st_size
Brad Bishop19323692019-04-05 15:28:33 -04001462 d.setVar('FILES_INFO', json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001463
Brad Bishop316dfdd2018-06-25 12:45:53 -04001464 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1465 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001466
Brad Bishop15ae2502019-06-18 21:44:24 -04001467 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1468 with open(subdata_file, 'w') as sf:
1469 for var in (d.getVar('PKGDATA_VARS') or "").split():
1470 val = write_if_exists(sf, pkg, var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001471
Brad Bishop15ae2502019-06-18 21:44:24 -04001472 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1473 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
1474 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1475
1476 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
1477 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
1478 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1479
1480 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001481
1482 # Symlinks needed for rprovides lookup
Brad Bishop15ae2502019-06-18 21:44:24 -04001483 rprov = d.getVar('RPROVIDES_%s' % pkg) or d.getVar('RPROVIDES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001484 if rprov:
1485 for p in rprov.strip().split():
1486 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1487 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1488 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1489
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001490 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001491 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001492 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001493 root = "%s/%s" % (pkgdest, pkg)
1494 os.chdir(root)
1495 g = glob('*')
1496 if g or allow_empty == "1":
1497 # Symlinks needed for reverse lookups (from the final package name)
1498 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1499 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1500
1501 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1502 open(packagedfile, 'w').close()
1503
1504 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1505 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1506
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001507 if bb.data.inherits_class('allarch', d) and not variants \
1508 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001509 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1510
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001511}
1512emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1513
1514ldconfig_postinst_fragment() {
1515if [ x"$D" = "x" ]; then
1516 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1517fi
1518}
1519
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001520RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001521
1522# Collect perfile run-time dependency metadata
1523# Output:
1524# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1525# FILERPROVIDES_filepath_pkg - per file dep
1526#
1527# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1528# FILERDEPENDS_filepath_pkg - per file dep
1529
1530python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001531 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001532 return
1533
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001534 pkgdest = d.getVar('PKGDEST')
1535 packages = d.getVar('PACKAGES')
1536 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001537
1538 def chunks(files, n):
1539 return [files[i:i+n] for i in range(0, len(files), n)]
1540
1541 pkglist = []
1542 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001543 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001544 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001545 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 -05001546 continue
1547 for files in chunks(pkgfiles[pkg], 100):
1548 pkglist.append((pkg, files, rpmdeps, pkgdest))
1549
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001550 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001551
1552 provides_files = {}
1553 requires_files = {}
1554
1555 for result in processed:
1556 (pkg, provides, requires) = result
1557
1558 if pkg not in provides_files:
1559 provides_files[pkg] = []
1560 if pkg not in requires_files:
1561 requires_files[pkg] = []
1562
Brad Bishop19323692019-04-05 15:28:33 -04001563 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001564 provides_files[pkg].append(file)
1565 key = "FILERPROVIDES_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001566 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001567
Brad Bishop19323692019-04-05 15:28:33 -04001568 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001569 requires_files[pkg].append(file)
1570 key = "FILERDEPENDS_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001571 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001572
1573 for pkg in requires_files:
1574 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1575 for pkg in provides_files:
1576 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1577}
1578
Brad Bishop96ff1982019-08-19 13:50:42 -04001579SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001580SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1581
1582python package_do_shlibs() {
1583 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001584 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001585
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001586 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001587 if exclude_shlibs:
1588 bb.note("not generating shlibs")
1589 return
1590
Brad Bishop19323692019-04-05 15:28:33 -04001591 lib_re = re.compile(r"^.*\.so")
1592 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001593
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001594 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001595
1596 shlib_pkgs = []
1597 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1598 if exclusion_list:
1599 for pkg in packages.split():
1600 if pkg not in exclusion_list.split():
1601 shlib_pkgs.append(pkg)
1602 else:
1603 bb.note("not generating shlibs for %s" % pkg)
1604 else:
1605 shlib_pkgs = packages.split()
1606
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001607 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001608
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001609 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001610
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001611 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001612 if not ver:
1613 msg = "PKGV not defined"
1614 package_qa_handle_error("pkgv-undefined", msg, d)
1615 return
1616
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001617 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001618
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001619 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001620
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001621 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001622 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001623 needed = set()
1624 sonames = set()
1625 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001626 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001627 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001628 fd = os.popen(cmd)
1629 lines = fd.readlines()
1630 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001631 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001632 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001633 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001634 if m:
1635 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001636 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001637 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001638 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001639 if m:
1640 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001641 if dep not in needed:
1642 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001643 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001644 if m:
1645 this_soname = m.group(1)
1646 prov = (this_soname, ldir, pkgver)
1647 if not prov in sonames:
1648 # if library is private (only used by package) then do not build shlib for it
Brad Bishop79641f22019-09-10 07:20:22 -04001649 import fnmatch
1650 if not private_libs or len([i for i in private_libs if fnmatch.fnmatch(this_soname, i)]) == 0:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001651 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001652 if libdir_re.match(os.path.dirname(file)):
1653 needs_ldconfig = True
1654 if snap_symlinks and (os.path.basename(file) != this_soname):
1655 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001656 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001657
1658 def darwin_so(file, needed, sonames, renames, pkgver):
1659 if not os.path.exists(file):
1660 return
1661 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1662
1663 def get_combinations(base):
1664 #
1665 # Given a base library name, find all combinations of this split by "." and "-"
1666 #
1667 combos = []
1668 options = base.split(".")
1669 for i in range(1, len(options) + 1):
1670 combos.append(".".join(options[0:i]))
1671 options = base.split("-")
1672 for i in range(1, len(options) + 1):
1673 combos.append("-".join(options[0:i]))
1674 return combos
1675
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001676 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 -05001677 # Drop suffix
1678 name = os.path.basename(file).rsplit(".",1)[0]
1679 # Find all combinations
1680 combos = get_combinations(name)
1681 for combo in combos:
1682 if not combo in sonames:
1683 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001684 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001685 if file.endswith('.dylib') or file.endswith('.so'):
1686 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001687 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001688 out, err = p.communicate()
1689 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001690 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001691 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001692 l = l.strip()
1693 if l.startswith('path '):
1694 rpath.append(l.split()[1])
1695
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001696 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001697 out, err = p.communicate()
1698 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001699 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001700 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001701 l = l.strip()
1702 if not l or l.endswith(":"):
1703 continue
1704 if "is not an object file" in l:
1705 continue
1706 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1707 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001708 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001709
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001710 def mingw_dll(file, needed, sonames, renames, pkgver):
1711 if not os.path.exists(file):
1712 return
1713
1714 if file.endswith(".dll"):
1715 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001716 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001717
1718 if (file.endswith(".dll") or file.endswith(".exe")):
1719 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001720 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001721 out, err = p.communicate()
1722 # process the output, grabbing all .dll names
1723 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001724 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001725 dllname = m.group(1)
1726 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001727 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001728
1729 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001730 snap_symlinks = True
1731 else:
1732 snap_symlinks = False
1733
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001734 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001735
1736 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001737
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001738 shlib_provider = oe.package.read_shlib_providers(d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001739
1740 for pkg in shlib_pkgs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001741 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001742 private_libs = private_libs.split()
1743 needs_ldconfig = False
1744 bb.debug(2, "calculating shlib provides for %s" % pkg)
1745
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001746 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001747 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001748 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001749 if not pkgver:
1750 pkgver = ver
1751
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001752 needed[pkg] = set()
1753 sonames = set()
1754 renames = []
1755 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001756 for file in pkgfiles[pkg]:
1757 soname = None
1758 if cpath.islink(file):
1759 continue
1760 if targetos == "darwin" or targetos == "darwin8":
1761 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001762 elif targetos.startswith("mingw"):
1763 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001764 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001765 linuxlist.append(file)
1766
1767 if linuxlist:
1768 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1769 for r in results:
1770 ldconfig = r[0]
1771 needed[pkg] |= r[1]
1772 sonames |= r[2]
1773 renames.extend(r[3])
1774 needs_ldconfig = needs_ldconfig or ldconfig
1775
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001776 for (old, new) in renames:
1777 bb.note("Renaming %s to %s" % (old, new))
1778 os.rename(old, new)
1779 pkgfiles[pkg].remove(old)
1780
1781 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1782 if len(sonames):
1783 fd = open(shlibs_file, 'w')
1784 for s in sonames:
1785 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1786 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1787 if old_pkg != pkg:
1788 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))
1789 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1790 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1791 if s[0] not in shlib_provider:
1792 shlib_provider[s[0]] = {}
1793 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1794 fd.close()
1795 if needs_ldconfig and use_ldconfig:
1796 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001797 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001798 if not postinst:
1799 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001800 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001801 d.setVar('pkg_postinst_%s' % pkg, postinst)
1802 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1803
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001804 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001805 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001806 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001807 for e in assumed_libs.split():
1808 l, dep_pkg = e.split(":")
1809 lib_ver = None
1810 dep_pkg = dep_pkg.rsplit("_", 1)
1811 if len(dep_pkg) == 2:
1812 lib_ver = dep_pkg[1]
1813 dep_pkg = dep_pkg[0]
1814 if l not in shlib_provider:
1815 shlib_provider[l] = {}
1816 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1817
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001818 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001819
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001820 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001821 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1822
Brad Bishop316dfdd2018-06-25 12:45:53 -04001823 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
1824 private_libs = private_libs.split()
1825
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001826 deps = list()
1827 for n in needed[pkg]:
1828 # if n is in private libraries, don't try to search provider for it
1829 # this could cause problem in case some abc.bb provides private
1830 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1831 # but skipping it is still better alternative than providing own
1832 # version and then adding runtime dependency for the same system library
Brad Bishop79641f22019-09-10 07:20:22 -04001833 import fnmatch
1834 if private_libs and len([i for i in private_libs if fnmatch.fnmatch(n[0], i)]) > 0:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001835 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1836 continue
1837 if n[0] in shlib_provider.keys():
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001838 shlib_provider_path = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001839 for k in shlib_provider[n[0]].keys():
1840 shlib_provider_path.append(k)
1841 match = None
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001842 for p in list(n[2]) + shlib_provider_path + libsearchpath:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001843 if p in shlib_provider[n[0]]:
1844 match = p
1845 break
1846 if match:
1847 (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
1848
1849 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1850
1851 if dep_pkg == pkg:
1852 continue
1853
1854 if ver_needed:
1855 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1856 else:
1857 dep = dep_pkg
1858 if not dep in deps:
1859 deps.append(dep)
1860 continue
1861 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1862
1863 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1864 if os.path.exists(deps_file):
1865 os.remove(deps_file)
1866 if len(deps):
1867 fd = open(deps_file, 'w')
Brad Bishop19323692019-04-05 15:28:33 -04001868 for dep in sorted(deps):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001869 fd.write(dep + '\n')
1870 fd.close()
1871}
1872
1873python package_do_pkgconfig () {
1874 import re
1875
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001876 packages = d.getVar('PACKAGES')
1877 workdir = d.getVar('WORKDIR')
1878 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001879
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001880 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1881 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001882
Brad Bishop19323692019-04-05 15:28:33 -04001883 pc_re = re.compile(r'(.*)\.pc$')
1884 var_re = re.compile(r'(.*)=(.*)')
1885 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001886
1887 pkgconfig_provided = {}
1888 pkgconfig_needed = {}
1889 for pkg in packages.split():
1890 pkgconfig_provided[pkg] = []
1891 pkgconfig_needed[pkg] = []
1892 for file in pkgfiles[pkg]:
1893 m = pc_re.match(file)
1894 if m:
1895 pd = bb.data.init()
1896 name = m.group(1)
1897 pkgconfig_provided[pkg].append(name)
1898 if not os.access(file, os.R_OK):
1899 continue
1900 f = open(file, 'r')
1901 lines = f.readlines()
1902 f.close()
1903 for l in lines:
1904 m = var_re.match(l)
1905 if m:
1906 name = m.group(1)
1907 val = m.group(2)
1908 pd.setVar(name, pd.expand(val))
1909 continue
1910 m = field_re.match(l)
1911 if m:
1912 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001913 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001914 if hdr == 'Requires':
1915 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1916
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001917 for pkg in packages.split():
1918 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1919 if pkgconfig_provided[pkg] != []:
1920 f = open(pkgs_file, 'w')
1921 for p in pkgconfig_provided[pkg]:
1922 f.write('%s\n' % p)
1923 f.close()
1924
1925 # Go from least to most specific since the last one found wins
1926 for dir in reversed(shlibs_dirs):
1927 if not os.path.exists(dir):
1928 continue
Brad Bishop08902b02019-08-20 09:16:51 -04001929 for file in sorted(os.listdir(dir)):
Brad Bishop19323692019-04-05 15:28:33 -04001930 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001931 if m:
1932 pkg = m.group(1)
1933 fd = open(os.path.join(dir, file))
1934 lines = fd.readlines()
1935 fd.close()
1936 pkgconfig_provided[pkg] = []
1937 for l in lines:
1938 pkgconfig_provided[pkg].append(l.rstrip())
1939
1940 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 ?= " \
Brad Bishop96ff1982019-08-19 13:50:42 -04002136 package_prepare_pkgdata \
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002137 perform_packagecopy \
2138 ${PACKAGE_PREPROCESS_FUNCS} \
2139 split_and_strip_files \
2140 fixup_perms \
2141 "
2142# Functions which split PKGD up into separate packages
2143PACKAGESPLITFUNCS ?= " \
2144 package_do_split_locales \
2145 populate_packages"
2146# Functions which process metadata based on split packages
2147PACKAGEFUNCS += " \
2148 package_fixsymlinks \
2149 package_name_hook \
2150 package_do_filedeps \
2151 package_do_shlibs \
2152 package_do_pkgconfig \
2153 read_shlibdeps \
2154 package_depchains \
2155 emit_pkgdata"
2156
2157python do_package () {
2158 # Change the following version to cause sstate to invalidate the package
2159 # cache. This is useful if an item this class depends on changes in a
2160 # way that the output of this class changes. rpmdeps is a good example
2161 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002162 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002163
2164 # Init cachedpath
2165 global cpath
2166 cpath = oe.cachedpath.CachedPath()
2167
2168 ###########################################################################
2169 # Sanity test the setup
2170 ###########################################################################
2171
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002172 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002173 if len(packages) < 1:
2174 bb.debug(1, "No packages to build, skipping do_package")
2175 return
2176
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002177 workdir = d.getVar('WORKDIR')
2178 outdir = d.getVar('DEPLOY_DIR')
2179 dest = d.getVar('D')
2180 dvar = d.getVar('PKGD')
2181 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002182
2183 if not workdir or not outdir or not dest or not dvar or not pn:
2184 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2185 package_qa_handle_error("var-undefined", msg, d)
2186 return
2187
2188 bb.build.exec_func("package_get_auto_pr", d)
2189
2190 ###########################################################################
2191 # Optimisations
2192 ###########################################################################
2193
2194 # Continually expanding complex expressions is inefficient, particularly
2195 # when we write to the datastore and invalidate the expansion cache. This
2196 # code pre-expands some frequently used variables
2197
2198 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002199 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002200
2201 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2202 expandVar(x, d)
2203
2204 ###########################################################################
2205 # Setup PKGD (from D)
2206 ###########################################################################
2207
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002208 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002209 bb.build.exec_func(f, d)
2210
2211 ###########################################################################
2212 # Split up PKGD into PKGDEST
2213 ###########################################################################
2214
2215 cpath = oe.cachedpath.CachedPath()
2216
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002217 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002218 bb.build.exec_func(f, d)
2219
2220 ###########################################################################
2221 # Process PKGDEST
2222 ###########################################################################
2223
2224 # Build global list of files in each split package
2225 global pkgfiles
2226 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002227 packages = d.getVar('PACKAGES').split()
2228 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002229 for pkg in packages:
2230 pkgfiles[pkg] = []
2231 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2232 for file in files:
2233 pkgfiles[pkg].append(walkroot + os.sep + file)
2234
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002235 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002236 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002237
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002238 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002239 if not qa_sane:
2240 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002241}
2242
2243do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2244do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2245addtask package after do_install
2246
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002247SSTATETASKS += "do_package"
2248do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2249do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002250do_package_setscene[dirs] = "${STAGING_DIR}"
2251
2252python do_package_setscene () {
2253 sstate_setscene(d)
2254}
2255addtask do_package_setscene
2256
Brad Bishopc68388fc2019-08-26 01:33:31 -04002257# Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both
2258# do_package_setscene and do_packagedata_setscene leading to races
2259python do_packagedata () {
2260 src = d.expand("${PKGDESTWORK}")
2261 dest = d.expand("${WORKDIR}/pkgdata-pdata-input")
2262 oe.path.copyhardlinktree(src, dest)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002263}
2264
2265addtask packagedata before do_build after do_package
2266
2267SSTATETASKS += "do_packagedata"
Brad Bishopc68388fc2019-08-26 01:33:31 -04002268do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002269do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002270do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002271
2272python do_packagedata_setscene () {
2273 sstate_setscene(d)
2274}
2275addtask do_packagedata_setscene
2276
2277#
2278# Helper functions for the package writing classes
2279#
2280
2281def mapping_rename_hook(d):
2282 """
2283 Rewrite variables to account for package renaming in things
2284 like debian.bbclass or manual PKG variable name changes
2285 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002286 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002287 runtime_mapping_rename("RDEPENDS", pkg, d)
2288 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2289 runtime_mapping_rename("RSUGGESTS", pkg, d)