blob: a428d306411bcd138a487ddcc43cd24a3ab7fdb4 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001inherit package
2
3IMAGE_PKGTYPE ?= "rpm"
4
5RPM="rpm"
6RPMBUILD="rpmbuild"
7
8PKGWRITEDIRRPM = "${WORKDIR}/deploy-rpms"
9
Brad Bishop6e60e8b2018-02-01 10:27:11 -050010# Maintaining the perfile dependencies has singificant overhead when writing the
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011# packages. When set, this value merges them for efficiency.
12MERGEPERFILEDEPS = "1"
13
Brad Bishop6e60e8b2018-02-01 10:27:11 -050014# Filter dependencies based on a provided function.
15def filter_deps(var, f):
16 import collections
17
18 depends_dict = bb.utils.explode_dep_versions2(var)
19 newdeps_dict = collections.OrderedDict()
20 for dep in depends_dict:
21 if f(dep):
22 newdeps_dict[dep] = depends_dict[dep]
23 return bb.utils.join_deps(newdeps_dict, commasep=False)
24
25# Filter out absolute paths (typically /bin/sh and /usr/bin/env) and any perl
26# dependencies for nativesdk packages.
27def filter_nativesdk_deps(srcname, var):
28 if var and srcname.startswith("nativesdk-"):
29 var = filter_deps(var, lambda dep: not dep.startswith('/') and dep != 'perl' and not dep.startswith('perl('))
30 return var
31
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032# Construct per file dependencies file
33def write_rpm_perfiledata(srcname, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050034 workdir = d.getVar('WORKDIR')
35 packages = d.getVar('PACKAGES')
36 pkgd = d.getVar('PKGD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050037
38 def dump_filerdeps(varname, outfile, d):
39 outfile.write("#!/usr/bin/env python\n\n")
40 outfile.write("# Dependency table\n")
41 outfile.write('deps = {\n')
42 for pkg in packages.split():
43 dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg
Brad Bishop6e60e8b2018-02-01 10:27:11 -050044 dependsflist = (d.getVar(dependsflist_key) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050045 for dfile in dependsflist.split():
46 key = "FILE" + varname + "_" + dfile + "_" + pkg
Brad Bishop6e60e8b2018-02-01 10:27:11 -050047 deps = filter_nativesdk_deps(srcname, d.getVar(key) or "")
48 depends_dict = bb.utils.explode_dep_versions(deps)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050049 file = dfile.replace("@underscore@", "_")
50 file = file.replace("@closebrace@", "]")
51 file = file.replace("@openbrace@", "[")
52 file = file.replace("@tab@", "\t")
53 file = file.replace("@space@", " ")
54 file = file.replace("@at@", "@")
55 outfile.write('"' + pkgd + file + '" : "')
56 for dep in depends_dict:
57 ver = depends_dict[dep]
58 if dep and ver:
59 ver = ver.replace("(","")
60 ver = ver.replace(")","")
61 outfile.write(dep + " " + ver + " ")
62 else:
63 outfile.write(dep + " ")
64 outfile.write('",\n')
65 outfile.write('}\n\n')
66 outfile.write("import sys\n")
67 outfile.write("while 1:\n")
68 outfile.write("\tline = sys.stdin.readline().strip()\n")
69 outfile.write("\tif not line:\n")
70 outfile.write("\t\tsys.exit(0)\n")
71 outfile.write("\tif line in deps:\n")
72 outfile.write("\t\tprint(deps[line] + '\\n')\n")
73
74 # OE-core dependencies a.k.a. RPM requires
75 outdepends = workdir + "/" + srcname + ".requires"
76
Brad Bishop6e60e8b2018-02-01 10:27:11 -050077 dependsfile = open(outdepends, 'w')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078
79 dump_filerdeps('RDEPENDS', dependsfile, d)
80
81 dependsfile.close()
Patrick Williamsc0f7c042017-02-23 20:41:17 -060082 os.chmod(outdepends, 0o755)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050083
84 # OE-core / RPM Provides
85 outprovides = workdir + "/" + srcname + ".provides"
86
Brad Bishop6e60e8b2018-02-01 10:27:11 -050087 providesfile = open(outprovides, 'w')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050088
89 dump_filerdeps('RPROVIDES', providesfile, d)
90
91 providesfile.close()
Patrick Williamsc0f7c042017-02-23 20:41:17 -060092 os.chmod(outprovides, 0o755)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093
94 return (outdepends, outprovides)
95
96
97python write_specfile () {
98 import oe.packagedata
99
100 # append information for logs and patches to %prep
101 def add_prep(d,spec_files_bottom):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500102 if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
103 spec_files_bottom.append('%%prep -n %s' % d.getVar('PN') )
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104 spec_files_bottom.append('%s' % "echo \"include logs and patches, Please check them in SOURCES\"")
105 spec_files_bottom.append('')
106
107 # append the name of tarball to key word 'SOURCE' in xxx.spec.
108 def tail_source(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500109 if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
110 ar_outdir = d.getVar('ARCHIVER_OUTDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111 if not os.path.exists(ar_outdir):
112 return
113 source_list = os.listdir(ar_outdir)
114 source_number = 0
115 for source in source_list:
116 # The rpmbuild doesn't need the root permission, but it needs
117 # to know the file's user and group name, the only user and
118 # group in fakeroot is "root" when working in fakeroot.
119 f = os.path.join(ar_outdir, source)
120 os.chown(f, 0, 0)
121 spec_preamble_top.append('Source%s: %s' % (source_number, source))
122 source_number += 1
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123
124 # In RPM, dependencies are of the format: pkg <>= Epoch:Version-Release
125 # This format is similar to OE, however there are restrictions on the
126 # characters that can be in a field. In the Version field, "-"
127 # characters are not allowed. "-" is allowed in the Release field.
128 #
129 # We translate the "-" in the version to a "+", by loading the PKGV
130 # from the dependent recipe, replacing the - with a +, and then using
131 # that value to do a replace inside of this recipe's dependencies.
132 # This preserves the "-" separator between the version and release, as
133 # well as any "-" characters inside of the release field.
134 #
135 # All of this has to happen BEFORE the mapping_rename_hook as
136 # after renaming we cannot look up the dependencies in the packagedata
137 # store.
138 def translate_vers(varname, d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500139 depends = d.getVar(varname)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500140 if depends:
141 depends_dict = bb.utils.explode_dep_versions2(depends)
142 newdeps_dict = {}
143 for dep in depends_dict:
144 verlist = []
145 for ver in depends_dict[dep]:
146 if '-' in ver:
147 subd = oe.packagedata.read_subpkgdata_dict(dep, d)
148 if 'PKGV' in subd:
149 pv = subd['PV']
150 pkgv = subd['PKGV']
151 reppv = pkgv.replace('-', '+')
152 ver = ver.replace(pv, reppv).replace(pkgv, reppv)
153 if 'PKGR' in subd:
154 # Make sure PKGR rather than PR in ver
155 pr = '-' + subd['PR']
156 pkgr = '-' + subd['PKGR']
157 if pkgr not in ver:
158 ver = ver.replace(pr, pkgr)
159 verlist.append(ver)
160 else:
161 verlist.append(ver)
162 newdeps_dict[dep] = verlist
163 depends = bb.utils.join_deps(newdeps_dict)
164 d.setVar(varname, depends.strip())
165
166 # We need to change the style the dependency from BB to RPM
167 # This needs to happen AFTER the mapping_rename_hook
168 def print_deps(variable, tag, array, d):
169 depends = variable
170 if depends:
171 depends_dict = bb.utils.explode_dep_versions2(depends)
172 for dep in depends_dict:
173 for ver in depends_dict[dep]:
174 ver = ver.replace('(', '')
175 ver = ver.replace(')', '')
176 array.append("%s: %s %s" % (tag, dep, ver))
177 if not len(depends_dict[dep]):
178 array.append("%s: %s" % (tag, dep))
179
180 def walk_files(walkpath, target, conffiles, dirfiles):
181 # We can race against the ipk/deb backends which create CONTROL or DEBIAN directories
182 # when packaging. We just ignore these files which are created in
183 # packages-split/ and not package/
184 # We have the odd situation where the CONTROL/DEBIAN directory can be removed in the middle of
185 # of the walk, the isdir() test would then fail and the walk code would assume its a file
186 # hence we check for the names in files too.
187 for rootpath, dirs, files in os.walk(walkpath):
188 path = rootpath.replace(walkpath, "")
189 if path.endswith("DEBIAN") or path.endswith("CONTROL"):
190 continue
191 path = path.replace("%", "%%%%%%%%")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500192 path = path.replace("[", "?")
193 path = path.replace("]", "?")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500194
195 # Treat all symlinks to directories as normal files.
196 # os.walk() lists them as directories.
197 def move_to_files(dir):
198 if os.path.islink(os.path.join(rootpath, dir)):
199 files.append(dir)
200 return True
201 else:
202 return False
203 dirs[:] = [dir for dir in dirs if not move_to_files(dir)]
204
205 # Directory handling can happen in two ways, either DIRFILES is not set at all
206 # in which case we fall back to the older behaviour of packages owning all their
207 # directories
208 if dirfiles is None:
209 for dir in dirs:
210 if dir == "CONTROL" or dir == "DEBIAN":
211 continue
212 dir = dir.replace("%", "%%%%%%%%")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500213 dir = dir.replace("[", "?")
214 dir = dir.replace("]", "?")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500215 # All packages own the directories their files are in...
216 target.append('%dir "' + path + '/' + dir + '"')
217 else:
218 # packages own only empty directories or explict directory.
219 # This will prevent the overlapping of security permission.
220 if path and not files and not dirs:
221 target.append('%dir "' + path + '"')
222 elif path and path in dirfiles:
223 target.append('%dir "' + path + '"')
224
225 for file in files:
226 if file == "CONTROL" or file == "DEBIAN":
227 continue
228 file = file.replace("%", "%%%%%%%%")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500229 file = file.replace("[", "?")
230 file = file.replace("]", "?")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500231 if conffiles.count(path + '/' + file):
232 target.append('%config "' + path + '/' + file + '"')
233 else:
234 target.append('"' + path + '/' + file + '"')
235
236 # Prevent the prerm/postrm scripts from being run during an upgrade
237 def wrap_uninstall(scriptvar):
238 scr = scriptvar.strip()
239 if scr.startswith("#!"):
240 pos = scr.find("\n") + 1
241 else:
242 pos = 0
243 scr = scr[:pos] + 'if [ "$1" = "0" ] ; then\n' + scr[pos:] + '\nfi'
244 return scr
245
246 def get_perfile(varname, pkg, d):
247 deps = []
248 dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500249 dependsflist = (d.getVar(dependsflist_key) or "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 for dfile in dependsflist.split():
251 key = "FILE" + varname + "_" + dfile + "_" + pkg
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500252 depends = d.getVar(key)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500253 if depends:
254 deps.append(depends)
255 return " ".join(deps)
256
257 def append_description(spec_preamble, text):
258 """
259 Add the description to the spec file.
260 """
261 import textwrap
262 dedent_text = textwrap.dedent(text).strip()
263 # Bitbake saves "\n" as "\\n"
264 if '\\n' in dedent_text:
265 for t in dedent_text.split('\\n'):
266 spec_preamble.append(t.strip())
267 else:
268 spec_preamble.append('%s' % textwrap.fill(dedent_text, width=75))
269
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500270 packages = d.getVar('PACKAGES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500271 if not packages or packages == '':
272 bb.debug(1, "No packages; nothing to do")
273 return
274
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500275 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500276 if not pkgdest:
277 bb.fatal("No PKGDEST")
278
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500279 outspecfile = d.getVar('OUTSPECFILE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500280 if not outspecfile:
281 bb.fatal("No OUTSPECFILE")
282
283 # Construct the SPEC file...
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500284 srcname = d.getVar('PN')
285 srcsummary = (d.getVar('SUMMARY') or d.getVar('DESCRIPTION') or ".")
286 srcversion = d.getVar('PKGV').replace('-', '+')
287 srcrelease = d.getVar('PKGR')
288 srcepoch = (d.getVar('PKGE') or "")
289 srclicense = d.getVar('LICENSE')
290 srcsection = d.getVar('SECTION')
291 srcmaintainer = d.getVar('MAINTAINER')
292 srchomepage = d.getVar('HOMEPAGE')
293 srcdescription = d.getVar('DESCRIPTION') or "."
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500294 srccustomtagschunk = get_package_additional_metadata("rpm", d)
295
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500296 srcdepends = d.getVar('DEPENDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500297 srcrdepends = []
298 srcrrecommends = []
299 srcrsuggests = []
300 srcrprovides = []
301 srcrreplaces = []
302 srcrconflicts = []
303 srcrobsoletes = []
304
305 srcrpreinst = []
306 srcrpostinst = []
307 srcrprerm = []
308 srcrpostrm = []
309
310 spec_preamble_top = []
311 spec_preamble_bottom = []
312
313 spec_scriptlets_top = []
314 spec_scriptlets_bottom = []
315
316 spec_files_top = []
317 spec_files_bottom = []
318
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500319 perfiledeps = (d.getVar("MERGEPERFILEDEPS") or "0") == "0"
320 extra_pkgdata = (d.getVar("RPM_EXTRA_PKGDATA") or "0") == "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500321
322 for pkg in packages.split():
323 localdata = bb.data.createCopy(d)
324
325 root = "%s/%s" % (pkgdest, pkg)
326
327 localdata.setVar('ROOT', '')
328 localdata.setVar('ROOT_%s' % pkg, root)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500329 pkgname = localdata.getVar('PKG_%s' % pkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500330 if not pkgname:
331 pkgname = pkg
332 localdata.setVar('PKG', pkgname)
333
334 localdata.setVar('OVERRIDES', d.getVar("OVERRIDES", False) + ":" + pkg)
335
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500336 conffiles = get_conffiles(pkg, d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500337 dirfiles = localdata.getVar('DIRFILES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500338 if dirfiles is not None:
339 dirfiles = dirfiles.split()
340
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500341 splitname = pkgname
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500342
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500343 splitsummary = (localdata.getVar('SUMMARY') or localdata.getVar('DESCRIPTION') or ".")
344 splitversion = (localdata.getVar('PKGV') or "").replace('-', '+')
345 splitrelease = (localdata.getVar('PKGR') or "")
346 splitepoch = (localdata.getVar('PKGE') or "")
347 splitlicense = (localdata.getVar('LICENSE') or "")
348 splitsection = (localdata.getVar('SECTION') or "")
349 splitdescription = (localdata.getVar('DESCRIPTION') or ".")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500350 splitcustomtagschunk = get_package_additional_metadata("rpm", localdata)
351
352 translate_vers('RDEPENDS', localdata)
353 translate_vers('RRECOMMENDS', localdata)
354 translate_vers('RSUGGESTS', localdata)
355 translate_vers('RPROVIDES', localdata)
356 translate_vers('RREPLACES', localdata)
357 translate_vers('RCONFLICTS', localdata)
358
359 # Map the dependencies into their final form
360 mapping_rename_hook(localdata)
361
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500362 splitrdepends = localdata.getVar('RDEPENDS')
363 splitrrecommends = localdata.getVar('RRECOMMENDS')
364 splitrsuggests = localdata.getVar('RSUGGESTS')
365 splitrprovides = localdata.getVar('RPROVIDES')
366 splitrreplaces = localdata.getVar('RREPLACES')
367 splitrconflicts = localdata.getVar('RCONFLICTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368 splitrobsoletes = []
369
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500370 splitrpreinst = localdata.getVar('pkg_preinst')
371 splitrpostinst = localdata.getVar('pkg_postinst')
372 splitrprerm = localdata.getVar('pkg_prerm')
373 splitrpostrm = localdata.getVar('pkg_postrm')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500374
375
376 if not perfiledeps:
377 # Add in summary of per file dependencies
378 splitrdepends = splitrdepends + " " + get_perfile('RDEPENDS', pkg, d)
379 splitrprovides = splitrprovides + " " + get_perfile('RPROVIDES', pkg, d)
380
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500381 splitrdepends = filter_nativesdk_deps(srcname, splitrdepends)
382
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500383 # Gather special src/first package data
384 if srcname == splitname:
385 srcrdepends = splitrdepends
386 srcrrecommends = splitrrecommends
387 srcrsuggests = splitrsuggests
388 srcrprovides = splitrprovides
389 srcrreplaces = splitrreplaces
390 srcrconflicts = splitrconflicts
391
392 srcrpreinst = splitrpreinst
393 srcrpostinst = splitrpostinst
394 srcrprerm = splitrprerm
395 srcrpostrm = splitrpostrm
396
397 file_list = []
398 walk_files(root, file_list, conffiles, dirfiles)
399 if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1":
400 bb.note("Not creating empty RPM package for %s" % splitname)
401 else:
402 bb.note("Creating RPM package for %s" % splitname)
403 spec_files_top.append('%files')
404 if extra_pkgdata:
405 package_rpm_extra_pkgdata(splitname, spec_files_top, localdata)
406 spec_files_top.append('%defattr(-,-,-,-)')
407 if file_list:
408 bb.note("Creating RPM package for %s" % splitname)
409 spec_files_top.extend(file_list)
410 else:
411 bb.note("Creating EMPTY RPM Package for %s" % splitname)
412 spec_files_top.append('')
413 continue
414
415 # Process subpackage data
416 spec_preamble_bottom.append('%%package -n %s' % splitname)
417 spec_preamble_bottom.append('Summary: %s' % splitsummary)
418 if srcversion != splitversion:
419 spec_preamble_bottom.append('Version: %s' % splitversion)
420 if srcrelease != splitrelease:
421 spec_preamble_bottom.append('Release: %s' % splitrelease)
422 if srcepoch != splitepoch:
423 spec_preamble_bottom.append('Epoch: %s' % splitepoch)
424 if srclicense != splitlicense:
425 spec_preamble_bottom.append('License: %s' % splitlicense)
426 spec_preamble_bottom.append('Group: %s' % splitsection)
427
428 if srccustomtagschunk != splitcustomtagschunk:
429 spec_preamble_bottom.append(splitcustomtagschunk)
430
431 # Replaces == Obsoletes && Provides
432 robsoletes = bb.utils.explode_dep_versions2(splitrobsoletes or "")
433 rprovides = bb.utils.explode_dep_versions2(splitrprovides or "")
434 rreplaces = bb.utils.explode_dep_versions2(splitrreplaces or "")
435 for dep in rreplaces:
436 if not dep in robsoletes:
437 robsoletes[dep] = rreplaces[dep]
438 if not dep in rprovides:
439 rprovides[dep] = rreplaces[dep]
440 splitrobsoletes = bb.utils.join_deps(robsoletes, commasep=False)
441 splitrprovides = bb.utils.join_deps(rprovides, commasep=False)
442
443 print_deps(splitrdepends, "Requires", spec_preamble_bottom, d)
444 if splitrpreinst:
445 print_deps(splitrdepends, "Requires(pre)", spec_preamble_bottom, d)
446 if splitrpostinst:
447 print_deps(splitrdepends, "Requires(post)", spec_preamble_bottom, d)
448 if splitrprerm:
449 print_deps(splitrdepends, "Requires(preun)", spec_preamble_bottom, d)
450 if splitrpostrm:
451 print_deps(splitrdepends, "Requires(postun)", spec_preamble_bottom, d)
452
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500453 print_deps(splitrrecommends, "Recommends", spec_preamble_bottom, d)
454 print_deps(splitrsuggests, "Suggests", spec_preamble_bottom, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500455 print_deps(splitrprovides, "Provides", spec_preamble_bottom, d)
456 print_deps(splitrobsoletes, "Obsoletes", spec_preamble_bottom, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500457 print_deps(splitrconflicts, "Conflicts", spec_preamble_bottom, d)
458
459 spec_preamble_bottom.append('')
460
461 spec_preamble_bottom.append('%%description -n %s' % splitname)
462 append_description(spec_preamble_bottom, splitdescription)
463
464 spec_preamble_bottom.append('')
465
466 # Now process scriptlets
467 if splitrpreinst:
468 spec_scriptlets_bottom.append('%%pre -n %s' % splitname)
469 spec_scriptlets_bottom.append('# %s - preinst' % splitname)
470 spec_scriptlets_bottom.append(splitrpreinst)
471 spec_scriptlets_bottom.append('')
472 if splitrpostinst:
473 spec_scriptlets_bottom.append('%%post -n %s' % splitname)
474 spec_scriptlets_bottom.append('# %s - postinst' % splitname)
475 spec_scriptlets_bottom.append(splitrpostinst)
476 spec_scriptlets_bottom.append('')
477 if splitrprerm:
478 spec_scriptlets_bottom.append('%%preun -n %s' % splitname)
479 spec_scriptlets_bottom.append('# %s - prerm' % splitname)
480 scriptvar = wrap_uninstall(splitrprerm)
481 spec_scriptlets_bottom.append(scriptvar)
482 spec_scriptlets_bottom.append('')
483 if splitrpostrm:
484 spec_scriptlets_bottom.append('%%postun -n %s' % splitname)
485 spec_scriptlets_bottom.append('# %s - postrm' % splitname)
486 scriptvar = wrap_uninstall(splitrpostrm)
487 spec_scriptlets_bottom.append(scriptvar)
488 spec_scriptlets_bottom.append('')
489
490 # Now process files
491 file_list = []
492 walk_files(root, file_list, conffiles, dirfiles)
493 if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1":
494 bb.note("Not creating empty RPM package for %s" % splitname)
495 else:
496 spec_files_bottom.append('%%files -n %s' % splitname)
497 if extra_pkgdata:
498 package_rpm_extra_pkgdata(splitname, spec_files_bottom, localdata)
499 spec_files_bottom.append('%defattr(-,-,-,-)')
500 if file_list:
501 bb.note("Creating RPM package for %s" % splitname)
502 spec_files_bottom.extend(file_list)
503 else:
504 bb.note("Creating EMPTY RPM Package for %s" % splitname)
505 spec_files_bottom.append('')
506
507 del localdata
508
509 add_prep(d,spec_files_bottom)
510 spec_preamble_top.append('Summary: %s' % srcsummary)
511 spec_preamble_top.append('Name: %s' % srcname)
512 spec_preamble_top.append('Version: %s' % srcversion)
513 spec_preamble_top.append('Release: %s' % srcrelease)
514 if srcepoch and srcepoch.strip() != "":
515 spec_preamble_top.append('Epoch: %s' % srcepoch)
516 spec_preamble_top.append('License: %s' % srclicense)
517 spec_preamble_top.append('Group: %s' % srcsection)
518 spec_preamble_top.append('Packager: %s' % srcmaintainer)
519 if srchomepage:
520 spec_preamble_top.append('URL: %s' % srchomepage)
521 if srccustomtagschunk:
522 spec_preamble_top.append(srccustomtagschunk)
523 tail_source(d)
524
525 # Replaces == Obsoletes && Provides
526 robsoletes = bb.utils.explode_dep_versions2(srcrobsoletes or "")
527 rprovides = bb.utils.explode_dep_versions2(srcrprovides or "")
528 rreplaces = bb.utils.explode_dep_versions2(srcrreplaces or "")
529 for dep in rreplaces:
530 if not dep in robsoletes:
531 robsoletes[dep] = rreplaces[dep]
532 if not dep in rprovides:
533 rprovides[dep] = rreplaces[dep]
534 srcrobsoletes = bb.utils.join_deps(robsoletes, commasep=False)
535 srcrprovides = bb.utils.join_deps(rprovides, commasep=False)
536
537 print_deps(srcdepends, "BuildRequires", spec_preamble_top, d)
538 print_deps(srcrdepends, "Requires", spec_preamble_top, d)
539 if srcrpreinst:
540 print_deps(srcrdepends, "Requires(pre)", spec_preamble_top, d)
541 if srcrpostinst:
542 print_deps(srcrdepends, "Requires(post)", spec_preamble_top, d)
543 if srcrprerm:
544 print_deps(srcrdepends, "Requires(preun)", spec_preamble_top, d)
545 if srcrpostrm:
546 print_deps(srcrdepends, "Requires(postun)", spec_preamble_top, d)
547
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500548 print_deps(srcrrecommends, "Recommends", spec_preamble_top, d)
549 print_deps(srcrsuggests, "Suggests", spec_preamble_top, d)
550 print_deps(srcrprovides + (" /bin/sh" if srcname.startswith("nativesdk-") else ""), "Provides", spec_preamble_top, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500551 print_deps(srcrobsoletes, "Obsoletes", spec_preamble_top, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500552 print_deps(srcrconflicts, "Conflicts", spec_preamble_top, d)
553
554 spec_preamble_top.append('')
555
556 spec_preamble_top.append('%description')
557 append_description(spec_preamble_top, srcdescription)
558
559 spec_preamble_top.append('')
560
561 if srcrpreinst:
562 spec_scriptlets_top.append('%pre')
563 spec_scriptlets_top.append('# %s - preinst' % srcname)
564 spec_scriptlets_top.append(srcrpreinst)
565 spec_scriptlets_top.append('')
566 if srcrpostinst:
567 spec_scriptlets_top.append('%post')
568 spec_scriptlets_top.append('# %s - postinst' % srcname)
569 spec_scriptlets_top.append(srcrpostinst)
570 spec_scriptlets_top.append('')
571 if srcrprerm:
572 spec_scriptlets_top.append('%preun')
573 spec_scriptlets_top.append('# %s - prerm' % srcname)
574 scriptvar = wrap_uninstall(srcrprerm)
575 spec_scriptlets_top.append(scriptvar)
576 spec_scriptlets_top.append('')
577 if srcrpostrm:
578 spec_scriptlets_top.append('%postun')
579 spec_scriptlets_top.append('# %s - postrm' % srcname)
580 scriptvar = wrap_uninstall(srcrpostrm)
581 spec_scriptlets_top.append(scriptvar)
582 spec_scriptlets_top.append('')
583
584 # Write the SPEC file
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500585 specfile = open(outspecfile, 'w')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500586
587 # RPMSPEC_PREAMBLE is a way to add arbitrary text to the top
588 # of the generated spec file
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500589 external_preamble = d.getVar("RPMSPEC_PREAMBLE")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500590 if external_preamble:
591 specfile.write(external_preamble + "\n")
592
593 for line in spec_preamble_top:
594 specfile.write(line + "\n")
595
596 for line in spec_preamble_bottom:
597 specfile.write(line + "\n")
598
599 for line in spec_scriptlets_top:
600 specfile.write(line + "\n")
601
602 for line in spec_scriptlets_bottom:
603 specfile.write(line + "\n")
604
605 for line in spec_files_top:
606 specfile.write(line + "\n")
607
608 for line in spec_files_bottom:
609 specfile.write(line + "\n")
610
611 specfile.close()
612}
613# Otherwise allarch packages may change depending on override configuration
614write_specfile[vardepsexclude] = "OVERRIDES"
615
616python do_package_rpm () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500617 workdir = d.getVar('WORKDIR')
618 tmpdir = d.getVar('TMPDIR')
619 pkgd = d.getVar('PKGD')
620 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500621 if not workdir or not pkgd or not tmpdir:
622 bb.error("Variables incorrectly set, unable to package")
623 return
624
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500625 packages = d.getVar('PACKAGES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500626 if not packages or packages == '':
627 bb.debug(1, "No packages; nothing to do")
628 return
629
630 # Construct the spec file...
631 # If the spec file already exist, and has not been stored into
632 # pseudo's files.db, it maybe cause rpmbuild src.rpm fail,
633 # so remove it before doing rpmbuild src.rpm.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500634 srcname = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500635 outspecfile = workdir + "/" + srcname + ".spec"
636 if os.path.isfile(outspecfile):
637 os.remove(outspecfile)
638 d.setVar('OUTSPECFILE', outspecfile)
639 bb.build.exec_func('write_specfile', d)
640
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500641 perfiledeps = (d.getVar("MERGEPERFILEDEPS") or "0") == "0"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500642 if perfiledeps:
643 outdepends, outprovides = write_rpm_perfiledata(srcname, d)
644
645 # Setup the rpmbuild arguments...
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500646 rpmbuild = d.getVar('RPMBUILD')
647 targetsys = d.getVar('TARGET_SYS')
648 targetvendor = d.getVar('HOST_VENDOR')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500649
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500650 # Too many places in dnf stack assume that arch-independent packages are "noarch".
651 # Let's not fight against this.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500652 package_arch = (d.getVar('PACKAGE_ARCH') or "").replace("-", "_")
653 if package_arch == "all":
654 package_arch = "noarch"
655
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500656 sdkpkgsuffix = (d.getVar('SDKPKGSUFFIX') or "nativesdk").replace("-", "_")
657 d.setVar('PACKAGE_ARCH_EXTEND', package_arch)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500658 pkgwritedir = d.expand('${PKGWRITEDIRRPM}/${PACKAGE_ARCH_EXTEND}')
659 d.setVar('RPM_PKGWRITEDIR', pkgwritedir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500660 bb.debug(1, 'PKGWRITEDIR: %s' % d.getVar('RPM_PKGWRITEDIR'))
661 pkgarch = d.expand('${PACKAGE_ARCH_EXTEND}${HOST_VENDOR}-linux')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500662 bb.utils.mkdirhier(pkgwritedir)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600663 os.chmod(pkgwritedir, 0o755)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664
665 cmd = rpmbuild
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500666 cmd = cmd + " --noclean --nodeps --short-circuit --target " + pkgarch + " --buildroot " + pkgd
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667 cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500668 cmd = cmd + " --define '_builddir " + d.getVar('S') + "'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500669 cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'"
670 cmd = cmd + " --define '_use_internal_dependency_generator 0'"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500671 cmd = cmd + " --define '_binaries_in_noarch_packages_terminate_build 0'"
672 cmd = cmd + " --define '_build_id_links none'"
673 cmd = cmd + " --define '_binary_payload w6T.xzdio'"
674 cmd = cmd + " --define '_source_payload w6T.xzdio'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500675 if perfiledeps:
676 cmd = cmd + " --define '__find_requires " + outdepends + "'"
677 cmd = cmd + " --define '__find_provides " + outprovides + "'"
678 else:
679 cmd = cmd + " --define '__find_requires %{nil}'"
680 cmd = cmd + " --define '__find_provides %{nil}'"
681 cmd = cmd + " --define '_unpackaged_files_terminate_build 0'"
682 cmd = cmd + " --define 'debug_package %{nil}'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500683 cmd = cmd + " --define '_tmppath " + workdir + "'"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500684 if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
685 cmd = cmd + " --define '_sourcedir " + d.getVar('ARCHIVER_OUTDIR') + "'"
686 cmdsrpm = cmd + " --define '_srcrpmdir " + d.getVar('ARCHIVER_OUTDIR') + "'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500687 cmdsrpm = cmdsrpm + " -bs " + outspecfile
688 # Build the .src.rpm
689 d.setVar('SBUILDSPEC', cmdsrpm + "\n")
690 d.setVarFlag('SBUILDSPEC', 'func', '1')
691 bb.build.exec_func('SBUILDSPEC', d)
692 cmd = cmd + " -bb " + outspecfile
693
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500694 # rpm 4 creates various empty directories in _topdir, let's clean them up
695 cleanupcmd = "rm -rf %s/BUILDROOT %s/SOURCES %s/SPECS %s/SRPMS" % (workdir, workdir, workdir, workdir)
696
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500697 # Build the rpm package!
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500698 d.setVar('BUILDSPEC', cmd + "\n" + cleanupcmd + "\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500699 d.setVarFlag('BUILDSPEC', 'func', '1')
700 bb.build.exec_func('BUILDSPEC', d)
701
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500702 if d.getVar('RPM_SIGN_PACKAGES') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500703 bb.build.exec_func("sign_rpm", d)
704}
705
706python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500707 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500708 deps = ' rpm-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot'
709 d.appendVarFlag('do_package_write_rpm', 'depends', deps)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500710 d.setVarFlag('do_package_write_rpm', 'fakeroot', '1')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500711}
712
713SSTATETASKS += "do_package_write_rpm"
714do_package_write_rpm[sstate-inputdirs] = "${PKGWRITEDIRRPM}"
715do_package_write_rpm[sstate-outputdirs] = "${DEPLOY_DIR_RPM}"
716# Take a shared lock, we can write multiple packages at the same time...
717# but we need to stop the rootfs/solver from running while we do...
718do_package_write_rpm[sstate-lockfile-shared] += "${DEPLOY_DIR_RPM}/rpm.lock"
719
720python do_package_write_rpm_setscene () {
721 sstate_setscene(d)
722}
723addtask do_package_write_rpm_setscene
724
725python do_package_write_rpm () {
726 bb.build.exec_func("read_subpackage_metadata", d)
727 bb.build.exec_func("do_package_rpm", d)
728}
729
730do_package_write_rpm[dirs] = "${PKGWRITEDIRRPM}"
731do_package_write_rpm[cleandirs] = "${PKGWRITEDIRRPM}"
732do_package_write_rpm[umask] = "022"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500733do_package_write_rpm[depends] += "${@oe.utils.build_depends_string(d.getVar('PACKAGE_WRITE_DEPS'), 'do_populate_sysroot')}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500734addtask package_write_rpm after do_packagedata do_package
735
736PACKAGEINDEXDEPS += "rpm-native:do_populate_sysroot"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500737PACKAGEINDEXDEPS += "createrepo-c-native:do_populate_sysroot"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500738
739do_build[recrdeptask] += "do_package_write_rpm"