From 02e77b6296b6b7c9be74cd036d71334cda6fe505 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti de Araujo Date: Thu, 26 Nov 2009 21:23:18 -0300 Subject: [PATCH 010/118] Adding sourcedsc.bbclass This bbclass is responsible to generate debian like source packages. Generated files: .dsc - debian source package control file .orig.tar.gz - Original source package .diff.gz - patches that we apply .changes - changes file Read only at the moment, you cannot use these sources to rebuild packages _yet_. Signed-off-by: Rodrigo Vivi Signed-off-by: Ricardo Salveti de Araujo --- classes/sourcedsc.bbclass | 449 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 449 insertions(+), 0 deletions(-) create mode 100644 classes/sourcedsc.bbclass diff --git a/classes/sourcedsc.bbclass b/classes/sourcedsc.bbclass new file mode 100644 index 0000000..0588db1 --- /dev/null +++ b/classes/sourcedsc.bbclass @@ -0,0 +1,449 @@ + +## sourcedsc.bbclass: Generates the debian source package. + +## Deploy: +## * .dsc - debian source package control file +## * .orig.tar.gz - Original source package +## * .diff.gz - patches that we apply +## * .changes - changes file + +DEPLOY_DIR_DSC ?= "${DEPLOY_DIR}/dsc" + +def gen_script_files(d, controldir): + import os + import bb + packages = bb.data.getVar('PACKAGES', d, 1) + if packages: + for pkg in packages.split(): + localdata = bb.data.createCopy(d) + pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, 1) + if not pkgname: + pkgname = pkg + bb.data.setVar('PKG', pkgname, localdata) + for script in ["preinst", "postinst", "prerm", "postrm"]: + scriptvar = bb.data.getVar('pkg_%s' % script, localdata, 1) + if not scriptvar: + continue + if os.path.exists(os.path.join(controldir, "%s.%s" % + (pkg, script))): + continue + try: + scriptfile = file(os.path.join(controldir, "%s.%s" % + (pkg, script)), 'w') + except OSError: + raise bb.build.FuncFailed("unable to open %s.%s script file for writing." % (pkg, script)) + scriptfile.write("#!/bin/sh\n") + scriptfile.write(scriptvar) + scriptfile.close() + os.chmod(os.path.join(controldir, + "%s.%s" % (pkg, script)), 0644) + +def gen_install_files(d, controldir): + import os + import bb + + workdir = bb.data.getVar('WORKDIR', d, 1) + if not workdir: + bb.error("WORKDIR not defined, unable to generate install file") + return + + pkgdest = bb.data.getVar('PKGDEST', d, 1) + packages = bb.data.getVar('PACKAGES', d, 1) + if packages: + for pkg in packages.split(): + if os.path.exists(os.path.join(controldir, "%s.install" % pkg)): + continue + installfile = file(os.path.join(controldir, "%s.install" % pkg), + 'w') + installroot = "%s/%s" % (pkgdest, pkg) + for root, dirs, files in os.walk(installroot): + for name in files: + if name.count("DEBIAN") == 0: + installfile.write( + os.path.join("debian", "tmp") + + os.path.join(root.replace(installroot,''), name) + + "\n") + + installfile.close() + +def gen_rules_file(d, controldir): + import os + import bb + try: + rulesfile = file( os.path.join(controldir, 'rules'), 'wb') + except OSError: + raise bb.build.FuncFailed("unable to open rules file for writing.") + + rulesfile.write("#!/bin/sh \n\n") + rulesfile.write("echo; echo\n") + rulesfile.write("echo \"#######################################################\"\n") + rulesfile.write("echo \"# #\"\n") + rulesfile.write("echo \"# WARNING !!! #\"\n") + rulesfile.write("echo \"# #\"\n") + rulesfile.write("echo \"# This is a read only dsc package. #\"\n") + rulesfile.write("echo \"# #\"\n") + rulesfile.write("echo \"# This is a fake rules file, do NOT use #\"\n") + rulesfile.write("echo \"# dpkg-buildpackage to build this package. #\"\n") + rulesfile.write("echo \"# #\"\n") + rulesfile.write("echo \"# http://dev.openbossa.org/trac/mamona/ticket/134 #\"\n") + rulesfile.write("echo \"# #\"\n") + rulesfile.write("echo \"#######################################################\"\n") + rulesfile.write("echo; echo\n") + rulesfile.close() + os.chmod(os.path.join(controldir, 'rules'), 0755) + +def gen_changelog_file(d, controldir): + import os + import bb + try: + chglogfile = file(os.path.join(controldir, 'changelog'), 'wb') + except OSError: + raise bb.build.FuncFailed("unable to open changelog file for writing.") + + chglogfile.write(u"%s (%s) %s; urgency=medium\n\n" % ( + bb.data.getVar('PN', d, 1), + bb.data.getVar('PV', d, 1), + bb.data.getVar('DISTRO', d, 1))) + + chglogfile.write(u" * Automatically Generated.\n\n") + + maintainer = bb.data.getVar("MAINTAINER", d, 1) or \ + "OpenEmbedded Team " + + from datetime import datetime + chglogfile.write(u" -- %s %s +0200\n" % ( + maintainer, datetime.today().strftime("%a, %d %b %Y %H:%M:%S"))) + + chglogfile.close() + +def gen_copyright_file(d, controldir): + import os + import bb + try: + cprfile = file(os.path.join(controldir, 'copyright'), 'wb') + except OSError: + raise bb.build.FuncFailed("unable to open copyright file for writing.") + + from datetime import datetime + maintainer = bb.data.getVar("MAINTAINER", d, 1) or \ + "OpenEmbedded Team " + lic = bb.data.getVar("LICENSE", d, 1) + + cprfile.write(u"This package was debianized by %s on %s\n\n" % ( + maintainer, datetime.today().strftime("%a, %d %b %Y %H:%M:%S"))) + cprfile.write(u"License: %s\n\n" % lic) + cprfile.write(u"The Debian packaging is (C) %s, %s and is licensed under the %s\n" % (datetime.today().year, maintainer, lic)) + cprfile.close() + +def add_pack_to_control_file(d, pkg, controldir): + import os + import bb + try: + ctrlfile = file(os.path.join(controldir, 'control'), 'a') + except OSError: + raise bb.build.FuncFailed("unable to open control file for writing.") + ctrlfile.write(u"Package: %s\n" % pkg) + ctrlfile.write(u"Architecture: any\n") + rdepends = explode_deps(unicode(bb.data.getVar("RDEPENDS", d, 1) or "")) + rdepends = [dep for dep in rdepends if not '*' in dep] + rrecommends = explode_deps(unicode(bb.data.getVar("RRECOMMENDS", d, 1) or "")) + rrecommends = [rec for rec in rrecommends if not '*' in rec] + rsuggests = (unicode(bb.data.getVar("RSUGGESTS", d, 1) or "")).split() + rprovides = (unicode(bb.data.getVar("RPROVIDES", d, 1) or "")).split() + rreplaces = (unicode(bb.data.getVar("RREPLACES", d, 1) or "")).split() + rconflicts = (unicode(bb.data.getVar("RCONFLICTS", d, 1) or "")).split() + if rdepends: + ctrlfile.write(u"Depends: %s\n" % ", ".join(rdepends)) + if rsuggests: + ctrlfile.write(u"Suggests: %s\n" % ", ".join(rsuggests)) + if rrecommends: + ctrlfile.write(u"Recommends: %s\n" % ", ".join(rrecommends)) + if rprovides: + ctrlfile.write(u"Provides: %s\n" % ", ".join(rprovides)) + if rreplaces: + ctrlfile.write(u"Replaces: %s\n" % ", ".join(rreplaces)) + if rconflicts: + ctrlfile.write(u"Conflicts: %s\n" % ", ".join(rconflicts)) + ctrlfile.write(u"Description: %s\n\n" % + bb.data.getVar("DESCRIPTION", d, 1)) + ctrlfile.close() + +def gen_control_file(d, controldir): + import os + import bb + try: + ctrlfile = file(os.path.join(controldir, 'control'), 'wb') + except OSError: + raise bb.build.FuncFailed("unable to open control file for writing.") + + maintainer = bb.data.getVar("MAINTAINER", d, 1) or \ + "OpenEmbedded Team " + + ctrlfile.write(u"Source: %s\n" % bb.data.getVar('PN', d, 1)) + ctrlfile.write(u"Section: %s\n" % bb.data.getVar("SECTION", d, 1)) + ctrlfile.write(u"Priority: %s\n" % bb.data.getVar("PRIORITY", d, 1)) + ctrlfile.write(u"Maintainer: %s\n" % maintainer) + ctrlfile.write(u"Standards-Version: %s\n\n" % bb.data.getVar('PV', d, 1)) + ctrlfile.close() + + packages = bb.data.getVar('PACKAGES', d, 1) + if packages: + added = [] + for pkg in packages.split(): + if added.count(pkg) == 0: + added.append(pkg) + add_pack_to_control_file(d, pkg, controldir) + +def gen_compat_file(d, controldir): + import os + import bb + try: + compatfile = file(os.path.join(controldir, 'compat'), 'wb') + except OSError: + raise bb.build.FuncFailed("unable to open changelog file for writing.") + + compatfile.write("5\n") + compatfile.close() + +def apply_patches(d, builddir): + import bb.fetch + import os + patch_init(d) + + localdata = bb.data.createCopy(d) + bb.data.update_data(localdata) + + workdir = bb.data.getVar("WORKDIR", d, 1) + src_uri = bb.data.getVar('SRC_URI', localdata) + if not src_uri: + return + src_uri = bb.data.expand(src_uri, localdata) + + patchsetmap = { + "patch": PatchTree, + "quilt": QuiltTree, + } + + cls = patchsetmap[bb.data.getVar('PATCHTOOL', d, 1) or 'quilt'] + + resolvermap = { + "noop": NOOPResolver, + "user": UserResolver, + } + + rcls = resolvermap[bb.data.getVar('PATCHRESOLVE', d, 1) or 'user'] + + path = os.getenv('PATH') + os.putenv('PATH', bb.data.getVar('PATH', d, 1)) + patchset = cls(builddir, d) + patchset.Clean() + + resolver = rcls(patchset) + + for url in src_uri.split(): + (type, host, path, user, pswd, parm) = bb.decodeurl(url) + if not "patch" in parm: + continue + + bb.fetch.init([url],d) + url = bb.encodeurl((type, host, path, user, pswd, [])) + local = os.path.join('/', bb.fetch.localpath(url, d)) + + # did it need to be unpacked? + dots = os.path.basename(local).split(".") + if dots[-1] in ['gz', 'bz2', 'Z']: + unpacked = os.path.join(workdir,'.'.join(dots[0:-1])) + else: + unpacked = local + unpacked = bb.data.expand(unpacked, d) + + if "pnum" in parm: + pnum = parm["pnum"] + else: + pnum = "1" + + if "pname" in parm: + pname = parm["pname"] + else: + pname = os.path.basename(unpacked) + + if "mindate" in parm or "maxdate" in parm: + pn = bb.data.getVar('PN', d, 1) + srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) + if not srcdate: + srcdate = bb.data.getVar('SRCDATE', d, 1) + + if srcdate == "now": + srcdate = bb.data.getVar('DATE', d, 1) + + if "maxdate" in parm and parm["maxdate"] < srcdate: + bb.note("Patch '%s' is outdated" % pname) + continue + + if "mindate" in parm and parm["mindate"] > srcdate: + bb.note("Patch '%s' is predated" % pname) + continue + + + if "minrev" in parm: + srcrev = bb.data.getVar('SRCREV', d, 1) + if srcrev and srcrev < parm["minrev"]: + bb.note("Patch '%s' applies to later revisions" % pname) + continue + + if "maxrev" in parm: + srcrev = bb.data.getVar('SRCREV', d, 1) + if srcrev and srcrev > parm["maxrev"]: + bb.note("Patch '%s' applies to earlier revisions" % pname) + continue + + bb.note("Applying patch '%s' (%s)" % (pname, unpacked)) + try: + patchset.Import({"file":unpacked, "remote":url, "strippath": pnum}, True) + except: + import sys + raise bb.build.FuncFailed(str(sys.exc_value)) + resolver.Resolve() + + # get rid of left overs + bb.note("Cleaning up patch leftovers") + os.system('rm -rf %s' % (os.path.join(builddir, '.pc'), )) + os.system('rm -rf %s' % (os.path.join(builddir, 'patches'), )) + + +def gen_controldir(d, builddir, controldir): + import pexpect + import bb + import os + + os.system("rm -rf %s" % controldir) + bb.mkdirhier(controldir) + + # Copying patches to controldir + o_patchesdir = os.path.join(bb.data.getVar('S', d, 1), "patches") + patchesdir = os.path.join(controldir, "patches") + bb.mkdirhier(patchesdir) + if os.path.isdir(o_patchesdir): + os.system("cp -a %s/*{.diff,.patch} %s/ 2>/dev/null" % + (o_patchesdir, patchesdir)) + apply_patches(d, builddir) + + # Generating preinst, postinst, prerm and postrm scripts + gen_script_files(d, controldir) + + # Generating list of installed files + gen_install_files(d, controldir) + + # Generating rules file + os.system("rm -f %s" % os.path.join(controldir, 'rules')) + gen_rules_file(d, controldir) + + # Generating changelog file + if not os.path.exists(os.path.join(controldir, 'changelog')): + gen_changelog_file(d, controldir) + + # Generating copyright file + if not os.path.exists(os.path.join(controldir, 'copyright')): + gen_copyright_file(d, controldir) + + # Generating control file + if not os.path.exists(os.path.join(controldir, 'control')): + gen_control_file(d, controldir) + + # Generating control file + if not os.path.exists(os.path.join(controldir, 'compat')): + gen_compat_file(d, controldir) + + +addtask create_dsc after do_install before do_build +python do_create_dsc () { + import re + import os + import bb + + packages = bb.data.getVar('PACKAGES', d, 1) + if not packages: + bb.note("dsc wasn't generated: Empty Package") + return + + # Getting package name: + pkgname = bb.data.getVar('P', d, 1) + if pkgname.count("intermediate") or \ + pkgname.count("native") or pkgname.count("cross"): + bb.note("dsc is not generated for native or cross packages") + return + + # Setting up directories: + workdir = bb.data.getVar("WORKDIR", d, 1) + if not workdir: + bb.error("WORKDIR not defined, unable to package") + return + + sdir = bb.data.getVar("S", d, 1).replace(workdir, "dscgen") + basedir = os.path.join(workdir, "dscgen") + os.system("rm -rf %s" % basedir) + bb.mkdirhier(basedir) + os.chdir(basedir) + builddir = os.path.join(workdir, sdir) + + outdir = bb.data.getVar("DEPLOY_DIR_DSC", d, 1) + if not outdir: + bb.error("DEPLOY_DIR_DSC not defined, unable to package") + return + pkgoutdir = os.path.join(outdir, pkgname.split('-')[0]) + + # Unpacking the source file (based on base_do_unpack of base.bbclass) + localdata = bb.data.createCopy(d) + bb.data.update_data(localdata) + src_uri = bb.data.getVar('SRC_URI', localdata) + if not src_uri: + return + src_uri = bb.data.expand(src_uri, localdata) + for url in src_uri.split(): + try: + local = bb.data.expand(bb.fetch.localpath(url, localdata), localdata) + except bb.MalformedUrl, e: + raise bb.build.FuncFailed('Unable to generate local path for malformed uri: %s' % e) + if not local: + raise bb.build.FuncFailed('Unable to locate local file for %s' % url) + # dont need any parameters for extraction, strip them off + local = re.sub(';.*$', '', local) + local = os.path.realpath(local) + ret = oe_unpack_file(local, localdata, url) + if not ret: + raise bb.build.FuncFailed() + + elements = os.listdir(os.getcwd()) + num_elements = len(elements) + + if num_elements == 0: + bb.note("Source empty. Unable to generate source package") + return + if not os.path.isdir(builddir): + bb.mkdirhier(builddir) + for e in elements: + os.system("mv %s %s/" % (os.path.join(os.getcwd(), e), builddir)) + + # Creating .orig + os.system("cp -a %s %s.orig" % (builddir, builddir)) + + # Generating debian control directory + gen_controldir(d, builddir, os.path.join(builddir, "debian")) + + # Let's build: + os.chdir(builddir) + bb.note("Building dsc package: %s" % os.getcwd()) + ret = os.system("dpkg-buildpackage -sa -uc -us -S -rfakeroot > /dev/null 2>&1") + if ret != 0: + raise bb.build.FuncFailed("dpkg-buildpackage -S execution failed") + else: + bb.mkdirhier(pkgoutdir) + os.system("mv ../*.dsc %s" % pkgoutdir) + os.system("mv ../*.diff.gz %s" % pkgoutdir) + os.system("mv ../*.changes %s" % pkgoutdir) + os.system("mv ../*.orig.tar.gz %s" % pkgoutdir) + + # Let's clean + os.chdir(workdir) + os.system("rm -rf %s" % basedir) +} -- 1.6.3.3