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