inherit package require conf/meta-translator.conf IMAGE_PKGTYPE ?= "rpm" RPM="rpm" RPMBUILD="rpmbuild" PKGWRITEDIRRPM = "${WORKDIR}/deploy-rpms" # Maintaining the perfile dependencies has singificant overhead when writing the # packages. When set, this value merges them for efficiency. MERGEPERFILEDEPS = "1" def license_to_tizen(d,license): '''Translates license string as set in .bb to SPDX with "and" and "or" as logic operators.''' import re # Split at logic operators, keeping them in the result without any surrounding spaces. components = re.split('\s*([()&|])\s*', license) result = [] for component in components: component = canonical_license(d, component) component = component.replace('|', 'or').replace('&', 'and') result.append(component) result = ' '.join(result) # Remove spaces after resp. before brackets to make the final result a bit nicer. result = result.replace('( ', '(').replace(' )', ')') return result # Construct per file dependencies file def write_srpm_perfiledata(srcname, d): workdir = d.getVar('WORKDIR', True) packages = d.getVar('PACKAGES', True) pkgd = d.getVar('PKGD', True) def dump_filerdeps(varname, outfile, d): outfile.write("#!/usr/bin/env python\n\n") outfile.write("# Dependency table\n") outfile.write('deps = {\n') for pkg in packages.split(): dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg dependsflist = (d.getVar(dependsflist_key, True) or "") for dfile in dependsflist.split(): key = "FILE" + varname + "_" + dfile + "_" + pkg depends_dict = bb.utils.explode_dep_versions(d.getVar(key, True) or "") file = dfile.replace("@underscore@", "_") file = file.replace("@closebrace@", "]") file = file.replace("@openbrace@", "[") file = file.replace("@tab@", "\t") file = file.replace("@space@", " ") file = file.replace("@at@", "@") outfile.write('"' + pkgd + file + '" : "') for dep in depends_dict: ver = depends_dict[dep] if dep and ver: ver = ver.replace("(","") ver = ver.replace(")","") outfile.write(dep + " " + ver + " ") else: outfile.write(dep + " ") outfile.write('",\n') outfile.write('}\n\n') outfile.write("import sys\n") outfile.write("while 1:\n") outfile.write("\tline = sys.stdin.readline().strip()\n") outfile.write("\tif not line:\n") outfile.write("\t\tsys.exit(0)\n") outfile.write("\tif line in deps:\n") outfile.write("\t\tprint(deps[line] + '\\n')\n") # OE-core dependencies a.k.a. RPM requires outdepends = workdir + "/" + srcname + ".requires" try: dependsfile = open(outdepends, 'w') except OSError: raise bb.build.FuncFailed("unable to open spec file for writing.") dump_filerdeps('RDEPENDS', dependsfile, d) dependsfile.close() os.chmod(outdepends, 0755) # OE-core / RPM Provides outprovides = workdir + "/" + srcname + ".provides" try: providesfile = open(outprovides, 'w') except OSError: raise bb.build.FuncFailed("unable to open spec file for writing.") dump_filerdeps('RPROVIDES', providesfile, d) providesfile.close() os.chmod(outprovides, 0755) return (outdepends, outprovides) python srpm_write_specfile () { import errno import oe.packagedata import StringIO import os.path import re import shutil import srpm_utils dynamic_file_lists = d.getVar("SRPM_DYNAMIC_FILE_LISTS", True) def compile_regex_replace(var): return [ (re.compile('^%s$' % l), r) for l,r in [ x.split('=') for x in (d.getVar(var, True) or "").split() ] ] def apply_regex_replace(replace, value): for pattern, repl in replace: value = pattern.sub(repl, value) return value # SRPM_RENAME is a space-separated list of = pairs. # Each replacement is applied to package names with re.sub(). The entire # name must match the regex (simplifies setting SRPM_RENAME because # there's no need to embed a $, and prevents accidental matching of sub-strings). package_rename = compile_regex_replace("SRPM_RENAME") def map_pkgname(name): return apply_regex_replace(package_rename, name) # remove shebang line def de_shebang(line): if not line: return line if line.startswith("#!/"): lines = line.split("\n") return "\n".join(lines[1:]) return line # append information for logs and patches to %prep def add_prep(d,spec_files_bottom, has_sources, patches): if bb.data.inherits_class('archiver', d): spec_files_bottom.append('%prep') if has_sources: tempd = bb.data.createCopy(d) tempd.setVar("PN", "%{name}") tempd.setVar("PV", "%{version}") build_dir = os.path.basename(tempd.getVar('S', True)) spec_files_bottom.append('%%setup -q -n %s' % build_dir) for number, (entry, depth) in enumerate(patches): spec_files_bottom.append('%%patch%d -p%d' % (number, depth)) spec_files_bottom.append('') def factory_print_block(d, buffer, rpm_name, bb_name): ''' Output a block of parsed bitbake code ''' # TODO remove ld = d s = StringIO.StringIO() should_call = False postfuncs = ld.getVarFlag(bb_name, 'postfuncs') prefuncs = ld.getVarFlag(bb_name, 'prefuncs') # Post/prefuncs temporarily disabled, break do_configure ''' '''for func in (prefuncs or '').split(): if not ld.getVarFlag(func, 'python'): bb.data.emit_func(func, s, ld) else: bb.warn("Python prefunc encountered, skipping %s" % func) s.write("# Python prefunc encountered, skipping %s\n" % func)''' if not ld.getVarFlag(bb_name, 'python'): try: bb.data.emit_func(bb_name, s, ld) should_call = True except: bb.warn("%s:%s function failed to emit, skipping" % (d.getVar("PN", True), bb_name)) s.write("%s function failed to emit, skipping\n" % bb_name) else: bb.warn("Python function encountered, skipping %s:%s" % (d.getVar("PN", True), bb_name)) s.write("# Python function encountered, skipping %s\n" % bb_name) '''for func in (postfuncs or '').split(): if not ld.getVarFlag(func, 'python'): bb.data.emit_func(func, s, ld) else: bb.warn("Python postfunc encountered, skipping %s" % func) s.write("# Python postfunc encountered, skipping %s\n" % func)''' buffer.append(s.getvalue()) s.close() if should_call: buffer.append("# Now %s\n%s\n" % (rpm_name, bb_name)) def patch_url_is_patch(url, fetch): local = fetch.localpath(url) base, ext = os.path.splitext(os.path.basename(local)) urldata = fetch.ud[url] if "apply" in urldata.parm: apply = oe.types.boolean(urldata.parm["apply"]) if not apply: return False elif ext not in (".diff", ".patch"): return False if "striplevel" in urldata.parm: striplevel = oe.types.integer(urldata.parm["striplevel"]) else: striplevel = 1 # Must return tuple with single entry, because that will # always evaluate to True regardles off the integer value. return (striplevel,) layers = {} def find_layer_name(path): if not layers: for layername in d.getVar("BBFILE_COLLECTIONS", True).split(): pattern = d.getVar("BBFILE_PATTERN_" + layername, True) if pattern: layers[re.compile(pattern)] = layername for regex, name in layers.iteritems(): if regex.match(path): # TODO: second level matching as in bitbake-layers to # handle eg meta-intel's nested layers. return name # append the name of tarball to key word 'SOURCE' in xxx.spec. def tail_source(d, od): sources = [] patches = [] if bb.data.inherits_class('archiver', d): workdir = od.getVar('WORKDIR', True) ar_outdir = od.getVar('ARCHIVER_OUTDIR', True) drop_layers = (d.getVar('SRPM_SKIP_PATCH_LAYERS', True) or "").split() if not os.path.exists(ar_outdir): return sources, patches # TODO: integrate tighter with archiver so we don't need to # replicate logic fetch = bb.fetch2.Fetch([], d) for url in fetch.urls: is_patch = patch_url_is_patch(url, fetch) local_path = fetch.localpath(url) base_path = os.path.basename(local_path) if os.path.isdir(local_path): base_path += ".tar.gz" # Fix the permissions as rpmbuild wants everything owned by root. #os.chown(os.path.join(ar_outdir, base_path), 0, 0) if is_patch: if not find_layer_name(local_path) in drop_layers: patches.append((base_path, is_patch[0])) else: # If the URL is http, use the URL instead of basename in the # Source tag if url.startswith("http://") or url.startswith("https://") or url.startswith("ftp://"): # Strip out the params so that the bitbake-specific # parameters don't confuse RPM. import urlparse t = list(urlparse.urlparse(url)) t[3] = '' sources.append(urlparse.urlunparse(t)) else: sources.append(base_path) return sources, patches # We need a simple way to remove the MLPREFIX from the package name, # and dependency information... def strip_multilib(name, d): multilibs = d.getVar('MULTILIBS', True) or "" for ext in multilibs.split(): eext = ext.split(':') if len(eext) > 1 and eext[0] == 'multilib' and name and name.find(eext[1] + '-') >= 0: name = "".join(name.split(eext[1] + '-')) return name def strip_multilib_deps(deps, d): depends = bb.utils.explode_dep_versions2(deps or "") newdeps = {} for dep in depends: newdeps[strip_multilib(dep, d)] = depends[dep] return bb.utils.join_deps(newdeps) # ml = d.getVar("MLPREFIX", True) # if ml and name and len(ml) != 0 and name.find(ml) == 0: # return ml.join(name.split(ml, 1)[1:]) # return name # SRPM_REWRITE_RUNTIME_DEPS: same format as SRPM_RENAME, regex # applied to each runtime dependency declarations (RDEPENDS, RPROVIDES, etc.), # including any version information in the format as used in .spec # (for example, "automake (= 1.14.1-r0)"). rewrite_rdeps = compile_regex_replace("SRPM_REWRITE_RUNTIME_DEPS") # In RPM, dependencies are of the format: pkg <>= Epoch:Version-Release # This format is similar to OE, however there are restrictions on the # characters that can be in a field. In the Version field, "-" # characters are not allowed. "-" is allowed in the Release field. # # We translate the "-" in the version to a "+", by loading the PKGV # from the dependent recipe, replacing the - with a +, and then using # that value to do a replace inside of this recipe's dependencies. # This preserves the "-" separator between the version and release, as # well as any "-" characters inside of the release field. # # All of this has to happen BEFORE the mapping_rename_hook as # after renaming we cannot look up the dependencies in the packagedata # store. def translate_vers(varname, d): depends = d.getVar(varname, True) if depends: depends_dict = bb.utils.explode_dep_versions2(depends) newdeps_dict = {} for dep in depends_dict: verlist = [] for ver in depends_dict[dep]: if '-' in ver: subd = oe.packagedata.read_subpkgdata_dict(dep, d) if 'PKGV' in subd: pv = subd['PV'] pkgv = subd['PKGV'] reppv = pkgv.replace('-', '+') ver = ver.replace(pv, reppv).replace(pkgv, reppv) if 'PKGR' in subd: # Make sure PKGR rather than PR in ver pr = '-' + subd['PR'] pkgr = '-' + subd['PKGR'] if pkgr not in ver: ver = ver.replace(pr, pkgr) verlist.append(ver) else: verlist.append(ver) newdeps_dict[dep] = verlist depends = [] def append_dep(dep): dep = apply_regex_replace(rewrite_rdeps, dep) if dep: depends.append(dep) for dep in newdeps_dict: if newdeps_dict[dep]: if isinstance(newdeps_dict[dep], list): for v in newdeps_dict[dep]: append_dep(dep + " (" + v + ")") else: append_dep(dep + " (" + newdeps_dict[dep] + ")") else: append_dep(dep) depends = sorted(set(depends)) depends = ", ".join(depends) d.setVar(varname, depends.strip()) # Translate a list of dependencies+versions from Bitbake notation to # RPM-notation, handling syntax, multilib, epoch and spec idioms. # This needs to happen AFTER the mapping_rename_hook def prepare_deps(depends, d): if depends: deps = [] depends_dict = bb.utils.explode_dep_versions2(depends) for dep in depends_dict: for ver in depends_dict[dep]: ver = ver.replace('(', '') ver = ver.replace(')', '') # if its a package in this spec, use %{version}%{release} n = strip_multilib(d.getVar('PN', True), d) v = localdata.getVar('PKG_%s' % dep, True) if dep == n or v is not None: deps.append("%s = %s%s" % (map_pkgname(dep), "%{epoch}:" if srcepoch and srcepoch.strip() != "" else "", "%{version}-%{release}")) else: deps.append("%s %s" % (dep, ver)) if not len(depends_dict[dep]): deps.append("%s" % (map_pkgname(dep))) # Sort and de-duplicate. Duplicates may have been the result of # SRPM_REWRITE_DEPENDS and/or appending the "python" dependency # for SRPM_DYNAMIC_FILE_LISTS. return sorted(set(deps)) else: return [] def print_deps(variable, tag, array, d): deps = prepare_deps (variable, d) array.extend(map(lambda d: justify("%s: %s" % (tag, d)), deps)) def walk_files(walkpath, target, conffiles): # We can race against the ipk/deb backends which create CONTROL or DEBIAN directories # when packaging. We just ignore these files which are created in # packages-split/ and not package/ # We have the odd situation where the CONTROL/DEBIAN directory can be removed in the middle of # of the walk, the isdir() test would then fail and the walk code would assume its a file # hence we check for the names in files too. for rootpath, dirs, files in os.walk(walkpath): path = rootpath.replace(walkpath, "") if path.endswith("DEBIAN") or path.endswith("CONTROL"): continue for dir in dirs: if dir == "CONTROL" or dir == "DEBIAN": continue ## --All packages own the directories their files are in...-- # Need filesystem packages #target.append('%dir "' + path + '/' + dir + '"') for file in files: if file == "CONTROL" or file == "DEBIAN": continue if conffiles.count(path + '/' + file): target.append('%config "' + path + '/' + file + '"') else: target.append('"' + path + '/' + file + '"') def justify(line): split = line.split(":", 1) key = split[0].strip() value = split[1].strip() # Alter to set how much to justify (matches common rpm specs) LINE_WIDTH=17 length = LINE_WIDTH - len(key) ret = "%s: %s%s" % (key,(' '*length),value) return ret # Prevent the prerm/postrm scripts from being run during an upgrade def wrap_uninstall(scriptvar): scr = scriptvar.strip() if scr.startswith("#!"): pos = scr.find("\n") + 1 else: pos = 0 scr = scr[:pos] + 'if [ "$1" = "0" ] ; then\n' + scr[pos:] + '\nfi' return scr def get_perfile(varname, pkg, d): deps = [] dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg dependsflist = (d.getVar(dependsflist_key, True) or "") for dfile in dependsflist.split(): key = "FILE" + varname + "_" + dfile + "_" + pkg depends = d.getVar(key, True) if depends: deps.append(depends) return " ".join(deps) def append_description(spec_preamble, text): """ Add the description to the spec file. """ import textwrap dedent_text = textwrap.dedent(text).strip() # Bitbake saves "\n" as "\\n" if '\\n' in dedent_text: for t in dedent_text.split('\\n'): spec_preamble.append(t.strip()) else: spec_preamble.append('%s' % textwrap.fill(dedent_text, width=75)) def clean_release(release): """ If the release is a standard OE-style 'r1.2', then strip the leading 'r'. """ import re m = re.match(r'r([0-9.]+)', release) if m: return m.group(1) else: return release NATIVE_SUFFIX = "-native" def rewrite_deps(depends, d): nativepn = d.getVar("PN", True) + NATIVE_SUFFIX s = d.getVar("SRPM_REWRITE_DEPENDS", True) if s: mapping = dict([x.split('=') for x in s.split()]) else: mapping = {} rewrote = [] for dep in depends.split(): if dep == nativepn: continue mapped = mapping.get(dep, None) if mapped is None: if dep.endswith(NATIVE_SUFFIX): mapped = dep[0:-len(NATIVE_SUFFIX)] else: mapped = dep + '-dev' rewrote.extend(mapped.split(',')) return " ".join(rewrote) def parse_packageconfig(d): """ Parse PACKAGECONFIG and return fragments for .spec, whilst removing values from DEPENDS/RDEPENDS/EXTRA_OECONF that needs to be removed. """ bconds = [] depends = [] rdepends = [] configure = [] pkgconfigflags = d.getVarFlags("PACKAGECONFIG") if not pkgconfigflags: return None pn = d.getVar("PN", True) orig_oeconf = d.getVar("EXTRA_OECONF", True) or "" orig_depends = (d.getVar("DEPENDS", True) or "").split() orig_rdepends = (d.getVar("RDEPENDS_" + pn, True) or "").split() pkgconfig = (d.getVar('PACKAGECONFIG', True) or "").split() for flag, flagval in sorted(pkgconfigflags.items()): if flag == "defaultval" or flag == "doc": continue items = flagval.split(",") # For convenience, pad out items so it's always got the expected four values in items += [""] * (4-len(items)) (flag_enable, flag_disable, flag_depends, flag_rdepends) = map(d.expand, items) if flag in pkgconfig: bconds.append("%bcond_without " + flag) else: bconds.append("%bcond_with " + flag) if flag_depends: depends.append("%%if %%{with %s}" % flag) for dep in prepare_deps(rewrite_deps(flag_depends, d), d): depends.append(justify("BuildRequires: " + dep)) try: orig_depends.remove(dep) except: pass depends.append("%endif") if flag_rdepends: rdepends.append("%%if %%{with %s}" % flag) for dep in prepare_deps(flag_rdepends, d): rdepends.append(justify("Requires: " + dep)) try: orig_rdepends.remove(dep) except: pass rdepends.append("%endif") orig_oeconf = orig_oeconf.replace(flag_disable, "") if flag_enable: configure.append("%%{?with_%s: %s}" % (flag, flag_enable)) orig_oeconf += " %%{?with_%s:%s}" % (flag, flag_enable) if flag_disable: configure.append("%%{!?with_%s: %s}" % (flag, flag_disable)) orig_oeconf += " %%{?without_%s:%s}" % (flag, flag_disable) d.setVar("EXTRA_OECONF", orig_oeconf) d.setVar("DEPENDS", " ".join(orig_depends)) d.setVar("RDEPENDS_" + pn, " ".join(orig_rdepends)) return (bconds, depends, rdepends, configure) # od is Original Data # d has been processed for RPM-land od = d d = srpm_utils.clean_data(d) packages = d.getVar('PACKAGES', True) if not packages or packages == '': bb.debug(1, "No packages; nothing to do") return pkgdest = od.getVar('PKGDEST', True) if not pkgdest: bb.fatal("No PKGDEST") outspecfile = od.getVar('OUTSPECFILE', True) if not outspecfile: bb.fatal("No OUTSPECFILE") # Construct the SPEC file... srcname = strip_multilib(d.getVar('PN', True), d) srcsummary = (d.getVar('SUMMARY', True) or d.getVar('DESCRIPTION', True) or ".") srcversion = d.getVar('PKGV', True).replace('-', '+') srcrelease = clean_release(d.getVar('PKGR', True)) srcepoch = (d.getVar('PKGE', True) or "") srclicense = d.getVar('LICENSE', True) srcsection = d.getVar('SECTION', True) srcmaintainer = d.getVar('MAINTAINER', True) srchomepage = d.getVar('HOMEPAGE', True) srcdescription = d.getVar('DESCRIPTION', True) or "." srccustomtagschunk = get_package_additional_metadata("rpm", d) srcdepends = strip_multilib_deps(rewrite_deps(d.getVar('DEPENDS', True), d), d) srcrdepends = [] srcrrecommends = [] srcrsuggests = [] srcrprovides = [] srcrreplaces = [] srcrconflicts = [] srcrobsoletes = [] srcrpreinst = [] srcrpostinst = [] srcrprerm = [] srcrpostrm = [] spec_preamble_top = [] spec_preamble_source = [] spec_preamble_middle = [] spec_preamble_bottom = [] spec_preamble_prep = [] spec_scriptlets_top = [] spec_scriptlets_bottom = [] # Appended after regular %install. spec_install_bottom = [] # %post/%postun section inserted after %install and before %files. spec_post_postun = [] spec_files_top = [] spec_files_bottom = [] perfiledeps = (d.getVar("MERGEPERFILEDEPS", True) or "0") != "1" extra_pkgdata = (d.getVar("SRPM_EXTRA_PKGDATA", True) or "0") == "1" addldconfig = set([map_pkgname(x) for x in (d.getVar("SRPM_IS_LIB", True) or "").split()]) samegroup = (d.getVar("SRPM_SAME_GROUP", True) or "0") == "1" hook = d.getVar("SRPM_LICENSE_HOOK", True) if hook: license_to_spec = globals().get(hook) else: license_to_spec = lambda d, license: license sources, patches = tail_source(d, od) try: (bconds, pkg_depends, pkg_rdepends, configure) = parse_packageconfig(d) except Exception as e: bb.warn(str(e)) bconds = pkg_depends = pkg_rdepends = configure = "" pkgnames = [] for pkg in packages.split(): localdata = bb.data.createCopy(d) root = "%s/%s" % (pkgdest, pkg) localdata.setVar('ROOT', '') localdata.setVar('ROOT_%s' % pkg, root) pkgname = localdata.getVar('PKG_%s' % pkg, True) if not pkgname: pkgname = pkg localdata.setVar('PKG', pkgname) localdata.prependVar('OVERRIDES', pkg + ":") bb.data.update_data(localdata) conffiles = (localdata.getVar('CONFFILES', True) or "").split() splitname = strip_multilib(pkgname, d) splitsummary = (d.getVar("SUMMARY_" + pkg, True) or d.getVar("DESCRIPTION_" + pkg, True)) or srcsummary splitversion = (localdata.getVar('PKGV', True) or "").replace('-', '+') splitrelease = clean_release((localdata.getVar('PKGR', True) or "")) splitepoch = (localdata.getVar('PKGE', True) or "") splitlicense = (localdata.getVar('LICENSE', True) or "") splitsection = (localdata.getVar('SECTION', True) or "") splitdescription = (d.getVar('DESCRIPTION_' + pkg, True) or srcdescription) splitcustomtagschunk = get_package_additional_metadata("rpm", localdata) translate_vers('RDEPENDS', localdata) translate_vers('RRECOMMENDS', localdata) translate_vers('RSUGGESTS', localdata) translate_vers('RPROVIDES', localdata) translate_vers('RREPLACES', localdata) translate_vers('RCONFLICTS', localdata) # Map the dependencies into their final form mapping_rename_hook(localdata) splitrdepends = strip_multilib_deps(localdata.getVar('RDEPENDS', True), d) splitrrecommends = strip_multilib_deps(localdata.getVar('RRECOMMENDS', True), d) splitrsuggests = strip_multilib_deps(localdata.getVar('RSUGGESTS', True), d) splitrprovides = strip_multilib_deps(localdata.getVar('RPROVIDES', True), d) splitrreplaces = strip_multilib_deps(localdata.getVar('RREPLACES', True), d) splitrconflicts = strip_multilib_deps(localdata.getVar('RCONFLICTS', True), d) splitrobsoletes = [] splitrpreinst = de_shebang(localdata.getVar('pkg_preinst', True)) splitrpostinst = de_shebang(localdata.getVar('pkg_postinst', True)) splitrprerm = de_shebang(localdata.getVar('pkg_prerm', True)) splitrpostrm = de_shebang(localdata.getVar('pkg_postrm', True)) if not perfiledeps: # Add in summary of per file dependencies splitrdepends = splitrdepends + " " + get_perfile('RDEPENDS', pkg, d) splitrprovides = splitrprovides + " " + get_perfile('RPROVIDES', pkg, d) # Gather special src/first package data if srcname == splitname: srcrdepends = splitrdepends srcrrecommends = splitrrecommends srcrsuggests = splitrsuggests srcrprovides = splitrprovides srcrreplaces = splitrreplaces srcrconflicts = splitrconflicts srcrpreinst = splitrpreinst srcrpostinst = splitrpostinst srcrprerm = splitrprerm srcrpostrm = splitrpostrm splitname = map_pkgname(splitname) if splitname != srcname: # Create an additional %package entry to rename the main package. srcpkgargs = ' -n ' + splitname spec_preamble_middle.append('%%package%s' % srcpkgargs) spec_preamble_middle.append(justify('Summary: %s' % splitsummary)) spec_preamble_middle.append('') spec_preamble_middle.append('%%description%s' % srcpkgargs) append_description(spec_preamble_middle, splitdescription) spec_preamble_middle.append('') else: srcpkgargs = '' if splitname in addldconfig: spec_post_postun.extend( [ '%%post%s -p /sbin/ldconfig' % srcpkgargs, '', '%%postun%s -p /sbin/ldconfig' % srcpkgargs, '' ]) files = localdata.getVar("FILES", True).split(" ") configs = localdata.getVar("CONFIGFILES", True) if configs is not None: configs = configs.split(" ") if dynamic_file_lists: spec_files_top.append('%%files%s -f main-spec.list' % srcpkgargs) spec_install_bottom.append('cat >main-file.list <main-conf.list <sub-%s-file.list <sub-%s-conf.list <= 0: return "".join(name.split(ml)) return name workdir = d.getVar('WORKDIR', True) tmpdir = d.getVar('TMPDIR', True) pkgd = d.getVar('PKGD', True) pkgdest = d.getVar('PKGDEST', True) if not workdir or not pkgd or not tmpdir: bb.error("Variables incorrectly set, unable to package") return packages = d.getVar('PACKAGES', True) if not packages or packages == '': bb.debug(1, "No packages; nothing to do") return # Construct the spec file... # If the spec file already exist, and has not been stored into # pseudo's files.db, it maybe cause rpmbuild src.rpm fail, # so remove it before doing rpmbuild src.rpm. srcname = strip_multilib(d.getVar('PN', True), d) outspecfile = workdir + "/" + srcname + ".spec" if os.path.isfile(outspecfile): os.remove(outspecfile) d.setVar('OUTSPECFILE', outspecfile) bb.build.exec_func('srpm_write_specfile', d) perfiledeps = (d.getVar("MERGEPERFILEDEPS", True) or "0") == "0" if perfiledeps: outdepends, outprovides = write_srpm_perfiledata(srcname, d) # Setup the rpmbuild arguments... rpmbuild = d.getVar('RPMBUILD', True) targetsys = d.getVar('TARGET_SYS', True) targetvendor = d.getVar('TARGET_VENDOR', True) package_arch = (d.getVar('PACKAGE_ARCH', True) or "").replace("-", "_") if package_arch not in "all any noarch".split() and not package_arch.endswith("_nativesdk"): ml_prefix = (d.getVar('MLPREFIX', True) or "").replace("-", "_") d.setVar('PACKAGE_ARCH_EXTEND', ml_prefix + package_arch) else: d.setVar('PACKAGE_ARCH_EXTEND', package_arch) pkgwritedir = d.expand('${PKGWRITEDIRRPM}/${PACKAGE_ARCH_EXTEND}') specdir = d.expand('${PKGWRITEDIRRPM}/specs/') pkgarch = d.expand('${PACKAGE_ARCH_EXTEND}${TARGET_VENDOR}-${TARGET_OS}') magicfile = d.expand('${STAGING_DIR_NATIVE}${datadir_native}/misc/magic.mgc') bb.utils.mkdirhier(pkgwritedir) bb.utils.mkdirhier(specdir) os.chmod(pkgwritedir, 0755) cmd = rpmbuild cmd = cmd + " --nodeps --short-circuit --target " + pkgarch + " --buildroot " + pkgd cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'" cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'" cmd = cmd + " --define '_use_internal_dependency_generator 0'" if perfiledeps: cmd = cmd + " --define '__find_requires " + outdepends + "'" cmd = cmd + " --define '__find_provides " + outprovides + "'" else: cmd = cmd + " --define '__find_requires %{nil}'" cmd = cmd + " --define '__find_provides %{nil}'" cmd = cmd + " --define '_unpackaged_files_terminate_build 0'" cmd = cmd + " --define 'debug_package %{nil}'" cmd = cmd + " --define '_rpmfc_magic_path " + magicfile + "'" cmd = cmd + " --define '_tmppath " + workdir + "'" cmd = cmd + " --define '_sourcedir " + d.getVar('ARCHIVER_OUTDIR', True) + "'" cmd = cmd + " --define '_srcrpmdir " + d.getVar('ARCHIVER_OUTDIR', True) + "'" cmd = cmd + " -bs " + outspecfile # Build the .src.rpm d.setVar('SBUILDSPEC', cmd + "\n") d.setVarFlag('SBUILDSPEC', 'func', '1') bb.build.exec_func('SBUILDSPEC', d) bb.utils.copyfile(outspecfile, specdir + os.path.basename(outspecfile)) } SSTATETASKS += "do_package_write_srcrpm" do_package_write_srcrpm[sstate-inputdirs] = "${PKGWRITEDIRRPM}" do_package_write_srcrpm[sstate-outputdirs] = "${DEPLOY_DIR_RPM}" # Take a shared lock, we can write multiple packages at the same time... # but we need to stop the rootfs/solver from running while we do... do_package_write_srcrpm[sstate-lockfile-shared] += "${DEPLOY_DIR_RPM}/rpm.lock" python do_package_write_srpm_setscene () { sstate_setscene(d) } addtask do_package_write_srpm_setscene python do_package_write_srcrpm () { bb.build.exec_func("read_subpackage_metadata", d) bb.build.exec_func("do_package_srcrpm", d) } do_package_write_srcrpm[dirs] = "${PKGWRITEDIRRPM}" do_package_write_srcrpm[cleandirs] = "${PKGWRITEDIRRPM}" do_package_write_srcrpm[umask] = "022" do_package_write_srcrpm[depends] += "rpm-native:do_populate_sysroot" do_package_write_srcrpm[vardeps] += "${SRPM_EXTRA_HOOKS}" addtask package_write_srcrpm #addtask package_write_srcrpm before do_package_write after do_packagedata do_package PACKAGEINDEXDEPS += "rpm-native:do_populate_sysroot" PACKAGEINDEXDEPS += "createrepo-native:do_populate_sysroot" do_build[recrdeptask] += "do_package_write_srcrpm"