xref: /OK3568_Linux_fs/yocto/poky/meta/classes/package_rpm.bbclass (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyuninherit package
2*4882a593Smuzhiyun
3*4882a593SmuzhiyunIMAGE_PKGTYPE ?= "rpm"
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunRPM="rpm"
6*4882a593SmuzhiyunRPMBUILD="rpmbuild"
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunPKGWRITEDIRRPM = "${WORKDIR}/deploy-rpms"
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun# Maintaining the perfile dependencies has singificant overhead when writing the
11*4882a593Smuzhiyun# packages. When set, this value merges them for efficiency.
12*4882a593SmuzhiyunMERGEPERFILEDEPS = "1"
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun# Filter dependencies based on a provided function.
15*4882a593Smuzhiyundef filter_deps(var, f):
16*4882a593Smuzhiyun    import collections
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun    depends_dict = bb.utils.explode_dep_versions2(var)
19*4882a593Smuzhiyun    newdeps_dict = collections.OrderedDict()
20*4882a593Smuzhiyun    for dep in depends_dict:
21*4882a593Smuzhiyun        if f(dep):
22*4882a593Smuzhiyun            newdeps_dict[dep] = depends_dict[dep]
23*4882a593Smuzhiyun    return bb.utils.join_deps(newdeps_dict, commasep=False)
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun# Filter out absolute paths (typically /bin/sh and /usr/bin/env) and any perl
26*4882a593Smuzhiyun# dependencies for nativesdk packages.
27*4882a593Smuzhiyundef filter_nativesdk_deps(srcname, var):
28*4882a593Smuzhiyun    if var and srcname.startswith("nativesdk-"):
29*4882a593Smuzhiyun        var = filter_deps(var, lambda dep: not dep.startswith('/') and dep != 'perl' and not dep.startswith('perl('))
30*4882a593Smuzhiyun    return var
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun# Construct per file dependencies file
33*4882a593Smuzhiyundef write_rpm_perfiledata(srcname, d):
34*4882a593Smuzhiyun    workdir = d.getVar('WORKDIR')
35*4882a593Smuzhiyun    packages = d.getVar('PACKAGES')
36*4882a593Smuzhiyun    pkgd = d.getVar('PKGD')
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun    def dump_filerdeps(varname, outfile, d):
39*4882a593Smuzhiyun        outfile.write("#!/usr/bin/env python3\n\n")
40*4882a593Smuzhiyun        outfile.write("# Dependency table\n")
41*4882a593Smuzhiyun        outfile.write('deps = {\n')
42*4882a593Smuzhiyun        for pkg in packages.split():
43*4882a593Smuzhiyun            dependsflist_key = 'FILE' + varname + 'FLIST' + ":" + pkg
44*4882a593Smuzhiyun            dependsflist = (d.getVar(dependsflist_key) or "")
45*4882a593Smuzhiyun            for dfile in dependsflist.split():
46*4882a593Smuzhiyun                key = "FILE" + varname + ":" + dfile + ":" + pkg
47*4882a593Smuzhiyun                deps = filter_nativesdk_deps(srcname, d.getVar(key) or "")
48*4882a593Smuzhiyun                depends_dict = bb.utils.explode_dep_versions(deps)
49*4882a593Smuzhiyun                file = dfile.replace("@underscore@", "_")
50*4882a593Smuzhiyun                file = file.replace("@closebrace@", "]")
51*4882a593Smuzhiyun                file = file.replace("@openbrace@", "[")
52*4882a593Smuzhiyun                file = file.replace("@tab@", "\t")
53*4882a593Smuzhiyun                file = file.replace("@space@", " ")
54*4882a593Smuzhiyun                file = file.replace("@at@", "@")
55*4882a593Smuzhiyun                outfile.write('"' + pkgd + file + '" : "')
56*4882a593Smuzhiyun                for dep in depends_dict:
57*4882a593Smuzhiyun                    ver = depends_dict[dep]
58*4882a593Smuzhiyun                    if dep and ver:
59*4882a593Smuzhiyun                        ver = ver.replace("(","")
60*4882a593Smuzhiyun                        ver = ver.replace(")","")
61*4882a593Smuzhiyun                        outfile.write(dep + " " + ver + " ")
62*4882a593Smuzhiyun                    else:
63*4882a593Smuzhiyun                        outfile.write(dep + " ")
64*4882a593Smuzhiyun                outfile.write('",\n')
65*4882a593Smuzhiyun        outfile.write('}\n\n')
66*4882a593Smuzhiyun        outfile.write("import sys\n")
67*4882a593Smuzhiyun        outfile.write("while 1:\n")
68*4882a593Smuzhiyun        outfile.write("\tline = sys.stdin.readline().strip()\n")
69*4882a593Smuzhiyun        outfile.write("\tif not line:\n")
70*4882a593Smuzhiyun        outfile.write("\t\tsys.exit(0)\n")
71*4882a593Smuzhiyun        outfile.write("\tif line in deps:\n")
72*4882a593Smuzhiyun        outfile.write("\t\tprint(deps[line] + '\\n')\n")
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun    # OE-core dependencies a.k.a. RPM requires
75*4882a593Smuzhiyun    outdepends = workdir + "/" + srcname + ".requires"
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun    dependsfile = open(outdepends, 'w')
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun    dump_filerdeps('RDEPENDS', dependsfile, d)
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun    dependsfile.close()
82*4882a593Smuzhiyun    os.chmod(outdepends, 0o755)
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun    # OE-core / RPM Provides
85*4882a593Smuzhiyun    outprovides = workdir + "/" + srcname + ".provides"
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun    providesfile = open(outprovides, 'w')
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun    dump_filerdeps('RPROVIDES', providesfile, d)
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun    providesfile.close()
92*4882a593Smuzhiyun    os.chmod(outprovides, 0o755)
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun    return (outdepends, outprovides)
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun
97*4882a593Smuzhiyunpython write_specfile () {
98*4882a593Smuzhiyun    import oe.packagedata
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun    # append information for logs and patches to %prep
101*4882a593Smuzhiyun    def add_prep(d,spec_files_bottom):
102*4882a593Smuzhiyun        if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
103*4882a593Smuzhiyun            spec_files_bottom.append('%%prep -n %s' % d.getVar('PN') )
104*4882a593Smuzhiyun            spec_files_bottom.append('%s' % "echo \"include logs and patches, Please check them in SOURCES\"")
105*4882a593Smuzhiyun            spec_files_bottom.append('')
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun    # append the name of tarball to key word 'SOURCE' in xxx.spec.
108*4882a593Smuzhiyun    def tail_source(d):
109*4882a593Smuzhiyun        if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
110*4882a593Smuzhiyun            ar_outdir = d.getVar('ARCHIVER_OUTDIR')
111*4882a593Smuzhiyun            if not os.path.exists(ar_outdir):
112*4882a593Smuzhiyun                return
113*4882a593Smuzhiyun            source_list = os.listdir(ar_outdir)
114*4882a593Smuzhiyun            source_number = 0
115*4882a593Smuzhiyun            for source in source_list:
116*4882a593Smuzhiyun                # do_deploy_archives may have already run (from sstate) meaning a .src.rpm may already
117*4882a593Smuzhiyun                # exist in ARCHIVER_OUTDIR so skip if present.
118*4882a593Smuzhiyun                if source.endswith(".src.rpm"):
119*4882a593Smuzhiyun                    continue
120*4882a593Smuzhiyun                # The rpmbuild doesn't need the root permission, but it needs
121*4882a593Smuzhiyun                # to know the file's user and group name, the only user and
122*4882a593Smuzhiyun                # group in fakeroot is "root" when working in fakeroot.
123*4882a593Smuzhiyun                f = os.path.join(ar_outdir, source)
124*4882a593Smuzhiyun                os.chown(f, 0, 0)
125*4882a593Smuzhiyun                spec_preamble_top.append('Source%s: %s' % (source_number, source))
126*4882a593Smuzhiyun                source_number += 1
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun    # In RPM, dependencies are of the format: pkg <>= Epoch:Version-Release
129*4882a593Smuzhiyun    # This format is similar to OE, however there are restrictions on the
130*4882a593Smuzhiyun    # characters that can be in a field.  In the Version field, "-"
131*4882a593Smuzhiyun    # characters are not allowed.  "-" is allowed in the Release field.
132*4882a593Smuzhiyun    #
133*4882a593Smuzhiyun    # We translate the "-" in the version to a "+", by loading the PKGV
134*4882a593Smuzhiyun    # from the dependent recipe, replacing the - with a +, and then using
135*4882a593Smuzhiyun    # that value to do a replace inside of this recipe's dependencies.
136*4882a593Smuzhiyun    # This preserves the "-" separator between the version and release, as
137*4882a593Smuzhiyun    # well as any "-" characters inside of the release field.
138*4882a593Smuzhiyun    #
139*4882a593Smuzhiyun    # All of this has to happen BEFORE the mapping_rename_hook as
140*4882a593Smuzhiyun    # after renaming we cannot look up the dependencies in the packagedata
141*4882a593Smuzhiyun    # store.
142*4882a593Smuzhiyun    def translate_vers(varname, d):
143*4882a593Smuzhiyun        depends = d.getVar(varname)
144*4882a593Smuzhiyun        if depends:
145*4882a593Smuzhiyun            depends_dict = bb.utils.explode_dep_versions2(depends)
146*4882a593Smuzhiyun            newdeps_dict = {}
147*4882a593Smuzhiyun            for dep in depends_dict:
148*4882a593Smuzhiyun                verlist = []
149*4882a593Smuzhiyun                for ver in depends_dict[dep]:
150*4882a593Smuzhiyun                    if '-' in ver:
151*4882a593Smuzhiyun                        subd = oe.packagedata.read_subpkgdata_dict(dep, d)
152*4882a593Smuzhiyun                        if 'PKGV' in subd:
153*4882a593Smuzhiyun                            pv = subd['PV']
154*4882a593Smuzhiyun                            pkgv = subd['PKGV']
155*4882a593Smuzhiyun                            reppv = pkgv.replace('-', '+')
156*4882a593Smuzhiyun                            ver = ver.replace(pv, reppv).replace(pkgv, reppv)
157*4882a593Smuzhiyun                        if 'PKGR' in subd:
158*4882a593Smuzhiyun                            # Make sure PKGR rather than PR in ver
159*4882a593Smuzhiyun                            pr = '-' + subd['PR']
160*4882a593Smuzhiyun                            pkgr = '-' + subd['PKGR']
161*4882a593Smuzhiyun                            if pkgr not in ver:
162*4882a593Smuzhiyun                                ver = ver.replace(pr, pkgr)
163*4882a593Smuzhiyun                        verlist.append(ver)
164*4882a593Smuzhiyun                    else:
165*4882a593Smuzhiyun                        verlist.append(ver)
166*4882a593Smuzhiyun                newdeps_dict[dep] = verlist
167*4882a593Smuzhiyun            depends = bb.utils.join_deps(newdeps_dict)
168*4882a593Smuzhiyun            d.setVar(varname, depends.strip())
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun    # We need to change the style the dependency from BB to RPM
171*4882a593Smuzhiyun    # This needs to happen AFTER the mapping_rename_hook
172*4882a593Smuzhiyun    def print_deps(variable, tag, array, d):
173*4882a593Smuzhiyun        depends = variable
174*4882a593Smuzhiyun        if depends:
175*4882a593Smuzhiyun            depends_dict = bb.utils.explode_dep_versions2(depends)
176*4882a593Smuzhiyun            for dep in depends_dict:
177*4882a593Smuzhiyun                for ver in depends_dict[dep]:
178*4882a593Smuzhiyun                    ver = ver.replace('(', '')
179*4882a593Smuzhiyun                    ver = ver.replace(')', '')
180*4882a593Smuzhiyun                    array.append("%s: %s %s" % (tag, dep, ver))
181*4882a593Smuzhiyun                if not len(depends_dict[dep]):
182*4882a593Smuzhiyun                    array.append("%s: %s" % (tag, dep))
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun    def walk_files(walkpath, target, conffiles, dirfiles):
185*4882a593Smuzhiyun        # We can race against the ipk/deb backends which create CONTROL or DEBIAN directories
186*4882a593Smuzhiyun        # when packaging. We just ignore these files which are created in
187*4882a593Smuzhiyun        # packages-split/ and not package/
188*4882a593Smuzhiyun        # We have the odd situation where the CONTROL/DEBIAN directory can be removed in the middle of
189*4882a593Smuzhiyun        # of the walk, the isdir() test would then fail and the walk code would assume its a file
190*4882a593Smuzhiyun        # hence we check for the names in files too.
191*4882a593Smuzhiyun        for rootpath, dirs, files in os.walk(walkpath):
192*4882a593Smuzhiyun            path = rootpath.replace(walkpath, "")
193*4882a593Smuzhiyun            if path.endswith("DEBIAN") or path.endswith("CONTROL"):
194*4882a593Smuzhiyun                continue
195*4882a593Smuzhiyun            path = path.replace("%", "%%%%%%%%")
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun            # Treat all symlinks to directories as normal files.
198*4882a593Smuzhiyun            # os.walk() lists them as directories.
199*4882a593Smuzhiyun            def move_to_files(dir):
200*4882a593Smuzhiyun                if os.path.islink(os.path.join(rootpath, dir)):
201*4882a593Smuzhiyun                    files.append(dir)
202*4882a593Smuzhiyun                    return True
203*4882a593Smuzhiyun                else:
204*4882a593Smuzhiyun                    return False
205*4882a593Smuzhiyun            dirs[:] = [dir for dir in dirs if not move_to_files(dir)]
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun            # Directory handling can happen in two ways, either DIRFILES is not set at all
208*4882a593Smuzhiyun            # in which case we fall back to the older behaviour of packages owning all their
209*4882a593Smuzhiyun            # directories
210*4882a593Smuzhiyun            if dirfiles is None:
211*4882a593Smuzhiyun                for dir in dirs:
212*4882a593Smuzhiyun                    if dir == "CONTROL" or dir == "DEBIAN":
213*4882a593Smuzhiyun                        continue
214*4882a593Smuzhiyun                    dir = dir.replace("%", "%%%%%%%%")
215*4882a593Smuzhiyun                    # All packages own the directories their files are in...
216*4882a593Smuzhiyun                    target.append('%dir "' + path + '/' + dir + '"')
217*4882a593Smuzhiyun            else:
218*4882a593Smuzhiyun                # packages own only empty directories or explict directory.
219*4882a593Smuzhiyun                # This will prevent the overlapping of security permission.
220*4882a593Smuzhiyun                if path and not files and not dirs:
221*4882a593Smuzhiyun                    target.append('%dir "' + path + '"')
222*4882a593Smuzhiyun                elif path and path in dirfiles:
223*4882a593Smuzhiyun                    target.append('%dir "' + path + '"')
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun            for file in files:
226*4882a593Smuzhiyun                if file == "CONTROL" or file == "DEBIAN":
227*4882a593Smuzhiyun                    continue
228*4882a593Smuzhiyun                file = file.replace("%", "%%%%%%%%")
229*4882a593Smuzhiyun                if conffiles.count(path + '/' + file):
230*4882a593Smuzhiyun                    target.append('%config "' + path + '/' + file + '"')
231*4882a593Smuzhiyun                else:
232*4882a593Smuzhiyun                    target.append('"' + path + '/' + file + '"')
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun    # Prevent the prerm/postrm scripts from being run during an upgrade
235*4882a593Smuzhiyun    def wrap_uninstall(scriptvar):
236*4882a593Smuzhiyun        scr = scriptvar.strip()
237*4882a593Smuzhiyun        if scr.startswith("#!"):
238*4882a593Smuzhiyun            pos = scr.find("\n") + 1
239*4882a593Smuzhiyun        else:
240*4882a593Smuzhiyun            pos = 0
241*4882a593Smuzhiyun        scr = scr[:pos] + 'if [ "$1" = "0" ] ; then\n' + scr[pos:] + '\nfi'
242*4882a593Smuzhiyun        return scr
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun    def get_perfile(varname, pkg, d):
245*4882a593Smuzhiyun        deps = []
246*4882a593Smuzhiyun        dependsflist_key = 'FILE' + varname + 'FLIST' + ":" + pkg
247*4882a593Smuzhiyun        dependsflist = (d.getVar(dependsflist_key) or "")
248*4882a593Smuzhiyun        for dfile in dependsflist.split():
249*4882a593Smuzhiyun            key = "FILE" + varname + ":" + dfile + ":" + pkg
250*4882a593Smuzhiyun            depends = d.getVar(key)
251*4882a593Smuzhiyun            if depends:
252*4882a593Smuzhiyun                deps.append(depends)
253*4882a593Smuzhiyun        return " ".join(deps)
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun    def append_description(spec_preamble, text):
256*4882a593Smuzhiyun        """
257*4882a593Smuzhiyun        Add the description to the spec file.
258*4882a593Smuzhiyun        """
259*4882a593Smuzhiyun        import textwrap
260*4882a593Smuzhiyun        dedent_text = textwrap.dedent(text).strip()
261*4882a593Smuzhiyun        # Bitbake saves "\n" as "\\n"
262*4882a593Smuzhiyun        if '\\n' in dedent_text:
263*4882a593Smuzhiyun            for t in dedent_text.split('\\n'):
264*4882a593Smuzhiyun                spec_preamble.append(t.strip())
265*4882a593Smuzhiyun        else:
266*4882a593Smuzhiyun            spec_preamble.append('%s' % textwrap.fill(dedent_text, width=75))
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun    packages = d.getVar('PACKAGES')
269*4882a593Smuzhiyun    if not packages or packages == '':
270*4882a593Smuzhiyun        bb.debug(1, "No packages; nothing to do")
271*4882a593Smuzhiyun        return
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun    pkgdest = d.getVar('PKGDEST')
274*4882a593Smuzhiyun    if not pkgdest:
275*4882a593Smuzhiyun        bb.fatal("No PKGDEST")
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun    outspecfile = d.getVar('OUTSPECFILE')
278*4882a593Smuzhiyun    if not outspecfile:
279*4882a593Smuzhiyun        bb.fatal("No OUTSPECFILE")
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun    # Construct the SPEC file...
282*4882a593Smuzhiyun    srcname    = d.getVar('PN')
283*4882a593Smuzhiyun    localdata = bb.data.createCopy(d)
284*4882a593Smuzhiyun    localdata.setVar('OVERRIDES', d.getVar("OVERRIDES", False) + ":" + srcname)
285*4882a593Smuzhiyun    srcsummary = (localdata.getVar('SUMMARY') or localdata.getVar('DESCRIPTION') or ".")
286*4882a593Smuzhiyun    srcversion = localdata.getVar('PKGV').replace('-', '+')
287*4882a593Smuzhiyun    srcrelease = localdata.getVar('PKGR')
288*4882a593Smuzhiyun    srcepoch   = (localdata.getVar('PKGE') or "")
289*4882a593Smuzhiyun    srclicense = localdata.getVar('LICENSE')
290*4882a593Smuzhiyun    srcsection = localdata.getVar('SECTION')
291*4882a593Smuzhiyun    srcmaintainer  = localdata.getVar('MAINTAINER')
292*4882a593Smuzhiyun    srchomepage    = localdata.getVar('HOMEPAGE')
293*4882a593Smuzhiyun    srcdescription = localdata.getVar('DESCRIPTION') or "."
294*4882a593Smuzhiyun    srccustomtagschunk = get_package_additional_metadata("rpm", localdata)
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun    srcdepends     = d.getVar('DEPENDS')
297*4882a593Smuzhiyun    srcrdepends    = ""
298*4882a593Smuzhiyun    srcrrecommends = ""
299*4882a593Smuzhiyun    srcrsuggests   = ""
300*4882a593Smuzhiyun    srcrprovides   = ""
301*4882a593Smuzhiyun    srcrreplaces   = ""
302*4882a593Smuzhiyun    srcrconflicts  = ""
303*4882a593Smuzhiyun    srcrobsoletes  = ""
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun    srcrpreinst  = []
306*4882a593Smuzhiyun    srcrpostinst = []
307*4882a593Smuzhiyun    srcrprerm    = []
308*4882a593Smuzhiyun    srcrpostrm   = []
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun    spec_preamble_top = []
311*4882a593Smuzhiyun    spec_preamble_bottom = []
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun    spec_scriptlets_top = []
314*4882a593Smuzhiyun    spec_scriptlets_bottom = []
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun    spec_files_top = []
317*4882a593Smuzhiyun    spec_files_bottom = []
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun    perfiledeps = (d.getVar("MERGEPERFILEDEPS") or "0") == "0"
320*4882a593Smuzhiyun    extra_pkgdata = (d.getVar("RPM_EXTRA_PKGDATA") or "0") == "1"
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun    for pkg in packages.split():
323*4882a593Smuzhiyun        localdata = bb.data.createCopy(d)
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun        root = "%s/%s" % (pkgdest, pkg)
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun        localdata.setVar('ROOT', '')
328*4882a593Smuzhiyun        localdata.setVar('ROOT_%s' % pkg, root)
329*4882a593Smuzhiyun        pkgname = localdata.getVar('PKG:%s' % pkg)
330*4882a593Smuzhiyun        if not pkgname:
331*4882a593Smuzhiyun            pkgname = pkg
332*4882a593Smuzhiyun        localdata.setVar('PKG', pkgname)
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun        localdata.setVar('OVERRIDES', d.getVar("OVERRIDES", False) + ":" + pkg)
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun        conffiles = get_conffiles(pkg, d)
337*4882a593Smuzhiyun        dirfiles = localdata.getVar('DIRFILES')
338*4882a593Smuzhiyun        if dirfiles is not None:
339*4882a593Smuzhiyun            dirfiles = dirfiles.split()
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun        splitname    = pkgname
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun        splitsummary = (localdata.getVar('SUMMARY') or localdata.getVar('DESCRIPTION') or ".")
344*4882a593Smuzhiyun        splitversion = (localdata.getVar('PKGV') or "").replace('-', '+')
345*4882a593Smuzhiyun        splitrelease = (localdata.getVar('PKGR') or "")
346*4882a593Smuzhiyun        splitepoch   = (localdata.getVar('PKGE') or "")
347*4882a593Smuzhiyun        splitlicense = (localdata.getVar('LICENSE') or "")
348*4882a593Smuzhiyun        splitsection = (localdata.getVar('SECTION') or "")
349*4882a593Smuzhiyun        splitdescription = (localdata.getVar('DESCRIPTION') or ".")
350*4882a593Smuzhiyun        splitcustomtagschunk = get_package_additional_metadata("rpm", localdata)
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun        translate_vers('RDEPENDS', localdata)
353*4882a593Smuzhiyun        translate_vers('RRECOMMENDS', localdata)
354*4882a593Smuzhiyun        translate_vers('RSUGGESTS', localdata)
355*4882a593Smuzhiyun        translate_vers('RPROVIDES', localdata)
356*4882a593Smuzhiyun        translate_vers('RREPLACES', localdata)
357*4882a593Smuzhiyun        translate_vers('RCONFLICTS', localdata)
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun        # Map the dependencies into their final form
360*4882a593Smuzhiyun        mapping_rename_hook(localdata)
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun        splitrdepends    = localdata.getVar('RDEPENDS') or ""
363*4882a593Smuzhiyun        splitrrecommends = localdata.getVar('RRECOMMENDS') or ""
364*4882a593Smuzhiyun        splitrsuggests   = localdata.getVar('RSUGGESTS') or ""
365*4882a593Smuzhiyun        splitrprovides   = localdata.getVar('RPROVIDES') or ""
366*4882a593Smuzhiyun        splitrreplaces   = localdata.getVar('RREPLACES') or ""
367*4882a593Smuzhiyun        splitrconflicts  = localdata.getVar('RCONFLICTS') or ""
368*4882a593Smuzhiyun        splitrobsoletes  = ""
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun        splitrpreinst  = localdata.getVar('pkg_preinst')
371*4882a593Smuzhiyun        splitrpostinst = localdata.getVar('pkg_postinst')
372*4882a593Smuzhiyun        splitrprerm    = localdata.getVar('pkg_prerm')
373*4882a593Smuzhiyun        splitrpostrm   = localdata.getVar('pkg_postrm')
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun        if not perfiledeps:
377*4882a593Smuzhiyun            # Add in summary of per file dependencies
378*4882a593Smuzhiyun            splitrdepends = splitrdepends + " " + get_perfile('RDEPENDS', pkg, d)
379*4882a593Smuzhiyun            splitrprovides = splitrprovides + " " + get_perfile('RPROVIDES', pkg, d)
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun        splitrdepends = filter_nativesdk_deps(srcname, splitrdepends)
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun        # Gather special src/first package data
384*4882a593Smuzhiyun        if srcname == splitname:
385*4882a593Smuzhiyun            archiving = d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and \
386*4882a593Smuzhiyun                        bb.data.inherits_class('archiver', d)
387*4882a593Smuzhiyun            if archiving and srclicense != splitlicense:
388*4882a593Smuzhiyun                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*4882a593Smuzhiyun
390*4882a593Smuzhiyun            srclicense     = splitlicense
391*4882a593Smuzhiyun            srcrdepends    = splitrdepends
392*4882a593Smuzhiyun            srcrrecommends = splitrrecommends
393*4882a593Smuzhiyun            srcrsuggests   = splitrsuggests
394*4882a593Smuzhiyun            srcrprovides   = splitrprovides
395*4882a593Smuzhiyun            srcrreplaces   = splitrreplaces
396*4882a593Smuzhiyun            srcrconflicts  = splitrconflicts
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun            srcrpreinst    = splitrpreinst
399*4882a593Smuzhiyun            srcrpostinst   = splitrpostinst
400*4882a593Smuzhiyun            srcrprerm      = splitrprerm
401*4882a593Smuzhiyun            srcrpostrm     = splitrpostrm
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun            file_list = []
404*4882a593Smuzhiyun            walk_files(root, file_list, conffiles, dirfiles)
405*4882a593Smuzhiyun            if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1":
406*4882a593Smuzhiyun                bb.note("Not creating empty RPM package for %s" % splitname)
407*4882a593Smuzhiyun            else:
408*4882a593Smuzhiyun                spec_files_top.append('%files')
409*4882a593Smuzhiyun                if extra_pkgdata:
410*4882a593Smuzhiyun                    package_rpm_extra_pkgdata(splitname, spec_files_top, localdata)
411*4882a593Smuzhiyun                spec_files_top.append('%defattr(-,-,-,-)')
412*4882a593Smuzhiyun                if file_list:
413*4882a593Smuzhiyun                    bb.note("Creating RPM package for %s" % splitname)
414*4882a593Smuzhiyun                    spec_files_top.extend(file_list)
415*4882a593Smuzhiyun                else:
416*4882a593Smuzhiyun                    bb.note("Creating empty RPM package for %s" % splitname)
417*4882a593Smuzhiyun                spec_files_top.append('')
418*4882a593Smuzhiyun            continue
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun        # Process subpackage data
421*4882a593Smuzhiyun        spec_preamble_bottom.append('%%package -n %s' % splitname)
422*4882a593Smuzhiyun        spec_preamble_bottom.append('Summary: %s' % splitsummary)
423*4882a593Smuzhiyun        if srcversion != splitversion:
424*4882a593Smuzhiyun            spec_preamble_bottom.append('Version: %s' % splitversion)
425*4882a593Smuzhiyun        if srcrelease != splitrelease:
426*4882a593Smuzhiyun            spec_preamble_bottom.append('Release: %s' % splitrelease)
427*4882a593Smuzhiyun        if srcepoch != splitepoch:
428*4882a593Smuzhiyun            spec_preamble_bottom.append('Epoch: %s' % splitepoch)
429*4882a593Smuzhiyun        spec_preamble_bottom.append('License: %s' % splitlicense)
430*4882a593Smuzhiyun        spec_preamble_bottom.append('Group: %s' % splitsection)
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun        if srccustomtagschunk != splitcustomtagschunk:
433*4882a593Smuzhiyun            spec_preamble_bottom.append(splitcustomtagschunk)
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun        # Replaces == Obsoletes && Provides
436*4882a593Smuzhiyun        robsoletes = bb.utils.explode_dep_versions2(splitrobsoletes)
437*4882a593Smuzhiyun        rprovides = bb.utils.explode_dep_versions2(splitrprovides)
438*4882a593Smuzhiyun        rreplaces = bb.utils.explode_dep_versions2(splitrreplaces)
439*4882a593Smuzhiyun        for dep in rreplaces:
440*4882a593Smuzhiyun            if not dep in robsoletes:
441*4882a593Smuzhiyun                robsoletes[dep] = rreplaces[dep]
442*4882a593Smuzhiyun            if not dep in rprovides:
443*4882a593Smuzhiyun                rprovides[dep] = rreplaces[dep]
444*4882a593Smuzhiyun        splitrobsoletes = bb.utils.join_deps(robsoletes, commasep=False)
445*4882a593Smuzhiyun        splitrprovides = bb.utils.join_deps(rprovides, commasep=False)
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun        print_deps(splitrdepends, "Requires", spec_preamble_bottom, d)
448*4882a593Smuzhiyun        if splitrpreinst:
449*4882a593Smuzhiyun            print_deps(splitrdepends, "Requires(pre)", spec_preamble_bottom, d)
450*4882a593Smuzhiyun        if splitrpostinst:
451*4882a593Smuzhiyun            print_deps(splitrdepends, "Requires(post)", spec_preamble_bottom, d)
452*4882a593Smuzhiyun        if splitrprerm:
453*4882a593Smuzhiyun            print_deps(splitrdepends, "Requires(preun)", spec_preamble_bottom, d)
454*4882a593Smuzhiyun        if splitrpostrm:
455*4882a593Smuzhiyun            print_deps(splitrdepends, "Requires(postun)", spec_preamble_bottom, d)
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun        print_deps(splitrrecommends, "Recommends", spec_preamble_bottom, d)
458*4882a593Smuzhiyun        print_deps(splitrsuggests,  "Suggests", spec_preamble_bottom, d)
459*4882a593Smuzhiyun        print_deps(splitrprovides,  "Provides", spec_preamble_bottom, d)
460*4882a593Smuzhiyun        print_deps(splitrobsoletes, "Obsoletes", spec_preamble_bottom, d)
461*4882a593Smuzhiyun        print_deps(splitrconflicts,  "Conflicts", spec_preamble_bottom, d)
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun        spec_preamble_bottom.append('')
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun        spec_preamble_bottom.append('%%description -n %s' % splitname)
466*4882a593Smuzhiyun        append_description(spec_preamble_bottom, splitdescription)
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun        spec_preamble_bottom.append('')
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun        # Now process scriptlets
471*4882a593Smuzhiyun        if splitrpreinst:
472*4882a593Smuzhiyun            spec_scriptlets_bottom.append('%%pre -n %s' % splitname)
473*4882a593Smuzhiyun            spec_scriptlets_bottom.append('# %s - preinst' % splitname)
474*4882a593Smuzhiyun            spec_scriptlets_bottom.append(splitrpreinst)
475*4882a593Smuzhiyun            spec_scriptlets_bottom.append('')
476*4882a593Smuzhiyun        if splitrpostinst:
477*4882a593Smuzhiyun            spec_scriptlets_bottom.append('%%post -n %s' % splitname)
478*4882a593Smuzhiyun            spec_scriptlets_bottom.append('# %s - postinst' % splitname)
479*4882a593Smuzhiyun            spec_scriptlets_bottom.append(splitrpostinst)
480*4882a593Smuzhiyun            spec_scriptlets_bottom.append('')
481*4882a593Smuzhiyun        if splitrprerm:
482*4882a593Smuzhiyun            spec_scriptlets_bottom.append('%%preun -n %s' % splitname)
483*4882a593Smuzhiyun            spec_scriptlets_bottom.append('# %s - prerm' % splitname)
484*4882a593Smuzhiyun            scriptvar = wrap_uninstall(splitrprerm)
485*4882a593Smuzhiyun            spec_scriptlets_bottom.append(scriptvar)
486*4882a593Smuzhiyun            spec_scriptlets_bottom.append('')
487*4882a593Smuzhiyun        if splitrpostrm:
488*4882a593Smuzhiyun            spec_scriptlets_bottom.append('%%postun -n %s' % splitname)
489*4882a593Smuzhiyun            spec_scriptlets_bottom.append('# %s - postrm' % splitname)
490*4882a593Smuzhiyun            scriptvar = wrap_uninstall(splitrpostrm)
491*4882a593Smuzhiyun            spec_scriptlets_bottom.append(scriptvar)
492*4882a593Smuzhiyun            spec_scriptlets_bottom.append('')
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun        # Now process files
495*4882a593Smuzhiyun        file_list = []
496*4882a593Smuzhiyun        walk_files(root, file_list, conffiles, dirfiles)
497*4882a593Smuzhiyun        if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1":
498*4882a593Smuzhiyun            bb.note("Not creating empty RPM package for %s" % splitname)
499*4882a593Smuzhiyun        else:
500*4882a593Smuzhiyun            spec_files_bottom.append('%%files -n %s' % splitname)
501*4882a593Smuzhiyun            if extra_pkgdata:
502*4882a593Smuzhiyun                package_rpm_extra_pkgdata(splitname, spec_files_bottom, localdata)
503*4882a593Smuzhiyun            spec_files_bottom.append('%defattr(-,-,-,-)')
504*4882a593Smuzhiyun            if file_list:
505*4882a593Smuzhiyun                bb.note("Creating RPM package for %s" % splitname)
506*4882a593Smuzhiyun                spec_files_bottom.extend(file_list)
507*4882a593Smuzhiyun            else:
508*4882a593Smuzhiyun                bb.note("Creating empty RPM package for %s" % splitname)
509*4882a593Smuzhiyun            spec_files_bottom.append('')
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun        del localdata
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun    add_prep(d,spec_files_bottom)
514*4882a593Smuzhiyun    spec_preamble_top.append('Summary: %s' % srcsummary)
515*4882a593Smuzhiyun    spec_preamble_top.append('Name: %s' % srcname)
516*4882a593Smuzhiyun    spec_preamble_top.append('Version: %s' % srcversion)
517*4882a593Smuzhiyun    spec_preamble_top.append('Release: %s' % srcrelease)
518*4882a593Smuzhiyun    if srcepoch and srcepoch.strip() != "":
519*4882a593Smuzhiyun        spec_preamble_top.append('Epoch: %s' % srcepoch)
520*4882a593Smuzhiyun    spec_preamble_top.append('License: %s' % srclicense)
521*4882a593Smuzhiyun    spec_preamble_top.append('Group: %s' % srcsection)
522*4882a593Smuzhiyun    spec_preamble_top.append('Packager: %s' % srcmaintainer)
523*4882a593Smuzhiyun    if srchomepage:
524*4882a593Smuzhiyun        spec_preamble_top.append('URL: %s' % srchomepage)
525*4882a593Smuzhiyun    if srccustomtagschunk:
526*4882a593Smuzhiyun        spec_preamble_top.append(srccustomtagschunk)
527*4882a593Smuzhiyun    tail_source(d)
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun    # Replaces == Obsoletes && Provides
530*4882a593Smuzhiyun    robsoletes = bb.utils.explode_dep_versions2(srcrobsoletes)
531*4882a593Smuzhiyun    rprovides = bb.utils.explode_dep_versions2(srcrprovides)
532*4882a593Smuzhiyun    rreplaces = bb.utils.explode_dep_versions2(srcrreplaces)
533*4882a593Smuzhiyun    for dep in rreplaces:
534*4882a593Smuzhiyun        if not dep in robsoletes:
535*4882a593Smuzhiyun            robsoletes[dep] = rreplaces[dep]
536*4882a593Smuzhiyun        if not dep in rprovides:
537*4882a593Smuzhiyun            rprovides[dep] = rreplaces[dep]
538*4882a593Smuzhiyun    srcrobsoletes = bb.utils.join_deps(robsoletes, commasep=False)
539*4882a593Smuzhiyun    srcrprovides = bb.utils.join_deps(rprovides, commasep=False)
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun    print_deps(srcdepends, "BuildRequires", spec_preamble_top, d)
542*4882a593Smuzhiyun    print_deps(srcrdepends, "Requires", spec_preamble_top, d)
543*4882a593Smuzhiyun    if srcrpreinst:
544*4882a593Smuzhiyun        print_deps(srcrdepends, "Requires(pre)", spec_preamble_top, d)
545*4882a593Smuzhiyun    if srcrpostinst:
546*4882a593Smuzhiyun        print_deps(srcrdepends, "Requires(post)", spec_preamble_top, d)
547*4882a593Smuzhiyun    if srcrprerm:
548*4882a593Smuzhiyun        print_deps(srcrdepends, "Requires(preun)", spec_preamble_top, d)
549*4882a593Smuzhiyun    if srcrpostrm:
550*4882a593Smuzhiyun        print_deps(srcrdepends, "Requires(postun)", spec_preamble_top, d)
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun    print_deps(srcrrecommends, "Recommends", spec_preamble_top, d)
553*4882a593Smuzhiyun    print_deps(srcrsuggests, "Suggests", spec_preamble_top, d)
554*4882a593Smuzhiyun    print_deps(srcrprovides, "Provides", spec_preamble_top, d)
555*4882a593Smuzhiyun    print_deps(srcrobsoletes, "Obsoletes", spec_preamble_top, d)
556*4882a593Smuzhiyun    print_deps(srcrconflicts, "Conflicts", spec_preamble_top, d)
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun    spec_preamble_top.append('')
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun    spec_preamble_top.append('%description')
561*4882a593Smuzhiyun    append_description(spec_preamble_top, srcdescription)
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun    spec_preamble_top.append('')
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun    if srcrpreinst:
566*4882a593Smuzhiyun        spec_scriptlets_top.append('%pre')
567*4882a593Smuzhiyun        spec_scriptlets_top.append('# %s - preinst' % srcname)
568*4882a593Smuzhiyun        spec_scriptlets_top.append(srcrpreinst)
569*4882a593Smuzhiyun        spec_scriptlets_top.append('')
570*4882a593Smuzhiyun    if srcrpostinst:
571*4882a593Smuzhiyun        spec_scriptlets_top.append('%post')
572*4882a593Smuzhiyun        spec_scriptlets_top.append('# %s - postinst' % srcname)
573*4882a593Smuzhiyun        spec_scriptlets_top.append(srcrpostinst)
574*4882a593Smuzhiyun        spec_scriptlets_top.append('')
575*4882a593Smuzhiyun    if srcrprerm:
576*4882a593Smuzhiyun        spec_scriptlets_top.append('%preun')
577*4882a593Smuzhiyun        spec_scriptlets_top.append('# %s - prerm' % srcname)
578*4882a593Smuzhiyun        scriptvar = wrap_uninstall(srcrprerm)
579*4882a593Smuzhiyun        spec_scriptlets_top.append(scriptvar)
580*4882a593Smuzhiyun        spec_scriptlets_top.append('')
581*4882a593Smuzhiyun    if srcrpostrm:
582*4882a593Smuzhiyun        spec_scriptlets_top.append('%postun')
583*4882a593Smuzhiyun        spec_scriptlets_top.append('# %s - postrm' % srcname)
584*4882a593Smuzhiyun        scriptvar = wrap_uninstall(srcrpostrm)
585*4882a593Smuzhiyun        spec_scriptlets_top.append(scriptvar)
586*4882a593Smuzhiyun        spec_scriptlets_top.append('')
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun    # Write the SPEC file
589*4882a593Smuzhiyun    specfile = open(outspecfile, 'w')
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun    # RPMSPEC_PREAMBLE is a way to add arbitrary text to the top
592*4882a593Smuzhiyun    # of the generated spec file
593*4882a593Smuzhiyun    external_preamble = d.getVar("RPMSPEC_PREAMBLE")
594*4882a593Smuzhiyun    if external_preamble:
595*4882a593Smuzhiyun        specfile.write(external_preamble + "\n")
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun    for line in spec_preamble_top:
598*4882a593Smuzhiyun        specfile.write(line + "\n")
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun    for line in spec_preamble_bottom:
601*4882a593Smuzhiyun        specfile.write(line + "\n")
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun    for line in spec_scriptlets_top:
604*4882a593Smuzhiyun        specfile.write(line + "\n")
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun    for line in spec_scriptlets_bottom:
607*4882a593Smuzhiyun        specfile.write(line + "\n")
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun    for line in spec_files_top:
610*4882a593Smuzhiyun        specfile.write(line + "\n")
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun    for line in spec_files_bottom:
613*4882a593Smuzhiyun        specfile.write(line + "\n")
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun    specfile.close()
616*4882a593Smuzhiyun}
617*4882a593Smuzhiyun# Otherwise allarch packages may change depending on override configuration
618*4882a593Smuzhiyunwrite_specfile[vardepsexclude] = "OVERRIDES"
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun# Have to list any variables referenced as X_<pkg> that aren't in pkgdata here
621*4882a593SmuzhiyunRPMEXTRAVARS = "PACKAGE_ADD_METADATA_RPM"
622*4882a593Smuzhiyunwrite_specfile[vardeps] += "${@gen_packagevar(d, 'RPMEXTRAVARS')}"
623*4882a593Smuzhiyun
624*4882a593Smuzhiyunpython do_package_rpm () {
625*4882a593Smuzhiyun    workdir = d.getVar('WORKDIR')
626*4882a593Smuzhiyun    tmpdir = d.getVar('TMPDIR')
627*4882a593Smuzhiyun    pkgd = d.getVar('PKGD')
628*4882a593Smuzhiyun    pkgdest = d.getVar('PKGDEST')
629*4882a593Smuzhiyun    if not workdir or not pkgd or not tmpdir:
630*4882a593Smuzhiyun        bb.error("Variables incorrectly set, unable to package")
631*4882a593Smuzhiyun        return
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun    packages = d.getVar('PACKAGES')
634*4882a593Smuzhiyun    if not packages or packages == '':
635*4882a593Smuzhiyun        bb.debug(1, "No packages; nothing to do")
636*4882a593Smuzhiyun        return
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun    # Construct the spec file...
639*4882a593Smuzhiyun    # If the spec file already exist, and has not been stored into
640*4882a593Smuzhiyun    # pseudo's files.db, it maybe cause rpmbuild src.rpm fail,
641*4882a593Smuzhiyun    # so remove it before doing rpmbuild src.rpm.
642*4882a593Smuzhiyun    srcname    = d.getVar('PN')
643*4882a593Smuzhiyun    outspecfile = workdir + "/" + srcname + ".spec"
644*4882a593Smuzhiyun    if os.path.isfile(outspecfile):
645*4882a593Smuzhiyun        os.remove(outspecfile)
646*4882a593Smuzhiyun    d.setVar('OUTSPECFILE', outspecfile)
647*4882a593Smuzhiyun    bb.build.exec_func('write_specfile', d)
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun    perfiledeps = (d.getVar("MERGEPERFILEDEPS") or "0") == "0"
650*4882a593Smuzhiyun    if perfiledeps:
651*4882a593Smuzhiyun        outdepends, outprovides = write_rpm_perfiledata(srcname, d)
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun    # Setup the rpmbuild arguments...
654*4882a593Smuzhiyun    rpmbuild = d.getVar('RPMBUILD')
655*4882a593Smuzhiyun    targetsys = d.getVar('TARGET_SYS')
656*4882a593Smuzhiyun    targetvendor = d.getVar('HOST_VENDOR')
657*4882a593Smuzhiyun
658*4882a593Smuzhiyun    # Too many places in dnf stack assume that arch-independent packages are "noarch".
659*4882a593Smuzhiyun    # Let's not fight against this.
660*4882a593Smuzhiyun    package_arch = (d.getVar('PACKAGE_ARCH') or "").replace("-", "_")
661*4882a593Smuzhiyun    if package_arch == "all":
662*4882a593Smuzhiyun        package_arch = "noarch"
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun    sdkpkgsuffix = (d.getVar('SDKPKGSUFFIX') or "nativesdk").replace("-", "_")
665*4882a593Smuzhiyun    d.setVar('PACKAGE_ARCH_EXTEND', package_arch)
666*4882a593Smuzhiyun    pkgwritedir = d.expand('${PKGWRITEDIRRPM}/${PACKAGE_ARCH_EXTEND}')
667*4882a593Smuzhiyun    d.setVar('RPM_PKGWRITEDIR', pkgwritedir)
668*4882a593Smuzhiyun    bb.debug(1, 'PKGWRITEDIR: %s' % d.getVar('RPM_PKGWRITEDIR'))
669*4882a593Smuzhiyun    pkgarch = d.expand('${PACKAGE_ARCH_EXTEND}${HOST_VENDOR}-linux')
670*4882a593Smuzhiyun    bb.utils.mkdirhier(pkgwritedir)
671*4882a593Smuzhiyun    os.chmod(pkgwritedir, 0o755)
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun    cmd = rpmbuild
674*4882a593Smuzhiyun    cmd = cmd + " --noclean --nodeps --short-circuit --target " + pkgarch + " --buildroot " + pkgd
675*4882a593Smuzhiyun    cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'"
676*4882a593Smuzhiyun    cmd = cmd + " --define '_builddir " + d.getVar('B') + "'"
677*4882a593Smuzhiyun    cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'"
678*4882a593Smuzhiyun    cmd = cmd + " --define '_use_internal_dependency_generator 0'"
679*4882a593Smuzhiyun    cmd = cmd + " --define '_binaries_in_noarch_packages_terminate_build 0'"
680*4882a593Smuzhiyun    cmd = cmd + " --define '_build_id_links none'"
681*4882a593Smuzhiyun    cmd = cmd + " --define '_binary_payload w19T%d.zstdio'" % int(d.getVar("ZSTD_THREADS"))
682*4882a593Smuzhiyun    cmd = cmd + " --define '_source_payload w19T%d.zstdio'" % int(d.getVar("ZSTD_THREADS"))
683*4882a593Smuzhiyun    cmd = cmd + " --define 'clamp_mtime_to_source_date_epoch 1'"
684*4882a593Smuzhiyun    cmd = cmd + " --define 'use_source_date_epoch_as_buildtime 1'"
685*4882a593Smuzhiyun    cmd = cmd + " --define '_buildhost reproducible'"
686*4882a593Smuzhiyun    cmd = cmd + " --define '__font_provides %{nil}'"
687*4882a593Smuzhiyun    if perfiledeps:
688*4882a593Smuzhiyun        cmd = cmd + " --define '__find_requires " + outdepends + "'"
689*4882a593Smuzhiyun        cmd = cmd + " --define '__find_provides " + outprovides + "'"
690*4882a593Smuzhiyun    else:
691*4882a593Smuzhiyun        cmd = cmd + " --define '__find_requires %{nil}'"
692*4882a593Smuzhiyun        cmd = cmd + " --define '__find_provides %{nil}'"
693*4882a593Smuzhiyun    cmd = cmd + " --define '_unpackaged_files_terminate_build 0'"
694*4882a593Smuzhiyun    cmd = cmd + " --define 'debug_package %{nil}'"
695*4882a593Smuzhiyun    cmd = cmd + " --define '_tmppath " + workdir + "'"
696*4882a593Smuzhiyun    if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d):
697*4882a593Smuzhiyun        cmd = cmd + " --define '_sourcedir " + d.getVar('ARCHIVER_OUTDIR') + "'"
698*4882a593Smuzhiyun        cmdsrpm = cmd + " --define '_srcrpmdir " + d.getVar('ARCHIVER_RPMOUTDIR') + "'"
699*4882a593Smuzhiyun        cmdsrpm = cmdsrpm + " -bs " + outspecfile
700*4882a593Smuzhiyun        # Build the .src.rpm
701*4882a593Smuzhiyun        d.setVar('SBUILDSPEC', cmdsrpm + "\n")
702*4882a593Smuzhiyun        d.setVarFlag('SBUILDSPEC', 'func', '1')
703*4882a593Smuzhiyun        bb.build.exec_func('SBUILDSPEC', d)
704*4882a593Smuzhiyun    cmd = cmd + " -bb " + outspecfile
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun    # rpm 4 creates various empty directories in _topdir, let's clean them up
707*4882a593Smuzhiyun    cleanupcmd = "rm -rf %s/BUILDROOT %s/SOURCES %s/SPECS %s/SRPMS" % (workdir, workdir, workdir, workdir)
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun    # Build the rpm package!
710*4882a593Smuzhiyun    d.setVar('BUILDSPEC', cmd + "\n" + cleanupcmd + "\n")
711*4882a593Smuzhiyun    d.setVarFlag('BUILDSPEC', 'func', '1')
712*4882a593Smuzhiyun    bb.build.exec_func('BUILDSPEC', d)
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun    if d.getVar('RPM_SIGN_PACKAGES') == '1':
715*4882a593Smuzhiyun        bb.build.exec_func("sign_rpm", d)
716*4882a593Smuzhiyun}
717*4882a593Smuzhiyun
718*4882a593Smuzhiyunpython () {
719*4882a593Smuzhiyun    if d.getVar('PACKAGES') != '':
720*4882a593Smuzhiyun        deps = ' rpm-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot'
721*4882a593Smuzhiyun        d.appendVarFlag('do_package_write_rpm', 'depends', deps)
722*4882a593Smuzhiyun        d.setVarFlag('do_package_write_rpm', 'fakeroot', '1')
723*4882a593Smuzhiyun}
724*4882a593Smuzhiyun
725*4882a593SmuzhiyunSSTATETASKS += "do_package_write_rpm"
726*4882a593Smuzhiyundo_package_write_rpm[sstate-inputdirs] = "${PKGWRITEDIRRPM}"
727*4882a593Smuzhiyundo_package_write_rpm[sstate-outputdirs] = "${DEPLOY_DIR_RPM}"
728*4882a593Smuzhiyun# Take a shared lock, we can write multiple packages at the same time...
729*4882a593Smuzhiyun# but we need to stop the rootfs/solver from running while we do...
730*4882a593Smuzhiyundo_package_write_rpm[sstate-lockfile-shared] += "${DEPLOY_DIR_RPM}/rpm.lock"
731*4882a593Smuzhiyun
732*4882a593Smuzhiyunpython do_package_write_rpm_setscene () {
733*4882a593Smuzhiyun    sstate_setscene(d)
734*4882a593Smuzhiyun}
735*4882a593Smuzhiyunaddtask do_package_write_rpm_setscene
736*4882a593Smuzhiyun
737*4882a593Smuzhiyunpython do_package_write_rpm () {
738*4882a593Smuzhiyun    bb.build.exec_func("read_subpackage_metadata", d)
739*4882a593Smuzhiyun    bb.build.exec_func("do_package_rpm", d)
740*4882a593Smuzhiyun}
741*4882a593Smuzhiyun
742*4882a593Smuzhiyundo_package_write_rpm[dirs] = "${PKGWRITEDIRRPM}"
743*4882a593Smuzhiyundo_package_write_rpm[cleandirs] = "${PKGWRITEDIRRPM}"
744*4882a593Smuzhiyundo_package_write_rpm[depends] += "${@oe.utils.build_depends_string(d.getVar('PACKAGE_WRITE_DEPS'), 'do_populate_sysroot')}"
745*4882a593Smuzhiyunaddtask package_write_rpm after do_packagedata do_package do_deploy_source_date_epoch before do_build
746*4882a593Smuzhiyundo_build[rdeptask] += "do_package_write_rpm"
747*4882a593Smuzhiyun
748*4882a593SmuzhiyunPACKAGEINDEXDEPS += "rpm-native:do_populate_sysroot"
749*4882a593SmuzhiyunPACKAGEINDEXDEPS += "createrepo-c-native:do_populate_sysroot"
750