blob: 21ada348aaa372ffac70b3461dc680ff103000b5 [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:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400385 archiving = d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and \
386 bb.data.inherits_class('archiver', d)
387 if archiving and srclicense != splitlicense:
388 bb.warn("The SRPM produced may not have the correct overall source license in the License tag. This is due to the LICENSE for the primary package and SRPM conflicting.")
389
390 srclicense = splitlicense
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500391 srcrdepends = splitrdepends
392 srcrrecommends = splitrrecommends
393 srcrsuggests = splitrsuggests
394 srcrprovides = splitrprovides
395 srcrreplaces = splitrreplaces
396 srcrconflicts = splitrconflicts
397
398 srcrpreinst = splitrpreinst
399 srcrpostinst = splitrpostinst
400 srcrprerm = splitrprerm
401 srcrpostrm = splitrpostrm
402
403 file_list = []
404 walk_files(root, file_list, conffiles, dirfiles)
405 if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1":
406 bb.note("Not creating empty RPM package for %s" % splitname)
407 else:
408 bb.note("Creating RPM package for %s" % splitname)
409 spec_files_top.append('%files')
410 if extra_pkgdata:
411 package_rpm_extra_pkgdata(splitname, spec_files_top, localdata)
412 spec_files_top.append('%defattr(-,-,-,-)')
413 if file_list:
414 bb.note("Creating RPM package for %s" % splitname)
415 spec_files_top.extend(file_list)
416 else:
417 bb.note("Creating EMPTY RPM Package for %s" % splitname)
418 spec_files_top.append('')
419 continue
420
421 # Process subpackage data
422 spec_preamble_bottom.append('%%package -n %s' % splitname)
423 spec_preamble_bottom.append('Summary: %s' % splitsummary)
424 if srcversion != splitversion:
425 spec_preamble_bottom.append('Version: %s' % splitversion)
426 if srcrelease != splitrelease:
427 spec_preamble_bottom.append('Release: %s' % splitrelease)
428 if srcepoch != splitepoch:
429 spec_preamble_bottom.append('Epoch: %s' % splitepoch)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400430 spec_preamble_bottom.append('License: %s' % splitlicense)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500431 spec_preamble_bottom.append('Group: %s' % splitsection)
432
433 if srccustomtagschunk != splitcustomtagschunk:
434 spec_preamble_bottom.append(splitcustomtagschunk)
435
436 # Replaces == Obsoletes && Provides
437 robsoletes = bb.utils.explode_dep_versions2(splitrobsoletes or "")
438 rprovides = bb.utils.explode_dep_versions2(splitrprovides or "")
439 rreplaces = bb.utils.explode_dep_versions2(splitrreplaces or "")
440 for dep in rreplaces:
441 if not dep in robsoletes:
442 robsoletes[dep] = rreplaces[dep]
443 if not dep in rprovides:
444 rprovides[dep] = rreplaces[dep]
445 splitrobsoletes = bb.utils.join_deps(robsoletes, commasep=False)
446 splitrprovides = bb.utils.join_deps(rprovides, commasep=False)
447
448 print_deps(splitrdepends, "Requires", spec_preamble_bottom, d)
449 if splitrpreinst:
450 print_deps(splitrdepends, "Requires(pre)", spec_preamble_bottom, d)
451 if splitrpostinst:
452 print_deps(splitrdepends, "Requires(post)", spec_preamble_bottom, d)
453 if splitrprerm:
454 print_deps(splitrdepends, "Requires(preun)", spec_preamble_bottom, d)
455 if splitrpostrm:
456 print_deps(splitrdepends, "Requires(postun)", spec_preamble_bottom, d)
457
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500458 print_deps(splitrrecommends, "Recommends", spec_preamble_bottom, d)
459 print_deps(splitrsuggests, "Suggests", spec_preamble_bottom, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500460 print_deps(splitrprovides, "Provides", spec_preamble_bottom, d)
461 print_deps(splitrobsoletes, "Obsoletes", spec_preamble_bottom, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500462 print_deps(splitrconflicts, "Conflicts", spec_preamble_bottom, d)
463
464 spec_preamble_bottom.append('')
465
466 spec_preamble_bottom.append('%%description -n %s' % splitname)
467 append_description(spec_preamble_bottom, splitdescription)
468
469 spec_preamble_bottom.append('')
470
471 # Now process scriptlets
472 if splitrpreinst:
473 spec_scriptlets_bottom.append('%%pre -n %s' % splitname)
474 spec_scriptlets_bottom.append('# %s - preinst' % splitname)
475 spec_scriptlets_bottom.append(splitrpreinst)
476 spec_scriptlets_bottom.append('')
477 if splitrpostinst:
478 spec_scriptlets_bottom.append('%%post -n %s' % splitname)
479 spec_scriptlets_bottom.append('# %s - postinst' % splitname)
480 spec_scriptlets_bottom.append(splitrpostinst)
481 spec_scriptlets_bottom.append('')
482 if splitrprerm:
483 spec_scriptlets_bottom.append('%%preun -n %s' % splitname)
484 spec_scriptlets_bottom.append('# %s - prerm' % splitname)
485 scriptvar = wrap_uninstall(splitrprerm)
486 spec_scriptlets_bottom.append(scriptvar)
487 spec_scriptlets_bottom.append('')
488 if splitrpostrm:
489 spec_scriptlets_bottom.append('%%postun -n %s' % splitname)
490 spec_scriptlets_bottom.append('# %s - postrm' % splitname)
491 scriptvar = wrap_uninstall(splitrpostrm)
492 spec_scriptlets_bottom.append(scriptvar)
493 spec_scriptlets_bottom.append('')
494
495 # Now process files
496 file_list = []
497 walk_files(root, file_list, conffiles, dirfiles)
498 if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1":
499 bb.note("Not creating empty RPM package for %s" % splitname)
500 else:
501 spec_files_bottom.append('%%files -n %s' % splitname)
502 if extra_pkgdata:
503 package_rpm_extra_pkgdata(splitname, spec_files_bottom, localdata)
504 spec_files_bottom.append('%defattr(-,-,-,-)')
505 if file_list:
506 bb.note("Creating RPM package for %s" % splitname)
507 spec_files_bottom.extend(file_list)
508 else:
509 bb.note("Creating EMPTY RPM Package for %s" % splitname)
510 spec_files_bottom.append('')
511
512 del localdata
513
514 add_prep(d,spec_files_bottom)
515 spec_preamble_top.append('Summary: %s' % srcsummary)
516 spec_preamble_top.append('Name: %s' % srcname)
517 spec_preamble_top.append('Version: %s' % srcversion)
518 spec_preamble_top.append('Release: %s' % srcrelease)
519 if srcepoch and srcepoch.strip() != "":
520 spec_preamble_top.append('Epoch: %s' % srcepoch)
521 spec_preamble_top.append('License: %s' % srclicense)
522 spec_preamble_top.append('Group: %s' % srcsection)
523 spec_preamble_top.append('Packager: %s' % srcmaintainer)
524 if srchomepage:
525 spec_preamble_top.append('URL: %s' % srchomepage)
526 if srccustomtagschunk:
527 spec_preamble_top.append(srccustomtagschunk)
528 tail_source(d)
529
530 # Replaces == Obsoletes && Provides
531 robsoletes = bb.utils.explode_dep_versions2(srcrobsoletes or "")
532 rprovides = bb.utils.explode_dep_versions2(srcrprovides or "")
533 rreplaces = bb.utils.explode_dep_versions2(srcrreplaces or "")
534 for dep in rreplaces:
535 if not dep in robsoletes:
536 robsoletes[dep] = rreplaces[dep]
537 if not dep in rprovides:
538 rprovides[dep] = rreplaces[dep]
539 srcrobsoletes = bb.utils.join_deps(robsoletes, commasep=False)
540 srcrprovides = bb.utils.join_deps(rprovides, commasep=False)
541
542 print_deps(srcdepends, "BuildRequires", spec_preamble_top, d)
543 print_deps(srcrdepends, "Requires", spec_preamble_top, d)
544 if srcrpreinst:
545 print_deps(srcrdepends, "Requires(pre)", spec_preamble_top, d)
546 if srcrpostinst:
547 print_deps(srcrdepends, "Requires(post)", spec_preamble_top, d)
548 if srcrprerm:
549 print_deps(srcrdepends, "Requires(preun)", spec_preamble_top, d)
550 if srcrpostrm:
551 print_deps(srcrdepends, "Requires(postun)", spec_preamble_top, d)
552
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500553 print_deps(srcrrecommends, "Recommends", spec_preamble_top, d)
554 print_deps(srcrsuggests, "Suggests", spec_preamble_top, d)
555 print_deps(srcrprovides + (" /bin/sh" if srcname.startswith("nativesdk-") else ""), "Provides", spec_preamble_top, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556 print_deps(srcrobsoletes, "Obsoletes", spec_preamble_top, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557 print_deps(srcrconflicts, "Conflicts", spec_preamble_top, d)
558
559 spec_preamble_top.append('')
560
561 spec_preamble_top.append('%description')
562 append_description(spec_preamble_top, srcdescription)
563
564 spec_preamble_top.append('')
565
566 if srcrpreinst:
567 spec_scriptlets_top.append('%pre')
568 spec_scriptlets_top.append('# %s - preinst' % srcname)
569 spec_scriptlets_top.append(srcrpreinst)
570 spec_scriptlets_top.append('')
571 if srcrpostinst:
572 spec_scriptlets_top.append('%post')
573 spec_scriptlets_top.append('# %s - postinst' % srcname)
574 spec_scriptlets_top.append(srcrpostinst)
575 spec_scriptlets_top.append('')
576 if srcrprerm:
577 spec_scriptlets_top.append('%preun')
578 spec_scriptlets_top.append('# %s - prerm' % srcname)
579 scriptvar = wrap_uninstall(srcrprerm)
580 spec_scriptlets_top.append(scriptvar)
581 spec_scriptlets_top.append('')
582 if srcrpostrm:
583 spec_scriptlets_top.append('%postun')
584 spec_scriptlets_top.append('# %s - postrm' % srcname)
585 scriptvar = wrap_uninstall(srcrpostrm)
586 spec_scriptlets_top.append(scriptvar)
587 spec_scriptlets_top.append('')
588
589 # Write the SPEC file
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500590 specfile = open(outspecfile, 'w')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500591
592 # RPMSPEC_PREAMBLE is a way to add arbitrary text to the top
593 # of the generated spec file
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500594 external_preamble = d.getVar("RPMSPEC_PREAMBLE")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500595 if external_preamble:
596 specfile.write(external_preamble + "\n")
597
598 for line in spec_preamble_top:
599 specfile.write(line + "\n")
600
601 for line in spec_preamble_bottom:
602 specfile.write(line + "\n")
603
604 for line in spec_scriptlets_top:
605 specfile.write(line + "\n")
606
607 for line in spec_scriptlets_bottom:
608 specfile.write(line + "\n")
609
610 for line in spec_files_top:
611 specfile.write(line + "\n")
612
613 for line in spec_files_bottom:
614 specfile.write(line + "\n")
615
616 specfile.close()
617}
618# Otherwise allarch packages may change depending on override configuration
619write_specfile[vardepsexclude] = "OVERRIDES"
620
621python do_package_rpm () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500622 workdir = d.getVar('WORKDIR')
623 tmpdir = d.getVar('TMPDIR')
624 pkgd = d.getVar('PKGD')
625 pkgdest = d.getVar('PKGDEST')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500626 if not workdir or not pkgd or not tmpdir:
627 bb.error("Variables incorrectly set, unable to package")
628 return
629
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500630 packages = d.getVar('PACKAGES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500631 if not packages or packages == '':
632 bb.debug(1, "No packages; nothing to do")
633 return
634
635 # Construct the spec file...
636 # If the spec file already exist, and has not been stored into
637 # pseudo's files.db, it maybe cause rpmbuild src.rpm fail,
638 # so remove it before doing rpmbuild src.rpm.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500639 srcname = d.getVar('PN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500640 outspecfile = workdir + "/" + srcname + ".spec"
641 if os.path.isfile(outspecfile):
642 os.remove(outspecfile)
643 d.setVar('OUTSPECFILE', outspecfile)
644 bb.build.exec_func('write_specfile', d)
645
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500646 perfiledeps = (d.getVar("MERGEPERFILEDEPS") or "0") == "0"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500647 if perfiledeps:
648 outdepends, outprovides = write_rpm_perfiledata(srcname, d)
649
650 # Setup the rpmbuild arguments...
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500651 rpmbuild = d.getVar('RPMBUILD')
652 targetsys = d.getVar('TARGET_SYS')
653 targetvendor = d.getVar('HOST_VENDOR')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500654
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500655 # Too many places in dnf stack assume that arch-independent packages are "noarch".
656 # Let's not fight against this.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500657 package_arch = (d.getVar('PACKAGE_ARCH') or "").replace("-", "_")
658 if package_arch == "all":
659 package_arch = "noarch"
660
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500661 sdkpkgsuffix = (d.getVar('SDKPKGSUFFIX') or "nativesdk").replace("-", "_")
662 d.setVar('PACKAGE_ARCH_EXTEND', package_arch)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500663 pkgwritedir = d.expand('${PKGWRITEDIRRPM}/${PACKAGE_ARCH_EXTEND}')
664 d.setVar('RPM_PKGWRITEDIR', pkgwritedir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500665 bb.debug(1, 'PKGWRITEDIR: %s' % d.getVar('RPM_PKGWRITEDIR'))
666 pkgarch = d.expand('${PACKAGE_ARCH_EXTEND}${HOST_VENDOR}-linux')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667 bb.utils.mkdirhier(pkgwritedir)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600668 os.chmod(pkgwritedir, 0o755)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500669
670 cmd = rpmbuild
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500671 cmd = cmd + " --noclean --nodeps --short-circuit --target " + pkgarch + " --buildroot " + pkgd
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500672 cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'"
Brad Bishop316dfdd2018-06-25 12:45:53 -0400673 cmd = cmd + " --define '_builddir " + d.getVar('B') + "'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500674 cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'"
675 cmd = cmd + " --define '_use_internal_dependency_generator 0'"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500676 cmd = cmd + " --define '_binaries_in_noarch_packages_terminate_build 0'"
677 cmd = cmd + " --define '_build_id_links none'"
678 cmd = cmd + " --define '_binary_payload w6T.xzdio'"
679 cmd = cmd + " --define '_source_payload w6T.xzdio'"
Brad Bishop316dfdd2018-06-25 12:45:53 -0400680 cmd = cmd + " --define 'clamp_mtime_to_source_date_epoch 1'"
681 cmd = cmd + " --define '_buildhost reproducible'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500682 if perfiledeps:
683 cmd = cmd + " --define '__find_requires " + outdepends + "'"
684 cmd = cmd + " --define '__find_provides " + outprovides + "'"
685 else:
686 cmd = cmd + " --define '__find_requires %{nil}'"
687 cmd = cmd + " --define '__find_provides %{nil}'"
688 cmd = cmd + " --define '_unpackaged_files_terminate_build 0'"
689 cmd = cmd + " --define 'debug_package %{nil}'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500690 cmd = cmd + " --define '_tmppath " + workdir + "'"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500691 if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
692 cmd = cmd + " --define '_sourcedir " + d.getVar('ARCHIVER_OUTDIR') + "'"
693 cmdsrpm = cmd + " --define '_srcrpmdir " + d.getVar('ARCHIVER_OUTDIR') + "'"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500694 cmdsrpm = cmdsrpm + " -bs " + outspecfile
695 # Build the .src.rpm
696 d.setVar('SBUILDSPEC', cmdsrpm + "\n")
697 d.setVarFlag('SBUILDSPEC', 'func', '1')
698 bb.build.exec_func('SBUILDSPEC', d)
699 cmd = cmd + " -bb " + outspecfile
700
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500701 # rpm 4 creates various empty directories in _topdir, let's clean them up
702 cleanupcmd = "rm -rf %s/BUILDROOT %s/SOURCES %s/SPECS %s/SRPMS" % (workdir, workdir, workdir, workdir)
703
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500704 # Build the rpm package!
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500705 d.setVar('BUILDSPEC', cmd + "\n" + cleanupcmd + "\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500706 d.setVarFlag('BUILDSPEC', 'func', '1')
707 bb.build.exec_func('BUILDSPEC', d)
708
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500709 if d.getVar('RPM_SIGN_PACKAGES') == '1':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500710 bb.build.exec_func("sign_rpm", d)
711}
712
713python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500714 if d.getVar('PACKAGES') != '':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500715 deps = ' rpm-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot'
716 d.appendVarFlag('do_package_write_rpm', 'depends', deps)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500717 d.setVarFlag('do_package_write_rpm', 'fakeroot', '1')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500718}
719
720SSTATETASKS += "do_package_write_rpm"
721do_package_write_rpm[sstate-inputdirs] = "${PKGWRITEDIRRPM}"
722do_package_write_rpm[sstate-outputdirs] = "${DEPLOY_DIR_RPM}"
723# Take a shared lock, we can write multiple packages at the same time...
724# but we need to stop the rootfs/solver from running while we do...
725do_package_write_rpm[sstate-lockfile-shared] += "${DEPLOY_DIR_RPM}/rpm.lock"
726
727python do_package_write_rpm_setscene () {
728 sstate_setscene(d)
729}
730addtask do_package_write_rpm_setscene
731
732python do_package_write_rpm () {
733 bb.build.exec_func("read_subpackage_metadata", d)
734 bb.build.exec_func("do_package_rpm", d)
735}
736
737do_package_write_rpm[dirs] = "${PKGWRITEDIRRPM}"
738do_package_write_rpm[cleandirs] = "${PKGWRITEDIRRPM}"
739do_package_write_rpm[umask] = "022"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500740do_package_write_rpm[depends] += "${@oe.utils.build_depends_string(d.getVar('PACKAGE_WRITE_DEPS'), 'do_populate_sysroot')}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500741addtask package_write_rpm after do_packagedata do_package
742
743PACKAGEINDEXDEPS += "rpm-native:do_populate_sysroot"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500744PACKAGEINDEXDEPS += "createrepo-c-native:do_populate_sysroot"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500745
746do_build[recrdeptask] += "do_package_write_rpm"