diff options
author | Tudor Florea <tudor.florea@enea.com> | 2015-10-09 22:59:03 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2015-10-09 22:59:03 +0200 |
commit | 972dcfcdbfe75dcfeb777150c136576cf1a71e99 (patch) | |
tree | 97a61cd7e293d7ae9d56ef7ed0f81253365bb026 /meta/lib/oe/sstatesig.py | |
download | poky-972dcfcdbfe75dcfeb777150c136576cf1a71e99.tar.gz |
initial commit for Enea Linux 5.0 arm
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'meta/lib/oe/sstatesig.py')
-rw-r--r-- | meta/lib/oe/sstatesig.py | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py new file mode 100644 index 0000000000..af7617ee61 --- /dev/null +++ b/meta/lib/oe/sstatesig.py | |||
@@ -0,0 +1,276 @@ | |||
1 | import bb.siggen | ||
2 | |||
3 | def sstate_rundepfilter(siggen, fn, recipename, task, dep, depname, dataCache): | ||
4 | # Return True if we should keep the dependency, False to drop it | ||
5 | def isNative(x): | ||
6 | return x.endswith("-native") | ||
7 | def isCross(x): | ||
8 | return "-cross-" in x | ||
9 | def isNativeSDK(x): | ||
10 | return x.startswith("nativesdk-") | ||
11 | def isKernel(fn): | ||
12 | inherits = " ".join(dataCache.inherits[fn]) | ||
13 | return inherits.find("/module-base.bbclass") != -1 or inherits.find("/linux-kernel-base.bbclass") != -1 | ||
14 | def isPackageGroup(fn): | ||
15 | inherits = " ".join(dataCache.inherits[fn]) | ||
16 | return "/packagegroup.bbclass" in inherits | ||
17 | def isAllArch(fn): | ||
18 | inherits = " ".join(dataCache.inherits[fn]) | ||
19 | return "/allarch.bbclass" in inherits | ||
20 | def isImage(fn): | ||
21 | return "/image.bbclass" in " ".join(dataCache.inherits[fn]) | ||
22 | |||
23 | # Always include our own inter-task dependencies | ||
24 | if recipename == depname: | ||
25 | return True | ||
26 | |||
27 | # Quilt (patch application) changing isn't likely to affect anything | ||
28 | excludelist = ['quilt-native', 'subversion-native', 'git-native'] | ||
29 | if depname in excludelist and recipename != depname: | ||
30 | return False | ||
31 | |||
32 | # Exclude well defined recipe->dependency | ||
33 | if "%s->%s" % (recipename, depname) in siggen.saferecipedeps: | ||
34 | return False | ||
35 | |||
36 | # Don't change native/cross/nativesdk recipe dependencies any further | ||
37 | if isNative(recipename) or isCross(recipename) or isNativeSDK(recipename): | ||
38 | return True | ||
39 | |||
40 | # Only target packages beyond here | ||
41 | |||
42 | # allarch packagegroups are assumed to have well behaved names which don't change between architecures/tunes | ||
43 | if isPackageGroup(fn) and isAllArch(fn): | ||
44 | return False | ||
45 | |||
46 | # Exclude well defined machine specific configurations which don't change ABI | ||
47 | if depname in siggen.abisaferecipes and not isImage(fn): | ||
48 | return False | ||
49 | |||
50 | # Kernel modules are well namespaced. We don't want to depend on the kernel's checksum | ||
51 | # if we're just doing an RRECOMMENDS_xxx = "kernel-module-*", not least because the checksum | ||
52 | # is machine specific. | ||
53 | # Therefore if we're not a kernel or a module recipe (inheriting the kernel classes) | ||
54 | # and we reccomend a kernel-module, we exclude the dependency. | ||
55 | depfn = dep.rsplit(".", 1)[0] | ||
56 | if dataCache and isKernel(depfn) and not isKernel(fn): | ||
57 | for pkg in dataCache.runrecs[fn]: | ||
58 | if " ".join(dataCache.runrecs[fn][pkg]).find("kernel-module-") != -1: | ||
59 | return False | ||
60 | |||
61 | # Default to keep dependencies | ||
62 | return True | ||
63 | |||
64 | def sstate_lockedsigs(d): | ||
65 | sigs = {} | ||
66 | types = (d.getVar("SIGGEN_LOCKEDSIGS_TYPES", True) or "").split() | ||
67 | for t in types: | ||
68 | lockedsigs = (d.getVar("SIGGEN_LOCKEDSIGS_%s" % t, True) or "").split() | ||
69 | for ls in lockedsigs: | ||
70 | pn, task, h = ls.split(":", 2) | ||
71 | if pn not in sigs: | ||
72 | sigs[pn] = {} | ||
73 | sigs[pn][task] = h | ||
74 | return sigs | ||
75 | |||
76 | class SignatureGeneratorOEBasic(bb.siggen.SignatureGeneratorBasic): | ||
77 | name = "OEBasic" | ||
78 | def init_rundepcheck(self, data): | ||
79 | self.abisaferecipes = (data.getVar("SIGGEN_EXCLUDERECIPES_ABISAFE", True) or "").split() | ||
80 | self.saferecipedeps = (data.getVar("SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS", True) or "").split() | ||
81 | pass | ||
82 | def rundep_check(self, fn, recipename, task, dep, depname, dataCache = None): | ||
83 | return sstate_rundepfilter(self, fn, recipename, task, dep, depname, dataCache) | ||
84 | |||
85 | class SignatureGeneratorOEBasicHash(bb.siggen.SignatureGeneratorBasicHash): | ||
86 | name = "OEBasicHash" | ||
87 | def init_rundepcheck(self, data): | ||
88 | self.abisaferecipes = (data.getVar("SIGGEN_EXCLUDERECIPES_ABISAFE", True) or "").split() | ||
89 | self.saferecipedeps = (data.getVar("SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS", True) or "").split() | ||
90 | self.lockedsigs = sstate_lockedsigs(data) | ||
91 | self.lockedhashes = {} | ||
92 | self.lockedpnmap = {} | ||
93 | self.lockedhashfn = {} | ||
94 | self.machine = data.getVar("MACHINE", True) | ||
95 | self.mismatch_msgs = [] | ||
96 | pass | ||
97 | def rundep_check(self, fn, recipename, task, dep, depname, dataCache = None): | ||
98 | return sstate_rundepfilter(self, fn, recipename, task, dep, depname, dataCache) | ||
99 | |||
100 | def get_taskdata(self): | ||
101 | data = super(bb.siggen.SignatureGeneratorBasicHash, self).get_taskdata() | ||
102 | return (data, self.lockedpnmap, self.lockedhashfn) | ||
103 | |||
104 | def set_taskdata(self, data): | ||
105 | coredata, self.lockedpnmap, self.lockedhashfn = data | ||
106 | super(bb.siggen.SignatureGeneratorBasicHash, self).set_taskdata(coredata) | ||
107 | |||
108 | def dump_sigs(self, dataCache, options): | ||
109 | self.dump_lockedsigs() | ||
110 | return super(bb.siggen.SignatureGeneratorBasicHash, self).dump_sigs(dataCache, options) | ||
111 | |||
112 | def get_taskhash(self, fn, task, deps, dataCache): | ||
113 | h = super(bb.siggen.SignatureGeneratorBasicHash, self).get_taskhash(fn, task, deps, dataCache) | ||
114 | |||
115 | recipename = dataCache.pkg_fn[fn] | ||
116 | self.lockedpnmap[fn] = recipename | ||
117 | self.lockedhashfn[fn] = dataCache.hashfn[fn] | ||
118 | if recipename in self.lockedsigs: | ||
119 | if task in self.lockedsigs[recipename]: | ||
120 | k = fn + "." + task | ||
121 | h_locked = self.lockedsigs[recipename][task] | ||
122 | self.lockedhashes[k] = h_locked | ||
123 | self.taskhash[k] = h_locked | ||
124 | #bb.warn("Using %s %s %s" % (recipename, task, h)) | ||
125 | |||
126 | if h != h_locked: | ||
127 | self.mismatch_msgs.append('The %s:%s sig (%s) changed, use locked sig %s to instead' | ||
128 | % (recipename, task, h, h_locked)) | ||
129 | |||
130 | return h_locked | ||
131 | #bb.warn("%s %s %s" % (recipename, task, h)) | ||
132 | return h | ||
133 | |||
134 | def dump_sigtask(self, fn, task, stampbase, runtime): | ||
135 | k = fn + "." + task | ||
136 | if k in self.lockedhashes: | ||
137 | return | ||
138 | super(bb.siggen.SignatureGeneratorBasicHash, self).dump_sigtask(fn, task, stampbase, runtime) | ||
139 | |||
140 | def dump_lockedsigs(self, sigfile=None): | ||
141 | if not sigfile: | ||
142 | sigfile = os.getcwd() + "/locked-sigs.inc" | ||
143 | |||
144 | bb.plain("Writing locked sigs to %s" % sigfile) | ||
145 | types = {} | ||
146 | for k in self.runtaskdeps: | ||
147 | fn = k.rsplit(".",1)[0] | ||
148 | t = self.lockedhashfn[fn].split(" ")[1].split(":")[5] | ||
149 | t = 't-' + t.replace('_', '-') | ||
150 | if t not in types: | ||
151 | types[t] = [] | ||
152 | types[t].append(k) | ||
153 | |||
154 | with open(sigfile, "w") as f: | ||
155 | for t in types: | ||
156 | f.write('SIGGEN_LOCKEDSIGS_%s = "\\\n' % t) | ||
157 | types[t].sort() | ||
158 | sortedk = sorted(types[t], key=lambda k: self.lockedpnmap[k.rsplit(".",1)[0]]) | ||
159 | for k in sortedk: | ||
160 | fn = k.rsplit(".",1)[0] | ||
161 | task = k.rsplit(".",1)[1] | ||
162 | if k not in self.taskhash: | ||
163 | continue | ||
164 | f.write(" " + self.lockedpnmap[fn] + ":" + task + ":" + self.taskhash[k] + " \\\n") | ||
165 | f.write(' "\n') | ||
166 | f.write('SIGGEN_LOCKEDSIGS_TYPES_%s = "%s"' % (self.machine, " ".join(types.keys()))) | ||
167 | |||
168 | def checkhashes(self, missed, ret, sq_fn, sq_task, sq_hash, sq_hashfn, d): | ||
169 | checklevel = d.getVar("SIGGEN_LOCKEDSIGS_CHECK_LEVEL", True) | ||
170 | for task in range(len(sq_fn)): | ||
171 | if task not in ret: | ||
172 | for pn in self.lockedsigs: | ||
173 | if sq_hash[task] in self.lockedsigs[pn].itervalues(): | ||
174 | self.mismatch_msgs.append("Locked sig is set for %s:%s (%s) yet not in sstate cache?" | ||
175 | % (pn, sq_task[task], sq_hash[task])) | ||
176 | |||
177 | if self.mismatch_msgs and checklevel == 'warn': | ||
178 | bb.warn("\n".join(self.mismatch_msgs)) | ||
179 | elif self.mismatch_msgs and checklevel == 'error': | ||
180 | bb.fatal("\n".join(self.mismatch_msgs)) | ||
181 | |||
182 | |||
183 | # Insert these classes into siggen's namespace so it can see and select them | ||
184 | bb.siggen.SignatureGeneratorOEBasic = SignatureGeneratorOEBasic | ||
185 | bb.siggen.SignatureGeneratorOEBasicHash = SignatureGeneratorOEBasicHash | ||
186 | |||
187 | |||
188 | def find_siginfo(pn, taskname, taskhashlist, d): | ||
189 | """ Find signature data files for comparison purposes """ | ||
190 | |||
191 | import fnmatch | ||
192 | import glob | ||
193 | |||
194 | if taskhashlist: | ||
195 | hashfiles = {} | ||
196 | |||
197 | if not taskname: | ||
198 | # We have to derive pn and taskname | ||
199 | key = pn | ||
200 | splitit = key.split('.bb.') | ||
201 | taskname = splitit[1] | ||
202 | pn = os.path.basename(splitit[0]).split('_')[0] | ||
203 | if key.startswith('virtual:native:'): | ||
204 | pn = pn + '-native' | ||
205 | |||
206 | if taskname in ['do_fetch', 'do_unpack', 'do_patch', 'do_populate_lic']: | ||
207 | pn.replace("-native", "") | ||
208 | |||
209 | filedates = {} | ||
210 | |||
211 | # First search in stamps dir | ||
212 | localdata = d.createCopy() | ||
213 | localdata.setVar('MULTIMACH_TARGET_SYS', '*') | ||
214 | localdata.setVar('PN', pn) | ||
215 | localdata.setVar('PV', '*') | ||
216 | localdata.setVar('PR', '*') | ||
217 | localdata.setVar('EXTENDPE', '') | ||
218 | stamp = localdata.getVar('STAMP', True) | ||
219 | filespec = '%s.%s.sigdata.*' % (stamp, taskname) | ||
220 | foundall = False | ||
221 | import glob | ||
222 | for fullpath in glob.glob(filespec): | ||
223 | match = False | ||
224 | if taskhashlist: | ||
225 | for taskhash in taskhashlist: | ||
226 | if fullpath.endswith('.%s' % taskhash): | ||
227 | hashfiles[taskhash] = fullpath | ||
228 | if len(hashfiles) == len(taskhashlist): | ||
229 | foundall = True | ||
230 | break | ||
231 | else: | ||
232 | try: | ||
233 | filedates[fullpath] = os.stat(fullpath).st_mtime | ||
234 | except OSError: | ||
235 | continue | ||
236 | |||
237 | if not taskhashlist or (len(filedates) < 2 and not foundall): | ||
238 | # That didn't work, look in sstate-cache | ||
239 | hashes = taskhashlist or ['*'] | ||
240 | localdata = bb.data.createCopy(d) | ||
241 | for hashval in hashes: | ||
242 | localdata.setVar('PACKAGE_ARCH', '*') | ||
243 | localdata.setVar('TARGET_VENDOR', '*') | ||
244 | localdata.setVar('TARGET_OS', '*') | ||
245 | localdata.setVar('PN', pn) | ||
246 | localdata.setVar('PV', '*') | ||
247 | localdata.setVar('PR', '*') | ||
248 | localdata.setVar('BB_TASKHASH', hashval) | ||
249 | if pn.endswith('-native') or "-cross-" in pn or "-crosssdk-" in pn: | ||
250 | localdata.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/") | ||
251 | sstatename = taskname[3:] | ||
252 | filespec = '%s_%s.*.siginfo' % (localdata.getVar('SSTATE_PKG', True), sstatename) | ||
253 | |||
254 | if hashval != '*': | ||
255 | sstatedir = "%s/%s" % (d.getVar('SSTATE_DIR', True), hashval[:2]) | ||
256 | else: | ||
257 | sstatedir = d.getVar('SSTATE_DIR', True) | ||
258 | |||
259 | for root, dirs, files in os.walk(sstatedir): | ||
260 | for fn in files: | ||
261 | fullpath = os.path.join(root, fn) | ||
262 | if fnmatch.fnmatch(fullpath, filespec): | ||
263 | if taskhashlist: | ||
264 | hashfiles[hashval] = fullpath | ||
265 | else: | ||
266 | try: | ||
267 | filedates[fullpath] = os.stat(fullpath).st_mtime | ||
268 | except: | ||
269 | continue | ||
270 | |||
271 | if taskhashlist: | ||
272 | return hashfiles | ||
273 | else: | ||
274 | return filedates | ||
275 | |||
276 | bb.siggen.find_siginfo = find_siginfo | ||