sg3-utils: add newer buildable version
[openembedded.git] / conf / collections.inc
1 # Copyright (c) 2009 MontaVista Software, Inc.  All rights reserved.
2 #
3 # Released under the MIT license (see COPYING.MIT for the terms)
4 #
5 # Take a list of directories in COLLECTIONS, in priority order (highest to
6 # lowest), and use those to populate BBFILES, BBFILE_COLLECTIONS,
7 # BBFILE_PATTERN_*, and BBFILE_PRIORITY_*.
8 #
9 # Specifying an archive in COLLECTIONS is also supported.  Any archives of a
10 # supported format will be unpacked into COLLECTIONS_UNPACKDIR and used from
11 # there.
12
13 COLLECTIONS ?= "${@' '.join(d.getVar('BBPATH', 1).split(':'))}"
14 COLLECTIONS_UNPACKDIR = "${TMPDIR}/collections"
15
16 COLLECTIONINFO = "${@get_collection(d.getVar('FILE', 1), d)}"
17
18 def has_collection(name, d):
19     for (uniquename, info) in d.getVar("COLLECTIONSINFO", 1).iteritems():
20         if info["name"] == name:
21             return True
22     return False
23
24 def get_collection(file, d):
25     if not os.path.isabs(file):
26         file = bb.which(d.getVar("BBPATH", 1), file)
27     filedir = os.path.realpath(os.path.dirname(file))
28     for (uniquename, info) in d.getVar("COLLECTIONSINFO", 1).iteritems():
29         path = os.path.realpath(info["path"])
30         if filedir.startswith(path + os.path.sep):
31             return info
32
33 def collection_unpack(collection, d):
34     """ Unpack a collection archive and return the path to it. """
35     import bb
36     import os
37     from md5 import md5
38
39     handlers = {
40         ("tar"): "tar x --no-same-owner -f %s",
41         ("tar.gz", "tgz", "tar.Z"): "tar xz --no-same-owner -f %s",
42         ("tar.bz2", "tbz", "tbz2"): "tar xj --no-same-owner -f %s",
43         ("zip", "jar"): "unzip -q -o %s",
44     }
45
46     basename = os.path.basename(collection)
47     try:
48         cmd, name = ((cmd, basename[:-len(e)-1]) for (exts, cmd) in handlers.iteritems()
49                      for e in exts
50                      if basename.endswith(e)).next()
51     except StopIteration:
52         bb.fatal("No method available to unpack %s (unsupported file type?)" % collection)
53     else:
54         outpath = os.path.join(d.getVar("COLLECTIONS_UNPACKDIR", 1), name)
55         cmd = "cd %s && PATH=\"%s\" %s" % (outpath, d.getVar("PATH", 1), cmd)
56
57     try:
58         collectiondata = open(collection, "r").read()
59     except IOError:
60         bb.fatal("Unable to open %s to calculate md5 sum" % collection)
61
62     md5obj = md5()
63     md5obj.update(collectiondata)
64     md5sum = md5obj.hexdigest()
65
66     md5file = os.path.join(outpath, "md5")
67     if os.path.exists(md5file):
68         try:
69             oldmd5sum = open(md5file).read()
70         except IOError:
71             pass
72         else:
73             if oldmd5sum == md5sum:
74                 bb.debug(1, "Using existing %s for collection '%s'" % (outpath, name))
75                 return outpath, False, name
76
77         bb.note("Removing old unpacked collection at %s" % outpath)
78         os.system("rm -rf %s" % outpath)
79
80     if not os.path.isdir(outpath):
81         os.makedirs(outpath)
82
83     bb.note("Unpacking %s to %s/" % (collection, outpath))
84     ret = os.system(cmd % collection)
85     if ret != 0:
86         bb.fatal("Unable to unpack %s" % collection)
87
88     md5out = open(md5file, "w")
89     md5out.write(md5sum)
90     md5out.close()
91     return outpath, True, name
92
93 def collections_setup(d):
94     """ Populate collection and bbfiles metadata from the COLLECTIONS var. """
95     import bb
96     import os
97     from itertools import izip, chain
98     from glob import glob
99
100     def setifunset(k, v):
101         if d.getVar(k, 0) is None:
102             d.setVar(k, v)
103
104     collections = d.getVar("COLLECTIONS", 1)
105     if not collections:
106         return
107
108     bb.debug(1, "Processing COLLECTIONS (%s)" % collections)
109
110     globbed = []
111     for path in collections.split():
112         paths = glob(os.path.normpath(path))
113         if not paths:
114             bb.msg.warn(None, "No matches in filesystem for %s in COLLECTIONS" % path)
115         globbed += paths
116     collections = globbed
117
118     collectionmap = {}
119     namemap = {}
120     collectioninfo = {}
121     unpackedthisexec = False
122     oldbbpath = d.getVar("BBPATH", 1)
123     bbpath = (oldbbpath or "").split(":")
124     for (collection, priority) in izip(collections, xrange(len(collections), 0, -1)):
125         if not os.path.exists(collection):
126             bb.fatal("Collection %s does not exist" % collection)
127
128         origpath = collection
129         if not os.path.isdir(collection):
130             unpacked, unpackedthisexec, name = collection_unpack(collection, d)
131             if unpacked:
132                 collection = unpacked
133                 for dir in glob("%s/*/" % collection):
134                     if not dir in bbpath:
135                         bbpath.append(dir)
136             else:
137                 bb.fatal("Unable to unpack collection %s" % collection)
138         else:
139             name = os.path.basename(collection)
140             if not collection in bbpath:
141                 bbpath.append(collection)
142
143         if namemap.get(name):
144             name = "%s-%s" % (name, hash(collection))
145         namemap[name] = collection
146         collectionmap[collection] = name
147
148         collectioninfo[name] = {
149             "name": name,
150             "originalpath": origpath,
151             "path": collection,
152             "priority": priority,
153         }
154
155         setifunset("BBFILE_PATTERN_%s" % name, "^%s/" % collection)
156         setifunset("BBFILE_PRIORITY_%s" % name, str(priority))
157
158     d.setVar("COLLECTIONSINFO", collectioninfo)
159
160     setifunset("BBFILE_COLLECTIONS", " ".join(collectionmap.values()))
161     setifunset("BBFILES", " ".join(collectionmap.keys()))
162
163     bbpath = [os.path.realpath(dir) for dir in bbpath if os.path.exists(dir)]
164     d.setVar("BBPATH", ":".join(bbpath))
165     if unpackedthisexec or (set(bbpath) != set(oldbbpath.split(":"))):
166         import sys
167         bb.debug(1, "Re-executing bitbake with BBPATH of %s" % d.getVar("BBPATH", 0))
168         os.environ["BBPATH"] = d.getVar("BBPATH", 0)
169         # FIXME: This exports a bogus PYTHONPATH to OE recipes resulting in massive breakages: 
170         # http://thread.gmane.org/gmane.comp.handhelds.openembedded/30163
171         # os.environ["PYTHONPATH"] = ":".join(sys.path)
172         sys.argv.insert(0, sys.executable)
173         os.execvpe(sys.executable, sys.argv, os.environ)
174
175 addhandler collections_eh
176 python collections_eh () {
177     from bb.event import getName
178
179     if getName(e) == "ConfigParsed":
180         collections_setup(e.data)
181
182     return NotHandled
183 }