blob: d8bef3afb00f824b743c6c833b3213d9120b968b [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() {
Brad Bishop00e122a2019-10-05 11:10:57 -04001583 import itertools
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001584 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001585 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001586
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001587 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001588 if exclude_shlibs:
1589 bb.note("not generating shlibs")
1590 return
1591
Brad Bishop19323692019-04-05 15:28:33 -04001592 lib_re = re.compile(r"^.*\.so")
1593 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001594
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001595 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001596
1597 shlib_pkgs = []
1598 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1599 if exclusion_list:
1600 for pkg in packages.split():
1601 if pkg not in exclusion_list.split():
1602 shlib_pkgs.append(pkg)
1603 else:
1604 bb.note("not generating shlibs for %s" % pkg)
1605 else:
1606 shlib_pkgs = packages.split()
1607
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001608 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001609
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001610 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001611
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001612 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001613 if not ver:
1614 msg = "PKGV not defined"
1615 package_qa_handle_error("pkgv-undefined", msg, d)
1616 return
1617
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001618 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001619
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001620 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001621
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001622 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001623 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001624 needed = set()
1625 sonames = set()
1626 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001627 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001628 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001629 fd = os.popen(cmd)
1630 lines = fd.readlines()
1631 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001632 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001633 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001634 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001635 if m:
1636 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001637 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001638 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001639 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001640 if m:
1641 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001642 if dep not in needed:
1643 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001644 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001645 if m:
1646 this_soname = m.group(1)
1647 prov = (this_soname, ldir, pkgver)
1648 if not prov in sonames:
1649 # if library is private (only used by package) then do not build shlib for it
Brad Bishop79641f22019-09-10 07:20:22 -04001650 import fnmatch
1651 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 -08001652 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001653 if libdir_re.match(os.path.dirname(file)):
1654 needs_ldconfig = True
1655 if snap_symlinks and (os.path.basename(file) != this_soname):
1656 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001657 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001658
1659 def darwin_so(file, needed, sonames, renames, pkgver):
1660 if not os.path.exists(file):
1661 return
1662 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1663
1664 def get_combinations(base):
1665 #
1666 # Given a base library name, find all combinations of this split by "." and "-"
1667 #
1668 combos = []
1669 options = base.split(".")
1670 for i in range(1, len(options) + 1):
1671 combos.append(".".join(options[0:i]))
1672 options = base.split("-")
1673 for i in range(1, len(options) + 1):
1674 combos.append("-".join(options[0:i]))
1675 return combos
1676
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001677 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 -05001678 # Drop suffix
1679 name = os.path.basename(file).rsplit(".",1)[0]
1680 # Find all combinations
1681 combos = get_combinations(name)
1682 for combo in combos:
1683 if not combo in sonames:
1684 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001685 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001686 if file.endswith('.dylib') or file.endswith('.so'):
1687 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001688 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001689 out, err = p.communicate()
1690 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001691 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001692 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001693 l = l.strip()
1694 if l.startswith('path '):
1695 rpath.append(l.split()[1])
1696
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001697 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001698 out, err = p.communicate()
1699 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001700 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001701 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001702 l = l.strip()
1703 if not l or l.endswith(":"):
1704 continue
1705 if "is not an object file" in l:
1706 continue
1707 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1708 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001709 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001710
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001711 def mingw_dll(file, needed, sonames, renames, pkgver):
1712 if not os.path.exists(file):
1713 return
1714
1715 if file.endswith(".dll"):
1716 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001717 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001718
1719 if (file.endswith(".dll") or file.endswith(".exe")):
1720 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001721 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001722 out, err = p.communicate()
1723 # process the output, grabbing all .dll names
1724 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001725 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001726 dllname = m.group(1)
1727 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001728 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001729
1730 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001731 snap_symlinks = True
1732 else:
1733 snap_symlinks = False
1734
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001735 use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001736
1737 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001738
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001739 shlib_provider = oe.package.read_shlib_providers(d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001740
1741 for pkg in shlib_pkgs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001742 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001743 private_libs = private_libs.split()
1744 needs_ldconfig = False
1745 bb.debug(2, "calculating shlib provides for %s" % pkg)
1746
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001747 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001748 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001749 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001750 if not pkgver:
1751 pkgver = ver
1752
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001753 needed[pkg] = set()
1754 sonames = set()
1755 renames = []
1756 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001757 for file in pkgfiles[pkg]:
1758 soname = None
1759 if cpath.islink(file):
1760 continue
1761 if targetos == "darwin" or targetos == "darwin8":
1762 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001763 elif targetos.startswith("mingw"):
1764 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001765 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001766 linuxlist.append(file)
1767
1768 if linuxlist:
1769 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1770 for r in results:
1771 ldconfig = r[0]
1772 needed[pkg] |= r[1]
1773 sonames |= r[2]
1774 renames.extend(r[3])
1775 needs_ldconfig = needs_ldconfig or ldconfig
1776
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001777 for (old, new) in renames:
1778 bb.note("Renaming %s to %s" % (old, new))
1779 os.rename(old, new)
1780 pkgfiles[pkg].remove(old)
1781
1782 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1783 if len(sonames):
1784 fd = open(shlibs_file, 'w')
1785 for s in sonames:
1786 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1787 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1788 if old_pkg != pkg:
1789 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))
1790 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1791 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1792 if s[0] not in shlib_provider:
1793 shlib_provider[s[0]] = {}
1794 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
1795 fd.close()
1796 if needs_ldconfig and use_ldconfig:
1797 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001798 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001799 if not postinst:
1800 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001801 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001802 d.setVar('pkg_postinst_%s' % pkg, postinst)
1803 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1804
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001805 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001806 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001807 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001808 for e in assumed_libs.split():
1809 l, dep_pkg = e.split(":")
1810 lib_ver = None
1811 dep_pkg = dep_pkg.rsplit("_", 1)
1812 if len(dep_pkg) == 2:
1813 lib_ver = dep_pkg[1]
1814 dep_pkg = dep_pkg[0]
1815 if l not in shlib_provider:
1816 shlib_provider[l] = {}
1817 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1818
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001819 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001820
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001821 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001822 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1823
Brad Bishop316dfdd2018-06-25 12:45:53 -04001824 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
1825 private_libs = private_libs.split()
1826
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001827 deps = list()
1828 for n in needed[pkg]:
1829 # if n is in private libraries, don't try to search provider for it
1830 # this could cause problem in case some abc.bb provides private
1831 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1832 # but skipping it is still better alternative than providing own
1833 # version and then adding runtime dependency for the same system library
Brad Bishop79641f22019-09-10 07:20:22 -04001834 import fnmatch
1835 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 -05001836 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1837 continue
1838 if n[0] in shlib_provider.keys():
Brad Bishop00e122a2019-10-05 11:10:57 -04001839 shlib_provider_map = shlib_provider[n[0]]
1840 matches = set()
1841 for p in itertools.chain(list(n[2]), sorted(shlib_provider_map.keys()), libsearchpath):
1842 if p in shlib_provider_map:
1843 matches.add(p)
1844 if len(matches) > 1:
1845 matchpkgs = ', '.join([shlib_provider_map[match][0] for match in matches])
1846 bb.error("%s: Multiple shlib providers for %s: %s (used by files: %s)" % (pkg, n[0], matchpkgs, n[1]))
1847 elif len(matches) == 1:
1848 (dep_pkg, ver_needed) = shlib_provider_map[matches.pop()]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001849
1850 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1851
1852 if dep_pkg == pkg:
1853 continue
1854
1855 if ver_needed:
1856 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1857 else:
1858 dep = dep_pkg
1859 if not dep in deps:
1860 deps.append(dep)
1861 continue
1862 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1863
1864 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1865 if os.path.exists(deps_file):
1866 os.remove(deps_file)
1867 if len(deps):
1868 fd = open(deps_file, 'w')
Brad Bishop19323692019-04-05 15:28:33 -04001869 for dep in sorted(deps):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001870 fd.write(dep + '\n')
1871 fd.close()
1872}
1873
1874python package_do_pkgconfig () {
1875 import re
1876
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001877 packages = d.getVar('PACKAGES')
1878 workdir = d.getVar('WORKDIR')
1879 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001880
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001881 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1882 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001883
Brad Bishop19323692019-04-05 15:28:33 -04001884 pc_re = re.compile(r'(.*)\.pc$')
1885 var_re = re.compile(r'(.*)=(.*)')
1886 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001887
1888 pkgconfig_provided = {}
1889 pkgconfig_needed = {}
1890 for pkg in packages.split():
1891 pkgconfig_provided[pkg] = []
1892 pkgconfig_needed[pkg] = []
1893 for file in pkgfiles[pkg]:
1894 m = pc_re.match(file)
1895 if m:
1896 pd = bb.data.init()
1897 name = m.group(1)
1898 pkgconfig_provided[pkg].append(name)
1899 if not os.access(file, os.R_OK):
1900 continue
1901 f = open(file, 'r')
1902 lines = f.readlines()
1903 f.close()
1904 for l in lines:
1905 m = var_re.match(l)
1906 if m:
1907 name = m.group(1)
1908 val = m.group(2)
1909 pd.setVar(name, pd.expand(val))
1910 continue
1911 m = field_re.match(l)
1912 if m:
1913 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001914 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001915 if hdr == 'Requires':
1916 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1917
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001918 for pkg in packages.split():
1919 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1920 if pkgconfig_provided[pkg] != []:
1921 f = open(pkgs_file, 'w')
1922 for p in pkgconfig_provided[pkg]:
1923 f.write('%s\n' % p)
1924 f.close()
1925
1926 # Go from least to most specific since the last one found wins
1927 for dir in reversed(shlibs_dirs):
1928 if not os.path.exists(dir):
1929 continue
Brad Bishop08902b02019-08-20 09:16:51 -04001930 for file in sorted(os.listdir(dir)):
Brad Bishop19323692019-04-05 15:28:33 -04001931 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001932 if m:
1933 pkg = m.group(1)
1934 fd = open(os.path.join(dir, file))
1935 lines = fd.readlines()
1936 fd.close()
1937 pkgconfig_provided[pkg] = []
1938 for l in lines:
1939 pkgconfig_provided[pkg].append(l.rstrip())
1940
1941 for pkg in packages.split():
1942 deps = []
1943 for n in pkgconfig_needed[pkg]:
1944 found = False
1945 for k in pkgconfig_provided.keys():
1946 if n in pkgconfig_provided[k]:
1947 if k != pkg and not (k in deps):
1948 deps.append(k)
1949 found = True
1950 if found == False:
1951 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1952 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1953 if len(deps):
1954 fd = open(deps_file, 'w')
1955 for dep in deps:
1956 fd.write(dep + '\n')
1957 fd.close()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001958}
1959
1960def read_libdep_files(d):
1961 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001962 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001963 for pkg in packages:
1964 pkglibdeps[pkg] = {}
1965 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1966 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1967 if os.access(depsfile, os.R_OK):
1968 fd = open(depsfile)
1969 lines = fd.readlines()
1970 fd.close()
1971 for l in lines:
1972 l.rstrip()
1973 deps = bb.utils.explode_dep_versions2(l)
1974 for dep in deps:
1975 if not dep in pkglibdeps[pkg]:
1976 pkglibdeps[pkg][dep] = deps[dep]
1977 return pkglibdeps
1978
1979python read_shlibdeps () {
1980 pkglibdeps = read_libdep_files(d)
1981
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001982 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001983 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001984 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04001985 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001986 # Add the dep if it's not already there, or if no comparison is set
1987 if dep not in rdepends:
1988 rdepends[dep] = []
1989 for v in pkglibdeps[pkg][dep]:
1990 if v not in rdepends[dep]:
1991 rdepends[dep].append(v)
1992 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1993}
1994
1995python package_depchains() {
1996 """
1997 For a given set of prefix and postfix modifiers, make those packages
1998 RRECOMMENDS on the corresponding packages for its RDEPENDS.
1999
2000 Example: If package A depends upon package B, and A's .bb emits an
2001 A-dev package, this would make A-dev Recommends: B-dev.
2002
2003 If only one of a given suffix is specified, it will take the RRECOMMENDS
2004 based on the RDEPENDS of *all* other packages. If more than one of a given
2005 suffix is specified, its will only use the RDEPENDS of the single parent
2006 package.
2007 """
2008
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002009 packages = d.getVar('PACKAGES')
2010 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2011 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002012
2013 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2014
2015 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002016 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002017
Brad Bishop19323692019-04-05 15:28:33 -04002018 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002019 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2020 #bb.note("Skipping %s" % depend)
2021 continue
2022 if depend.endswith('-dev'):
2023 depend = depend[:-4]
2024 if depend.endswith('-dbg'):
2025 depend = depend[:-4]
2026 pkgname = getname(depend, suffix)
2027 #bb.note("Adding %s for %s" % (pkgname, depend))
2028 if pkgname not in rreclist and pkgname != pkg:
2029 rreclist[pkgname] = []
2030
2031 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2032 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2033
2034 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2035
2036 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002037 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002038
Brad Bishop19323692019-04-05 15:28:33 -04002039 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002040 if depend.find('virtual-locale-') != -1:
2041 #bb.note("Skipping %s" % depend)
2042 continue
2043 if depend.endswith('-dev'):
2044 depend = depend[:-4]
2045 if depend.endswith('-dbg'):
2046 depend = depend[:-4]
2047 pkgname = getname(depend, suffix)
2048 #bb.note("Adding %s for %s" % (pkgname, depend))
2049 if pkgname not in rreclist and pkgname != pkg:
2050 rreclist[pkgname] = []
2051
2052 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2053 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2054
2055 def add_dep(list, dep):
2056 if dep not in list:
2057 list.append(dep)
2058
2059 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002060 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002061 add_dep(depends, dep)
2062
2063 rdepends = []
2064 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002065 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002066 add_dep(rdepends, dep)
2067
2068 #bb.note('rdepends is %s' % rdepends)
2069
2070 def post_getname(name, suffix):
2071 return '%s%s' % (name, suffix)
2072 def pre_getname(name, suffix):
2073 return '%s%s' % (suffix, name)
2074
2075 pkgs = {}
2076 for pkg in packages.split():
2077 for postfix in postfixes:
2078 if pkg.endswith(postfix):
2079 if not postfix in pkgs:
2080 pkgs[postfix] = {}
2081 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2082
2083 for prefix in prefixes:
2084 if pkg.startswith(prefix):
2085 if not prefix in pkgs:
2086 pkgs[prefix] = {}
2087 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2088
2089 if "-dbg" in pkgs:
2090 pkglibdeps = read_libdep_files(d)
2091 pkglibdeplist = []
2092 for pkg in pkglibdeps:
2093 for k in pkglibdeps[pkg]:
2094 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002095 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002096
2097 for suffix in pkgs:
2098 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002099 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002100 continue
2101 (base, func) = pkgs[suffix][pkg]
2102 if suffix == "-dev":
2103 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2104 elif suffix == "-dbg":
2105 if not dbgdefaultdeps:
2106 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2107 continue
2108 if len(pkgs[suffix]) == 1:
2109 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2110 else:
2111 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002112 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002113 add_dep(rdeps, dep)
2114 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2115}
2116
2117# Since bitbake can't determine which variables are accessed during package
2118# iteration, we need to list them here:
Andrew Geissler99467da2019-02-25 18:54:23 -06002119PACKAGEVARS = "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 -05002120
2121def gen_packagevar(d):
2122 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002123 pkgs = (d.getVar("PACKAGES") or "").split()
2124 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002125 for p in pkgs:
2126 for v in vars:
2127 ret.append(v + "_" + p)
2128
2129 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2130 # affected recipes.
2131 ret.append('LICENSE_EXCLUSION-%s' % p)
2132 return " ".join(ret)
2133
2134PACKAGE_PREPROCESS_FUNCS ?= ""
2135# Functions for setting up PKGD
2136PACKAGEBUILDPKGD ?= " \
Brad Bishop96ff1982019-08-19 13:50:42 -04002137 package_prepare_pkgdata \
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002138 perform_packagecopy \
2139 ${PACKAGE_PREPROCESS_FUNCS} \
2140 split_and_strip_files \
2141 fixup_perms \
2142 "
2143# Functions which split PKGD up into separate packages
2144PACKAGESPLITFUNCS ?= " \
2145 package_do_split_locales \
2146 populate_packages"
2147# Functions which process metadata based on split packages
2148PACKAGEFUNCS += " \
2149 package_fixsymlinks \
2150 package_name_hook \
2151 package_do_filedeps \
2152 package_do_shlibs \
2153 package_do_pkgconfig \
2154 read_shlibdeps \
2155 package_depchains \
2156 emit_pkgdata"
2157
2158python do_package () {
2159 # Change the following version to cause sstate to invalidate the package
2160 # cache. This is useful if an item this class depends on changes in a
2161 # way that the output of this class changes. rpmdeps is a good example
2162 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002163 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002164
2165 # Init cachedpath
2166 global cpath
2167 cpath = oe.cachedpath.CachedPath()
2168
2169 ###########################################################################
2170 # Sanity test the setup
2171 ###########################################################################
2172
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002173 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002174 if len(packages) < 1:
2175 bb.debug(1, "No packages to build, skipping do_package")
2176 return
2177
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002178 workdir = d.getVar('WORKDIR')
2179 outdir = d.getVar('DEPLOY_DIR')
2180 dest = d.getVar('D')
2181 dvar = d.getVar('PKGD')
2182 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002183
2184 if not workdir or not outdir or not dest or not dvar or not pn:
2185 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2186 package_qa_handle_error("var-undefined", msg, d)
2187 return
2188
2189 bb.build.exec_func("package_get_auto_pr", d)
2190
2191 ###########################################################################
2192 # Optimisations
2193 ###########################################################################
2194
2195 # Continually expanding complex expressions is inefficient, particularly
2196 # when we write to the datastore and invalidate the expansion cache. This
2197 # code pre-expands some frequently used variables
2198
2199 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002200 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002201
2202 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2203 expandVar(x, d)
2204
2205 ###########################################################################
2206 # Setup PKGD (from D)
2207 ###########################################################################
2208
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002209 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002210 bb.build.exec_func(f, d)
2211
2212 ###########################################################################
2213 # Split up PKGD into PKGDEST
2214 ###########################################################################
2215
2216 cpath = oe.cachedpath.CachedPath()
2217
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002218 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002219 bb.build.exec_func(f, d)
2220
2221 ###########################################################################
2222 # Process PKGDEST
2223 ###########################################################################
2224
2225 # Build global list of files in each split package
2226 global pkgfiles
2227 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002228 packages = d.getVar('PACKAGES').split()
2229 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002230 for pkg in packages:
2231 pkgfiles[pkg] = []
2232 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2233 for file in files:
2234 pkgfiles[pkg].append(walkroot + os.sep + file)
2235
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002236 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002237 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002238
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002239 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002240 if not qa_sane:
2241 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002242}
2243
2244do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2245do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2246addtask package after do_install
2247
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002248SSTATETASKS += "do_package"
2249do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2250do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002251do_package_setscene[dirs] = "${STAGING_DIR}"
2252
2253python do_package_setscene () {
2254 sstate_setscene(d)
2255}
2256addtask do_package_setscene
2257
Brad Bishopc68388fc2019-08-26 01:33:31 -04002258# Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both
2259# do_package_setscene and do_packagedata_setscene leading to races
2260python do_packagedata () {
2261 src = d.expand("${PKGDESTWORK}")
2262 dest = d.expand("${WORKDIR}/pkgdata-pdata-input")
2263 oe.path.copyhardlinktree(src, dest)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002264}
2265
2266addtask packagedata before do_build after do_package
2267
2268SSTATETASKS += "do_packagedata"
Brad Bishopc68388fc2019-08-26 01:33:31 -04002269do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002270do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002271do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002272
2273python do_packagedata_setscene () {
2274 sstate_setscene(d)
2275}
2276addtask do_packagedata_setscene
2277
2278#
2279# Helper functions for the package writing classes
2280#
2281
2282def mapping_rename_hook(d):
2283 """
2284 Rewrite variables to account for package renaming in things
2285 like debian.bbclass or manual PKG variable name changes
2286 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002287 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002288 runtime_mapping_rename("RDEPENDS", pkg, d)
2289 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2290 runtime_mapping_rename("RSUGGESTS", pkg, d)