summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@windriver.com>2011-02-07 18:18:18 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2011-02-08 18:01:35 +0000
commit906285ff00d6ffd3fd7713af52250e7c6503edb7 (patch)
tree2ae9c99eb5772b965c8c690817407c0327f04e59
parent2f3a7348b7da637d2362e7ed50c96a248ff58fc5 (diff)
downloadpoky-906285ff00d6ffd3fd7713af52250e7c6503edb7.tar.gz
fetch2: Add SRPM knowledge
Enable the fetcher to be able to unpack and SRPM. By default the system will unpack the contents of the SRPM into the WORKDIR. A new syntax "unpack=file" was developed for the SRC_URI, to allow for a recipe to extract a specific file within an SRPM. An unpack operation will then be executed on the extracted file. In order to apply extracted patches (or unpack files not specified with unpack), you must specify the path using WORKDIR, i.e.: file://${WORKDIR}/mypatch.patch Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
-rw-r--r--bitbake/lib/bb/fetch2/__init__.py62
-rw-r--r--meta/recipes-devtools/rpm/rpm_5.4.0.bb52
-rwxr-xr-xscripts/rpm2cpio.sh53
3 files changed, 93 insertions, 74 deletions
diff --git a/bitbake/lib/bb/fetch2/__init__.py b/bitbake/lib/bb/fetch2/__init__.py
index ee3476bcc8..9a4acc2ede 100644
--- a/bitbake/lib/bb/fetch2/__init__.py
+++ b/bitbake/lib/bb/fetch2/__init__.py
@@ -628,6 +628,7 @@ class FetchMethod(object):
628 628
629 def unpack(self, urldata, rootdir, data): 629 def unpack(self, urldata, rootdir, data):
630 import subprocess 630 import subprocess
631 iterate = False
631 file = urldata.localpath 632 file = urldata.localpath
632 dots = file.split(".") 633 dots = file.split(".")
633 if dots[-1] in ['gz', 'bz2', 'Z']: 634 if dots[-1] in ['gz', 'bz2', 'Z']:
@@ -635,6 +636,7 @@ class FetchMethod(object):
635 else: 636 else:
636 efile = file 637 efile = file
637 cmd = None 638 cmd = None
639
638 if file.endswith('.tar'): 640 if file.endswith('.tar'):
639 cmd = 'tar x --no-same-owner -f %s' % file 641 cmd = 'tar x --no-same-owner -f %s' % file
640 elif file.endswith('.tgz') or file.endswith('.tar.gz') or file.endswith('.tar.Z'): 642 elif file.endswith('.tgz') or file.endswith('.tar.gz') or file.endswith('.tar.Z'):
@@ -654,36 +656,43 @@ class FetchMethod(object):
654 if 'dos' in urldata.parm: 656 if 'dos' in urldata.parm:
655 cmd = '%s -a' % cmd 657 cmd = '%s -a' % cmd
656 cmd = "%s '%s'" % (cmd, file) 658 cmd = "%s '%s'" % (cmd, file)
657 elif os.path.isdir(file): 659 elif file.endswith('.src.rpm') or file.endswith('.srpm'):
658 filesdir = os.path.realpath(bb.data.getVar("FILESDIR", data, True)) 660 if 'unpack' in urldata.parm:
659 destdir = "." 661 unpack_file = ("%s" % urldata.parm['unpack'])
660 if file[0:len(filesdir)] == filesdir: 662 cmd = 'rpm2cpio.sh %s | cpio -i %s' % (file, unpack_file)
661 destdir = file[len(filesdir):file.rfind('/')] 663 iterate = True
662 destdir = destdir.strip('/') 664 iterate_file = unpack_file
663 if len(destdir) < 1: 665 else:
664 destdir = "." 666 cmd = 'rpm2cpio.sh %s | cpio -i' % (file)
665 elif not os.access("%s/%s" % (rootdir, destdir), os.F_OK):
666 os.makedirs("%s/%s" % (rootdir, destdir))
667 cmd = 'cp -pPR %s %s/%s/' % (file, rootdir, destdir)
668 else: 667 else:
669 if not 'patch' in urldata.parm: 668 # If file == dest, then avoid any copies, as we already put the file into dest!
670 # The "destdir" handling was specifically done for FILESPATH 669 dest = os.path.join(rootdir, os.path.basename(file))
671 # items. So, only do so for file:// entries. 670 if (file != dest) and not (os.path.exists(dest) and os.path.samefile(file, dest)):
672 if urldata.type == "file" and urldata.path.find("/") != -1: 671 if os.path.isdir(file):
673 destdir = urldata.path.rsplit("/", 1)[0] 672 filesdir = os.path.realpath(bb.data.getVar("FILESDIR", data, True))
674 else:
675 destdir = "." 673 destdir = "."
676 bb.mkdirhier("%s/%s" % (rootdir, destdir)) 674 if file[0:len(filesdir)] == filesdir:
677 cmd = 'cp %s %s/%s/' % (file, rootdir, destdir) 675 destdir = file[len(filesdir):file.rfind('/')]
676 destdir = destdir.strip('/')
677 if len(destdir) < 1:
678 destdir = "."
679 elif not os.access("%s/%s" % (rootdir, destdir), os.F_OK):
680 os.makedirs("%s/%s" % (rootdir, destdir))
681 cmd = 'cp -pPR %s %s/%s/' % (file, rootdir, destdir)
682 else:
683 if not 'patch' in urldata.parm:
684 # The "destdir" handling was specifically done for FILESPATH
685 # items. So, only do so for file:// entries.
686 if urldata.type == "file" and urldata.path.find("/") != -1:
687 destdir = urldata.path.rsplit("/", 1)[0]
688 else:
689 destdir = "."
690 bb.mkdirhier("%s/%s" % (rootdir, destdir))
691 cmd = 'cp %s %s/%s/' % (file, rootdir, destdir)
678 692
679 if not cmd: 693 if not cmd:
680 return 694 return
681 695
682 dest = os.path.join(rootdir, os.path.basename(file))
683 if os.path.exists(dest):
684 if os.path.samefile(file, dest):
685 return
686
687 # Change to subdir before executing command 696 # Change to subdir before executing command
688 save_cwd = os.getcwd(); 697 save_cwd = os.getcwd();
689 os.chdir(rootdir) 698 os.chdir(rootdir)
@@ -701,6 +710,11 @@ class FetchMethod(object):
701 if ret != 0: 710 if ret != 0:
702 raise UnpackError("Unpack command %s failed with return value %s" % (cmd, ret), urldata.url) 711 raise UnpackError("Unpack command %s failed with return value %s" % (cmd, ret), urldata.url)
703 712
713 if iterate is True:
714 iterate_urldata = urldata
715 iterate_urldata.localpath = "%s/%s" % (rootdir, iterate_file)
716 self.unpack(urldata, rootdir, data)
717
704 return 718 return
705 719
706 def try_premirror(self, url, urldata, d): 720 def try_premirror(self, url, urldata, d):
diff --git a/meta/recipes-devtools/rpm/rpm_5.4.0.bb b/meta/recipes-devtools/rpm/rpm_5.4.0.bb
index ba1a2a2341..566325ea4a 100644
--- a/meta/recipes-devtools/rpm/rpm_5.4.0.bb
+++ b/meta/recipes-devtools/rpm/rpm_5.4.0.bb
@@ -43,12 +43,11 @@ LICENSE = "LGPL 2.1"
43LIC_FILES_CHKSUM = "file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1" 43LIC_FILES_CHKSUM = "file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1"
44 44
45DEPENDS = "bzip2 zlib python perl db openssl elfutils expat libpcre attr acl popt" 45DEPENDS = "bzip2 zlib python perl db openssl elfutils expat libpcre attr acl popt"
46PR = "r10" 46PR = "r11"
47 47
48# rpm2cpio is a shell script, which is part of the rpm src.rpm. It is needed 48# rpm2cpio is a shell script, which is part of the rpm src.rpm. It is needed
49# in order to extract the distribution SRPM into a format we can extract... 49# in order to extract the distribution SRPM into a format we can extract...
50SRC_URI = "http://www.rpm5.org/files/rpm/rpm-5.4/rpm-5.4.0-0.20101229.src.rpm \ 50SRC_URI = "http://www.rpm5.org/files/rpm/rpm-5.4/rpm-5.4.0-0.20101229.src.rpm;unpack=rpm-5.4.0.tar.gz \
51 file://rpm2cpio;md5=1850f9872a4803f5165bfd5816274275 \
52 file://perfile_rpmdeps.sh \ 51 file://perfile_rpmdeps.sh \
53 file://rpm-autogen.patch \ 52 file://rpm-autogen.patch \
54 file://rpm-libsql-fix.patch \ 53 file://rpm-libsql-fix.patch \
@@ -66,8 +65,6 @@ SRC_URI = "http://www.rpm5.org/files/rpm/rpm-5.4/rpm-5.4.0-0.20101229.src.rpm \
66SRC_URI[md5sum] = "19c1a7f68d7765eeb7615c9c4e54e380" 65SRC_URI[md5sum] = "19c1a7f68d7765eeb7615c9c4e54e380"
67SRC_URI[sha256sum] = "887e76218308b570c33c8c2fb10b5298b3afd5d602860d281befc85357b3b923" 66SRC_URI[sha256sum] = "887e76218308b570c33c8c2fb10b5298b3afd5d602860d281befc85357b3b923"
68 67
69SRPM_UNPACK = "rpm-5.4.0.tar.gz"
70
71inherit autotools gettext 68inherit autotools gettext
72 69
73acpaths = "-I ${S}/db/dist/aclocal -I ${S}/db/dist/aclocal_java" 70acpaths = "-I ${S}/db/dist/aclocal -I ${S}/db/dist/aclocal_java"
@@ -328,51 +325,6 @@ FILE_${PN}-dev = "${includedir}/rpm \
328###%{_rpmhome}/lib/librpmjsm.la 325###%{_rpmhome}/lib/librpmjsm.la
329###%{_rpmhome}/lib/librpmjsm.so 326###%{_rpmhome}/lib/librpmjsm.so
330 327
331def subprocess_setup():
332 import signal
333 # Python installs a SIGPIPE handler by default. This is usually not what
334 # non-Python subprocesses expect.
335 # SIGPIPE errors are known issues with gzip/bash
336 signal.signal(signal.SIGPIPE, signal.SIG_DFL)
337
338# If base_do_unpack is refactored this may have to be adjusted
339python base_do_unpack_append() {
340 import subprocess
341
342 for url in bb.data.getVar("SRC_URI", d, True).split():
343 local = bb.fetch2.localpath(url, d)
344 if local is None:
345 continue
346 local = os.path.realpath(local)
347
348 if local.endswith('.src.rpm') or local.endswith('.srpm'):
349 cmdname = os.path.join(bb.data.getVar('WORKDIR', localdata, 1),'rpm2cpio')
350 efile = os.path.join(bb.data.getVar('WORKDIR', localdata, 1),os.path.basename(local))
351 cmd = "%s %s | cpio -i" % (cmdname, efile)
352 cmd = "PATH=\"%s\" %s" % (bb.data.getVar('PATH', localdata, 1), cmd)
353 old_cwd = os.getcwd()
354 newdir = os.path.join(d.getVar("WORKDIR", True), 'srpm-unpack')
355 bb.mkdirhier(newdir)
356 os.chdir(newdir)
357 ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True)
358 os.chdir(old_cwd)
359 if ret != 0:
360 raise bb.build.FuncFailed('Unpack command failed: %s (%s)' % (cmd, ret))
361
362 srpm_uri = bb.data.getVar('SRPM_UNPACK', localdata, True).split()
363 if len(srpm_uri) == 0:
364 return
365
366 rootdir = bb.data.getVar('WORKDIR', localdata, True)
367 srpm_file_uri = [ "file://" + rootdir + "/srpm-unpack/" + uri for uri in srpm_uri];
368
369 try:
370 fetcher = bb.fetch2.Fetch(srpm_file_uri, localdata, cache=False)
371 fetcher.unpack(rootdir, srpm_file_uri)
372 except bb.fetch2.BBFetchException, e:
373 raise bb.build.FuncFailed(e)
374}
375
376do_configure() { 328do_configure() {
377 # Disable tests! 329 # Disable tests!
378 echo "all:" > tests/Makefile.am 330 echo "all:" > tests/Makefile.am
diff --git a/scripts/rpm2cpio.sh b/scripts/rpm2cpio.sh
new file mode 100755
index 0000000000..426fd77bb7
--- /dev/null
+++ b/scripts/rpm2cpio.sh
@@ -0,0 +1,53 @@
1#!/bin/sh
2
3# This comes from the RPM5 5.4.0 distribution.
4
5pkg=$1
6if [ "$pkg" = "" -o ! -e "$pkg" ]; then
7 echo "no package supplied" 1>&2
8 exit 1
9fi
10
11leadsize=96
12o=`expr $leadsize + 8`
13set `od -j $o -N 8 -t u1 $pkg`
14il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
15dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
16# echo "sig il: $il dl: $dl"
17
18sigsize=`expr 8 + 16 \* $il + $dl`
19o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
20set `od -j $o -N 8 -t u1 $pkg`
21il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
22dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
23# echo "hdr il: $il dl: $dl"
24
25hdrsize=`expr 8 + 16 \* $il + $dl`
26o=`expr $o + $hdrsize`
27EXTRACTOR="dd if=$pkg ibs=$o skip=1"
28
29COMPRESSION=`($EXTRACTOR |file -) 2>/dev/null`
30if echo $COMPRESSION |grep -q gzip; then
31 DECOMPRESSOR=gunzip
32elif echo $COMPRESSION |grep -q bzip2; then
33 DECOMPRESSOR=bunzip2
34elif echo $COMPRESSION |grep -q xz; then
35 DECOMPRESSOR=unxz
36elif echo $COMPRESSION |grep -q cpio; then
37 DECOMPRESSOR=cat
38else
39 # Most versions of file don't support LZMA, therefore we assume
40 # anything not detected is LZMA
41 DECOMPRESSOR=`which unlzma 2>/dev/null`
42 case "$DECOMPRESSOR" in
43 /* ) ;;
44 * ) DECOMPRESSOR=`which lzmash 2>/dev/null`
45 case "$DECOMPRESSOR" in
46 /* ) DECOMPRESSOR="lzmash -d -c" ;;
47 * ) DECOMPRESSOR=cat ;;
48 esac
49 ;;
50 esac
51fi
52
53$EXTRACTOR 2>/dev/null | $DECOMPRESSOR