blob: e0d6ff67018a0346d79f225b406eb868e2454a54 [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():
Brad Bishop64c979e2019-11-04 13:55:29 -0500829 if not os.path.exists(conf):
830 continue
831 with open(conf) as f:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500832 for line in f:
833 if line.startswith('#'):
834 continue
835 lsplit = line.split()
836 if len(lsplit) == 0:
837 continue
838 if len(lsplit) != 8 and not (len(lsplit) == 3 and lsplit[1].lower() == "link"):
839 msg = "Fixup perms: %s invalid line: %s" % (conf, line)
840 package_qa_handle_error("perm-line", msg, d)
841 continue
842 entry = fs_perms_entry(d.expand(line))
843 if entry and entry.path:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500844 if entry.link:
845 fs_link_table[entry.path] = entry
846 if entry.path in fs_perms_table:
847 fs_perms_table.pop(entry.path)
848 else:
849 fs_perms_table[entry.path] = entry
850 if entry.path in fs_link_table:
851 fs_link_table.pop(entry.path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500852
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
Brad Bishop64c979e2019-11-04 13:55:29 -05001427 data_file = pkgdatadir + d.expand("/${PN}")
1428 with open(data_file, 'w') as fd:
1429 fd.write("PACKAGES: %s\n" % packages)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001430
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001431 pn = d.getVar('PN')
1432 global_variants = (d.getVar('MULTILIB_GLOBAL_VARIANTS') or "").split()
1433 variants = (d.getVar('MULTILIB_VARIANTS') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001434
1435 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1436 write_extra_pkgs(variants, pn, packages, pkgdatadir)
1437
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001438 if bb.data.inherits_class('allarch', d) and not variants \
1439 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001440 write_extra_pkgs(global_variants, pn, packages, pkgdatadir)
1441
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001442 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001443
1444 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001445 pkgval = d.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001446 if pkgval is None:
1447 pkgval = pkg
1448 d.setVar('PKG_%s' % pkg, pkg)
1449
1450 pkgdestpkg = os.path.join(pkgdest, pkg)
1451 files = {}
1452 total_size = 0
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001453 seen = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001454 for f in pkgfiles[pkg]:
1455 relpth = os.path.relpath(f, pkgdestpkg)
1456 fstat = os.lstat(f)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001457 files[os.sep + relpth] = fstat.st_size
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001458 if fstat.st_ino not in seen:
1459 seen.add(fstat.st_ino)
1460 total_size += fstat.st_size
Brad Bishop19323692019-04-05 15:28:33 -04001461 d.setVar('FILES_INFO', json.dumps(files, sort_keys=True))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001462
Brad Bishop316dfdd2018-06-25 12:45:53 -04001463 process_postinst_on_target(pkg, d.getVar("MLPREFIX"))
1464 add_set_e_to_scriptlets(pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001465
Brad Bishop15ae2502019-06-18 21:44:24 -04001466 subdata_file = pkgdatadir + "/runtime/%s" % pkg
1467 with open(subdata_file, 'w') as sf:
1468 for var in (d.getVar('PKGDATA_VARS') or "").split():
1469 val = write_if_exists(sf, pkg, var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001470
Brad Bishop15ae2502019-06-18 21:44:24 -04001471 write_if_exists(sf, pkg, 'FILERPROVIDESFLIST')
1472 for dfile in (d.getVar('FILERPROVIDESFLIST_' + pkg) or "").split():
1473 write_if_exists(sf, pkg, 'FILERPROVIDES_' + dfile)
1474
1475 write_if_exists(sf, pkg, 'FILERDEPENDSFLIST')
1476 for dfile in (d.getVar('FILERDEPENDSFLIST_' + pkg) or "").split():
1477 write_if_exists(sf, pkg, 'FILERDEPENDS_' + dfile)
1478
1479 sf.write('%s_%s: %d\n' % ('PKGSIZE', pkg, total_size))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001480
1481 # Symlinks needed for rprovides lookup
Brad Bishop15ae2502019-06-18 21:44:24 -04001482 rprov = d.getVar('RPROVIDES_%s' % pkg) or d.getVar('RPROVIDES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001483 if rprov:
1484 for p in rprov.strip().split():
1485 subdata_sym = pkgdatadir + "/runtime-rprovides/%s/%s" % (p, pkg)
1486 bb.utils.mkdirhier(os.path.dirname(subdata_sym))
1487 oe.path.symlink("../../runtime/%s" % pkg, subdata_sym, True)
1488
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001489 allow_empty = d.getVar('ALLOW_EMPTY_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001490 if not allow_empty:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001491 allow_empty = d.getVar('ALLOW_EMPTY')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001492 root = "%s/%s" % (pkgdest, pkg)
1493 os.chdir(root)
1494 g = glob('*')
1495 if g or allow_empty == "1":
1496 # Symlinks needed for reverse lookups (from the final package name)
1497 subdata_sym = pkgdatadir + "/runtime-reverse/%s" % pkgval
1498 oe.path.symlink("../runtime/%s" % pkg, subdata_sym, True)
1499
1500 packagedfile = pkgdatadir + '/runtime/%s.packaged' % pkg
1501 open(packagedfile, 'w').close()
1502
1503 if bb.data.inherits_class('kernel', d) or bb.data.inherits_class('module-base', d):
1504 write_extra_runtime_pkgs(variants, packages, pkgdatadir)
1505
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001506 if bb.data.inherits_class('allarch', d) and not variants \
1507 and not bb.data.inherits_class('packagegroup', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001508 write_extra_runtime_pkgs(global_variants, packages, pkgdatadir)
1509
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001510}
1511emit_pkgdata[dirs] = "${PKGDESTWORK}/runtime ${PKGDESTWORK}/runtime-reverse ${PKGDESTWORK}/runtime-rprovides"
1512
1513ldconfig_postinst_fragment() {
1514if [ x"$D" = "x" ]; then
1515 if [ -x /sbin/ldconfig ]; then /sbin/ldconfig ; fi
1516fi
1517}
1518
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001519RPMDEPS = "${STAGING_LIBDIR_NATIVE}/rpm/rpmdeps --alldeps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001520
1521# Collect perfile run-time dependency metadata
1522# Output:
1523# FILERPROVIDESFLIST_pkg - list of all files w/ deps
1524# FILERPROVIDES_filepath_pkg - per file dep
1525#
1526# FILERDEPENDSFLIST_pkg - list of all files w/ deps
1527# FILERDEPENDS_filepath_pkg - per file dep
1528
1529python package_do_filedeps() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001530 if d.getVar('SKIP_FILEDEPS') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001531 return
1532
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001533 pkgdest = d.getVar('PKGDEST')
1534 packages = d.getVar('PACKAGES')
1535 rpmdeps = d.getVar('RPMDEPS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001536
1537 def chunks(files, n):
1538 return [files[i:i+n] for i in range(0, len(files), n)]
1539
1540 pkglist = []
1541 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001542 if d.getVar('SKIP_FILEDEPS_' + pkg) == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001543 continue
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001544 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 -05001545 continue
1546 for files in chunks(pkgfiles[pkg], 100):
1547 pkglist.append((pkg, files, rpmdeps, pkgdest))
1548
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001549 processed = oe.utils.multiprocess_launch(oe.package.filedeprunner, pkglist, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001550
1551 provides_files = {}
1552 requires_files = {}
1553
1554 for result in processed:
1555 (pkg, provides, requires) = result
1556
1557 if pkg not in provides_files:
1558 provides_files[pkg] = []
1559 if pkg not in requires_files:
1560 requires_files[pkg] = []
1561
Brad Bishop19323692019-04-05 15:28:33 -04001562 for file in sorted(provides):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001563 provides_files[pkg].append(file)
1564 key = "FILERPROVIDES_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001565 d.appendVar(key, " " + " ".join(provides[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001566
Brad Bishop19323692019-04-05 15:28:33 -04001567 for file in sorted(requires):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001568 requires_files[pkg].append(file)
1569 key = "FILERDEPENDS_" + file + "_" + pkg
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001570 d.appendVar(key, " " + " ".join(requires[file]))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001571
1572 for pkg in requires_files:
1573 d.setVar("FILERDEPENDSFLIST_" + pkg, " ".join(requires_files[pkg]))
1574 for pkg in provides_files:
1575 d.setVar("FILERPROVIDESFLIST_" + pkg, " ".join(provides_files[pkg]))
1576}
1577
Brad Bishop96ff1982019-08-19 13:50:42 -04001578SHLIBSDIRS = "${WORKDIR_PKGDATA}/${MLPREFIX}shlibs2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001579SHLIBSWORKDIR = "${PKGDESTWORK}/${MLPREFIX}shlibs2"
1580
1581python package_do_shlibs() {
Brad Bishop00e122a2019-10-05 11:10:57 -04001582 import itertools
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001583 import re, pipes
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001584 import subprocess
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001585
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001586 exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001587 if exclude_shlibs:
1588 bb.note("not generating shlibs")
1589 return
1590
Brad Bishop19323692019-04-05 15:28:33 -04001591 lib_re = re.compile(r"^.*\.so")
1592 libdir_re = re.compile(r".*/%s$" % d.getVar('baselib'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001593
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001594 packages = d.getVar('PACKAGES')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001595
1596 shlib_pkgs = []
1597 exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
1598 if exclusion_list:
1599 for pkg in packages.split():
1600 if pkg not in exclusion_list.split():
1601 shlib_pkgs.append(pkg)
1602 else:
1603 bb.note("not generating shlibs for %s" % pkg)
1604 else:
1605 shlib_pkgs = packages.split()
1606
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001607 targetos = d.getVar('TARGET_OS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001608
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001609 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001610
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001611 ver = d.getVar('PKGV')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001612 if not ver:
1613 msg = "PKGV not defined"
1614 package_qa_handle_error("pkgv-undefined", msg, d)
1615 return
1616
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001617 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001618
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001619 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001620
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001621 def linux_so(file, pkg, pkgver, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001622 needs_ldconfig = False
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001623 needed = set()
1624 sonames = set()
1625 renames = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001626 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001627 cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001628 fd = os.popen(cmd)
1629 lines = fd.readlines()
1630 fd.close()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001631 rpath = tuple()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001632 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001633 m = re.match(r"\s+RPATH\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001634 if m:
1635 rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001636 rpath = tuple(map(os.path.normpath, rpaths))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001637 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001638 m = re.match(r"\s+NEEDED\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001639 if m:
1640 dep = m.group(1)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001641 if dep not in needed:
1642 needed.add((dep, file, rpath))
Brad Bishop19323692019-04-05 15:28:33 -04001643 m = re.match(r"\s+SONAME\s+([^\s]*)", l)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001644 if m:
1645 this_soname = m.group(1)
1646 prov = (this_soname, ldir, pkgver)
1647 if not prov in sonames:
1648 # if library is private (only used by package) then do not build shlib for it
Brad Bishop79641f22019-09-10 07:20:22 -04001649 import fnmatch
1650 if not private_libs or len([i for i in private_libs if fnmatch.fnmatch(this_soname, i)]) == 0:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001651 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001652 if libdir_re.match(os.path.dirname(file)):
1653 needs_ldconfig = True
1654 if snap_symlinks and (os.path.basename(file) != this_soname):
1655 renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001656 return (needs_ldconfig, needed, sonames, renames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001657
1658 def darwin_so(file, needed, sonames, renames, pkgver):
1659 if not os.path.exists(file):
1660 return
1661 ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
1662
1663 def get_combinations(base):
1664 #
1665 # Given a base library name, find all combinations of this split by "." and "-"
1666 #
1667 combos = []
1668 options = base.split(".")
1669 for i in range(1, len(options) + 1):
1670 combos.append(".".join(options[0:i]))
1671 options = base.split("-")
1672 for i in range(1, len(options) + 1):
1673 combos.append("-".join(options[0:i]))
1674 return combos
1675
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001676 if (file.endswith('.dylib') or file.endswith('.so')) and not pkg.endswith('-dev') and not pkg.endswith('-dbg') and not pkg.endswith('-src'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001677 # Drop suffix
1678 name = os.path.basename(file).rsplit(".",1)[0]
1679 # Find all combinations
1680 combos = get_combinations(name)
1681 for combo in combos:
1682 if not combo in sonames:
1683 prov = (combo, ldir, pkgver)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001684 sonames.add(prov)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001685 if file.endswith('.dylib') or file.endswith('.so'):
1686 rpath = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001687 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001688 out, err = p.communicate()
1689 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001690 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001691 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001692 l = l.strip()
1693 if l.startswith('path '):
1694 rpath.append(l.split()[1])
1695
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001696 p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001697 out, err = p.communicate()
1698 # If returned successfully, process stdout for results
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001699 if p.returncode == 0:
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001700 for l in out.split("\n"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001701 l = l.strip()
1702 if not l or l.endswith(":"):
1703 continue
1704 if "is not an object file" in l:
1705 continue
1706 name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
1707 if name and name not in needed[pkg]:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001708 needed[pkg].add((name, file, tuple()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001709
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001710 def mingw_dll(file, needed, sonames, renames, pkgver):
1711 if not os.path.exists(file):
1712 return
1713
1714 if file.endswith(".dll"):
1715 # assume all dlls are shared objects provided by the package
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001716 sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001717
1718 if (file.endswith(".dll") or file.endswith(".exe")):
1719 # use objdump to search for "DLL Name: .*\.dll"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001720 p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001721 out, err = p.communicate()
1722 # process the output, grabbing all .dll names
1723 if p.returncode == 0:
Brad Bishop19323692019-04-05 15:28:33 -04001724 for m in re.finditer(r"DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001725 dllname = m.group(1)
1726 if dllname:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001727 needed[pkg].add((dllname, file, tuple()))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001728
1729 if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001730 snap_symlinks = True
1731 else:
1732 snap_symlinks = False
1733
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001734 needed = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001735
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001736 shlib_provider = oe.package.read_shlib_providers(d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001737
1738 for pkg in shlib_pkgs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001739 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001740 private_libs = private_libs.split()
1741 needs_ldconfig = False
1742 bb.debug(2, "calculating shlib provides for %s" % pkg)
1743
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001744 pkgver = d.getVar('PKGV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001745 if not pkgver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001746 pkgver = d.getVar('PV_' + pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001747 if not pkgver:
1748 pkgver = ver
1749
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001750 needed[pkg] = set()
1751 sonames = set()
1752 renames = []
1753 linuxlist = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001754 for file in pkgfiles[pkg]:
1755 soname = None
1756 if cpath.islink(file):
1757 continue
1758 if targetos == "darwin" or targetos == "darwin8":
1759 darwin_so(file, needed, sonames, renames, pkgver)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001760 elif targetos.startswith("mingw"):
1761 mingw_dll(file, needed, sonames, renames, pkgver)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001762 elif os.access(file, os.X_OK) or lib_re.match(file):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001763 linuxlist.append(file)
1764
1765 if linuxlist:
1766 results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
1767 for r in results:
1768 ldconfig = r[0]
1769 needed[pkg] |= r[1]
1770 sonames |= r[2]
1771 renames.extend(r[3])
1772 needs_ldconfig = needs_ldconfig or ldconfig
1773
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001774 for (old, new) in renames:
1775 bb.note("Renaming %s to %s" % (old, new))
1776 os.rename(old, new)
1777 pkgfiles[pkg].remove(old)
Brad Bishop64c979e2019-11-04 13:55:29 -05001778
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001779 shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
1780 if len(sonames):
Brad Bishop64c979e2019-11-04 13:55:29 -05001781 with open(shlibs_file, 'w') as fd:
1782 for s in sonames:
1783 if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
1784 (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
1785 if old_pkg != pkg:
1786 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))
1787 bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
1788 fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
1789 if s[0] not in shlib_provider:
1790 shlib_provider[s[0]] = {}
1791 shlib_provider[s[0]][s[1]] = (pkg, pkgver)
Brad Bishop1d80a2e2019-11-15 16:35:03 -05001792 if needs_ldconfig:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001793 bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001794 postinst = d.getVar('pkg_postinst_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001795 if not postinst:
1796 postinst = '#!/bin/sh\n'
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001797 postinst += d.getVar('ldconfig_postinst_fragment')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001798 d.setVar('pkg_postinst_%s' % pkg, postinst)
1799 bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
1800
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001801 assumed_libs = d.getVar('ASSUME_SHLIBS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001802 if assumed_libs:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001803 libdir = d.getVar("libdir")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001804 for e in assumed_libs.split():
1805 l, dep_pkg = e.split(":")
1806 lib_ver = None
1807 dep_pkg = dep_pkg.rsplit("_", 1)
1808 if len(dep_pkg) == 2:
1809 lib_ver = dep_pkg[1]
1810 dep_pkg = dep_pkg[0]
1811 if l not in shlib_provider:
1812 shlib_provider[l] = {}
1813 shlib_provider[l][libdir] = (dep_pkg, lib_ver)
1814
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001815 libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001816
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001817 for pkg in shlib_pkgs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001818 bb.debug(2, "calculating shlib requirements for %s" % pkg)
1819
Brad Bishop316dfdd2018-06-25 12:45:53 -04001820 private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
1821 private_libs = private_libs.split()
1822
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001823 deps = list()
1824 for n in needed[pkg]:
1825 # if n is in private libraries, don't try to search provider for it
1826 # this could cause problem in case some abc.bb provides private
1827 # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
1828 # but skipping it is still better alternative than providing own
1829 # version and then adding runtime dependency for the same system library
Brad Bishop79641f22019-09-10 07:20:22 -04001830 import fnmatch
1831 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 -05001832 bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
1833 continue
1834 if n[0] in shlib_provider.keys():
Brad Bishop00e122a2019-10-05 11:10:57 -04001835 shlib_provider_map = shlib_provider[n[0]]
1836 matches = set()
1837 for p in itertools.chain(list(n[2]), sorted(shlib_provider_map.keys()), libsearchpath):
1838 if p in shlib_provider_map:
1839 matches.add(p)
1840 if len(matches) > 1:
1841 matchpkgs = ', '.join([shlib_provider_map[match][0] for match in matches])
1842 bb.error("%s: Multiple shlib providers for %s: %s (used by files: %s)" % (pkg, n[0], matchpkgs, n[1]))
1843 elif len(matches) == 1:
1844 (dep_pkg, ver_needed) = shlib_provider_map[matches.pop()]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001845
1846 bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
1847
1848 if dep_pkg == pkg:
1849 continue
1850
1851 if ver_needed:
1852 dep = "%s (>= %s)" % (dep_pkg, ver_needed)
1853 else:
1854 dep = dep_pkg
1855 if not dep in deps:
1856 deps.append(dep)
1857 continue
1858 bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
1859
1860 deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
1861 if os.path.exists(deps_file):
1862 os.remove(deps_file)
Brad Bishop64c979e2019-11-04 13:55:29 -05001863 if deps:
1864 with open(deps_file, 'w') as fd:
1865 for dep in sorted(deps):
1866 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001867}
1868
1869python package_do_pkgconfig () {
1870 import re
1871
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001872 packages = d.getVar('PACKAGES')
1873 workdir = d.getVar('WORKDIR')
1874 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001875
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001876 shlibs_dirs = d.getVar('SHLIBSDIRS').split()
1877 shlibswork_dir = d.getVar('SHLIBSWORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001878
Brad Bishop19323692019-04-05 15:28:33 -04001879 pc_re = re.compile(r'(.*)\.pc$')
1880 var_re = re.compile(r'(.*)=(.*)')
1881 field_re = re.compile(r'(.*): (.*)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001882
1883 pkgconfig_provided = {}
1884 pkgconfig_needed = {}
1885 for pkg in packages.split():
1886 pkgconfig_provided[pkg] = []
1887 pkgconfig_needed[pkg] = []
1888 for file in pkgfiles[pkg]:
1889 m = pc_re.match(file)
1890 if m:
1891 pd = bb.data.init()
1892 name = m.group(1)
1893 pkgconfig_provided[pkg].append(name)
1894 if not os.access(file, os.R_OK):
1895 continue
Brad Bishop64c979e2019-11-04 13:55:29 -05001896 with open(file, 'r') as f:
1897 lines = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001898 for l in lines:
1899 m = var_re.match(l)
1900 if m:
1901 name = m.group(1)
1902 val = m.group(2)
1903 pd.setVar(name, pd.expand(val))
1904 continue
1905 m = field_re.match(l)
1906 if m:
1907 hdr = m.group(1)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001908 exp = pd.expand(m.group(2))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001909 if hdr == 'Requires':
1910 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
1911
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001912 for pkg in packages.split():
1913 pkgs_file = os.path.join(shlibswork_dir, pkg + ".pclist")
1914 if pkgconfig_provided[pkg] != []:
Brad Bishop64c979e2019-11-04 13:55:29 -05001915 with open(pkgs_file, 'w') as f:
1916 for p in pkgconfig_provided[pkg]:
1917 f.write('%s\n' % p)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001918
1919 # Go from least to most specific since the last one found wins
1920 for dir in reversed(shlibs_dirs):
1921 if not os.path.exists(dir):
1922 continue
Brad Bishop08902b02019-08-20 09:16:51 -04001923 for file in sorted(os.listdir(dir)):
Brad Bishop19323692019-04-05 15:28:33 -04001924 m = re.match(r'^(.*)\.pclist$', file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001925 if m:
1926 pkg = m.group(1)
Brad Bishop64c979e2019-11-04 13:55:29 -05001927 with open(os.path.join(dir, file)) as fd:
1928 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001929 pkgconfig_provided[pkg] = []
1930 for l in lines:
1931 pkgconfig_provided[pkg].append(l.rstrip())
1932
1933 for pkg in packages.split():
1934 deps = []
1935 for n in pkgconfig_needed[pkg]:
1936 found = False
1937 for k in pkgconfig_provided.keys():
1938 if n in pkgconfig_provided[k]:
1939 if k != pkg and not (k in deps):
1940 deps.append(k)
1941 found = True
1942 if found == False:
1943 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
1944 deps_file = os.path.join(pkgdest, pkg + ".pcdeps")
1945 if len(deps):
Brad Bishop64c979e2019-11-04 13:55:29 -05001946 with open(deps_file, 'w') as fd:
1947 for dep in deps:
1948 fd.write(dep + '\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001949}
1950
1951def read_libdep_files(d):
1952 pkglibdeps = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001953 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001954 for pkg in packages:
1955 pkglibdeps[pkg] = {}
1956 for extension in ".shlibdeps", ".pcdeps", ".clilibdeps":
1957 depsfile = d.expand("${PKGDEST}/" + pkg + extension)
1958 if os.access(depsfile, os.R_OK):
Brad Bishop64c979e2019-11-04 13:55:29 -05001959 with open(depsfile) as fd:
1960 lines = fd.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001961 for l in lines:
1962 l.rstrip()
1963 deps = bb.utils.explode_dep_versions2(l)
1964 for dep in deps:
1965 if not dep in pkglibdeps[pkg]:
1966 pkglibdeps[pkg][dep] = deps[dep]
1967 return pkglibdeps
1968
1969python read_shlibdeps () {
1970 pkglibdeps = read_libdep_files(d)
1971
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001972 packages = d.getVar('PACKAGES').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001973 for pkg in packages:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001974 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS_' + pkg) or "")
Brad Bishop19323692019-04-05 15:28:33 -04001975 for dep in sorted(pkglibdeps[pkg]):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001976 # Add the dep if it's not already there, or if no comparison is set
1977 if dep not in rdepends:
1978 rdepends[dep] = []
1979 for v in pkglibdeps[pkg][dep]:
1980 if v not in rdepends[dep]:
1981 rdepends[dep].append(v)
1982 d.setVar('RDEPENDS_' + pkg, bb.utils.join_deps(rdepends, commasep=False))
1983}
1984
1985python package_depchains() {
1986 """
1987 For a given set of prefix and postfix modifiers, make those packages
1988 RRECOMMENDS on the corresponding packages for its RDEPENDS.
1989
1990 Example: If package A depends upon package B, and A's .bb emits an
1991 A-dev package, this would make A-dev Recommends: B-dev.
1992
1993 If only one of a given suffix is specified, it will take the RRECOMMENDS
1994 based on the RDEPENDS of *all* other packages. If more than one of a given
1995 suffix is specified, its will only use the RDEPENDS of the single parent
1996 package.
1997 """
1998
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001999 packages = d.getVar('PACKAGES')
2000 postfixes = (d.getVar('DEPCHAIN_POST') or '').split()
2001 prefixes = (d.getVar('DEPCHAIN_PRE') or '').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002002
2003 def pkg_adddeprrecs(pkg, base, suffix, getname, depends, d):
2004
2005 #bb.note('depends for %s is %s' % (base, depends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002006 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002007
Brad Bishop19323692019-04-05 15:28:33 -04002008 for depend in sorted(depends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002009 if depend.find('-native') != -1 or depend.find('-cross') != -1 or depend.startswith('virtual/'):
2010 #bb.note("Skipping %s" % depend)
2011 continue
2012 if depend.endswith('-dev'):
2013 depend = depend[:-4]
2014 if depend.endswith('-dbg'):
2015 depend = depend[:-4]
2016 pkgname = getname(depend, suffix)
2017 #bb.note("Adding %s for %s" % (pkgname, depend))
2018 if pkgname not in rreclist and pkgname != pkg:
2019 rreclist[pkgname] = []
2020
2021 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2022 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2023
2024 def pkg_addrrecs(pkg, base, suffix, getname, rdepends, d):
2025
2026 #bb.note('rdepends for %s is %s' % (base, rdepends))
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002027 rreclist = bb.utils.explode_dep_versions2(d.getVar('RRECOMMENDS_' + pkg) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002028
Brad Bishop19323692019-04-05 15:28:33 -04002029 for depend in sorted(rdepends):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002030 if depend.find('virtual-locale-') != -1:
2031 #bb.note("Skipping %s" % depend)
2032 continue
2033 if depend.endswith('-dev'):
2034 depend = depend[:-4]
2035 if depend.endswith('-dbg'):
2036 depend = depend[:-4]
2037 pkgname = getname(depend, suffix)
2038 #bb.note("Adding %s for %s" % (pkgname, depend))
2039 if pkgname not in rreclist and pkgname != pkg:
2040 rreclist[pkgname] = []
2041
2042 #bb.note('setting: RRECOMMENDS_%s=%s' % (pkg, ' '.join(rreclist)))
2043 d.setVar('RRECOMMENDS_%s' % pkg, bb.utils.join_deps(rreclist, commasep=False))
2044
2045 def add_dep(list, dep):
2046 if dep not in list:
2047 list.append(dep)
2048
2049 depends = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002050 for dep in bb.utils.explode_deps(d.getVar('DEPENDS') or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002051 add_dep(depends, dep)
2052
2053 rdepends = []
2054 for pkg in packages.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002055 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + pkg) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002056 add_dep(rdepends, dep)
2057
2058 #bb.note('rdepends is %s' % rdepends)
2059
2060 def post_getname(name, suffix):
2061 return '%s%s' % (name, suffix)
2062 def pre_getname(name, suffix):
2063 return '%s%s' % (suffix, name)
2064
2065 pkgs = {}
2066 for pkg in packages.split():
2067 for postfix in postfixes:
2068 if pkg.endswith(postfix):
2069 if not postfix in pkgs:
2070 pkgs[postfix] = {}
2071 pkgs[postfix][pkg] = (pkg[:-len(postfix)], post_getname)
2072
2073 for prefix in prefixes:
2074 if pkg.startswith(prefix):
2075 if not prefix in pkgs:
2076 pkgs[prefix] = {}
2077 pkgs[prefix][pkg] = (pkg[:-len(prefix)], pre_getname)
2078
2079 if "-dbg" in pkgs:
2080 pkglibdeps = read_libdep_files(d)
2081 pkglibdeplist = []
2082 for pkg in pkglibdeps:
2083 for k in pkglibdeps[pkg]:
2084 add_dep(pkglibdeplist, k)
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002085 dbgdefaultdeps = ((d.getVar('DEPCHAIN_DBGDEFAULTDEPS') == '1') or (bb.data.inherits_class('packagegroup', d)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002086
2087 for suffix in pkgs:
2088 for pkg in pkgs[suffix]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002089 if d.getVarFlag('RRECOMMENDS_' + pkg, 'nodeprrecs'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002090 continue
2091 (base, func) = pkgs[suffix][pkg]
2092 if suffix == "-dev":
2093 pkg_adddeprrecs(pkg, base, suffix, func, depends, d)
2094 elif suffix == "-dbg":
2095 if not dbgdefaultdeps:
2096 pkg_addrrecs(pkg, base, suffix, func, pkglibdeplist, d)
2097 continue
2098 if len(pkgs[suffix]) == 1:
2099 pkg_addrrecs(pkg, base, suffix, func, rdepends, d)
2100 else:
2101 rdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002102 for dep in bb.utils.explode_deps(d.getVar('RDEPENDS_' + base) or ""):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002103 add_dep(rdeps, dep)
2104 pkg_addrrecs(pkg, base, suffix, func, rdeps, d)
2105}
2106
2107# Since bitbake can't determine which variables are accessed during package
2108# iteration, we need to list them here:
Andrew Geissler99467da2019-02-25 18:54:23 -06002109PACKAGEVARS = "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 -05002110
2111def gen_packagevar(d):
2112 ret = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002113 pkgs = (d.getVar("PACKAGES") or "").split()
2114 vars = (d.getVar("PACKAGEVARS") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002115 for p in pkgs:
2116 for v in vars:
2117 ret.append(v + "_" + p)
2118
2119 # Ensure that changes to INCOMPATIBLE_LICENSE re-run do_package for
2120 # affected recipes.
2121 ret.append('LICENSE_EXCLUSION-%s' % p)
2122 return " ".join(ret)
2123
2124PACKAGE_PREPROCESS_FUNCS ?= ""
2125# Functions for setting up PKGD
2126PACKAGEBUILDPKGD ?= " \
Brad Bishop96ff1982019-08-19 13:50:42 -04002127 package_prepare_pkgdata \
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002128 perform_packagecopy \
2129 ${PACKAGE_PREPROCESS_FUNCS} \
2130 split_and_strip_files \
2131 fixup_perms \
2132 "
2133# Functions which split PKGD up into separate packages
2134PACKAGESPLITFUNCS ?= " \
2135 package_do_split_locales \
2136 populate_packages"
2137# Functions which process metadata based on split packages
2138PACKAGEFUNCS += " \
2139 package_fixsymlinks \
2140 package_name_hook \
2141 package_do_filedeps \
2142 package_do_shlibs \
2143 package_do_pkgconfig \
2144 read_shlibdeps \
2145 package_depchains \
2146 emit_pkgdata"
2147
2148python do_package () {
2149 # Change the following version to cause sstate to invalidate the package
2150 # cache. This is useful if an item this class depends on changes in a
2151 # way that the output of this class changes. rpmdeps is a good example
2152 # as any change to rpmdeps requires this to be rerun.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002153 # PACKAGE_BBCLASS_VERSION = "2"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002154
2155 # Init cachedpath
2156 global cpath
2157 cpath = oe.cachedpath.CachedPath()
2158
2159 ###########################################################################
2160 # Sanity test the setup
2161 ###########################################################################
2162
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002163 packages = (d.getVar('PACKAGES') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002164 if len(packages) < 1:
2165 bb.debug(1, "No packages to build, skipping do_package")
2166 return
2167
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002168 workdir = d.getVar('WORKDIR')
2169 outdir = d.getVar('DEPLOY_DIR')
2170 dest = d.getVar('D')
2171 dvar = d.getVar('PKGD')
2172 pn = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002173
2174 if not workdir or not outdir or not dest or not dvar or not pn:
2175 msg = "WORKDIR, DEPLOY_DIR, D, PN and PKGD all must be defined, unable to package"
2176 package_qa_handle_error("var-undefined", msg, d)
2177 return
2178
2179 bb.build.exec_func("package_get_auto_pr", d)
2180
2181 ###########################################################################
2182 # Optimisations
2183 ###########################################################################
2184
2185 # Continually expanding complex expressions is inefficient, particularly
2186 # when we write to the datastore and invalidate the expansion cache. This
2187 # code pre-expands some frequently used variables
2188
2189 def expandVar(x, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002190 d.setVar(x, d.getVar(x))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002191
2192 for x in 'PN', 'PV', 'BPN', 'TARGET_SYS', 'EXTENDPRAUTO':
2193 expandVar(x, d)
2194
2195 ###########################################################################
2196 # Setup PKGD (from D)
2197 ###########################################################################
2198
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002199 for f in (d.getVar('PACKAGEBUILDPKGD') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002200 bb.build.exec_func(f, d)
2201
2202 ###########################################################################
2203 # Split up PKGD into PKGDEST
2204 ###########################################################################
2205
2206 cpath = oe.cachedpath.CachedPath()
2207
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002208 for f in (d.getVar('PACKAGESPLITFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002209 bb.build.exec_func(f, d)
2210
2211 ###########################################################################
2212 # Process PKGDEST
2213 ###########################################################################
2214
2215 # Build global list of files in each split package
2216 global pkgfiles
2217 pkgfiles = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002218 packages = d.getVar('PACKAGES').split()
2219 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002220 for pkg in packages:
2221 pkgfiles[pkg] = []
2222 for walkroot, dirs, files in cpath.walk(pkgdest + "/" + pkg):
2223 for file in files:
2224 pkgfiles[pkg].append(walkroot + os.sep + file)
2225
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002226 for f in (d.getVar('PACKAGEFUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002227 bb.build.exec_func(f, d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002228
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002229 qa_sane = d.getVar("QA_SANE")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002230 if not qa_sane:
2231 bb.fatal("Fatal QA errors found, failing task.")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002232}
2233
2234do_package[dirs] = "${SHLIBSWORKDIR} ${PKGDESTWORK} ${D}"
2235do_package[vardeps] += "${PACKAGEBUILDPKGD} ${PACKAGESPLITFUNCS} ${PACKAGEFUNCS} ${@gen_packagevar(d)}"
2236addtask package after do_install
2237
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002238SSTATETASKS += "do_package"
2239do_package[cleandirs] = "${PKGDEST} ${PKGDESTWORK}"
2240do_package[sstate-plaindirs] = "${PKGD} ${PKGDEST} ${PKGDESTWORK}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002241do_package_setscene[dirs] = "${STAGING_DIR}"
2242
2243python do_package_setscene () {
2244 sstate_setscene(d)
2245}
2246addtask do_package_setscene
2247
Brad Bishopc68388fc2019-08-26 01:33:31 -04002248# Copy from PKGDESTWORK to tempdirectory as tempdirectory can be cleaned at both
2249# do_package_setscene and do_packagedata_setscene leading to races
2250python do_packagedata () {
2251 src = d.expand("${PKGDESTWORK}")
2252 dest = d.expand("${WORKDIR}/pkgdata-pdata-input")
2253 oe.path.copyhardlinktree(src, dest)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002254}
2255
2256addtask packagedata before do_build after do_package
2257
2258SSTATETASKS += "do_packagedata"
Brad Bishopc68388fc2019-08-26 01:33:31 -04002259do_packagedata[sstate-inputdirs] = "${WORKDIR}/pkgdata-pdata-input"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002260do_packagedata[sstate-outputdirs] = "${PKGDATA_DIR}"
Brad Bishop316dfdd2018-06-25 12:45:53 -04002261do_packagedata[stamp-extra-info] = "${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002262
2263python do_packagedata_setscene () {
2264 sstate_setscene(d)
2265}
2266addtask do_packagedata_setscene
2267
2268#
2269# Helper functions for the package writing classes
2270#
2271
2272def mapping_rename_hook(d):
2273 """
2274 Rewrite variables to account for package renaming in things
2275 like debian.bbclass or manual PKG variable name changes
2276 """
Brad Bishop6e60e8b2018-02-01 10:27:11 -05002277 pkg = d.getVar("PKG")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002278 runtime_mapping_rename("RDEPENDS", pkg, d)
2279 runtime_mapping_rename("RRECOMMENDS", pkg, d)
2280 runtime_mapping_rename("RSUGGESTS", pkg, d)