diff options
Diffstat (limited to 'meta/lib/oe/sstatesig.py')
| -rw-r--r-- | meta/lib/oe/sstatesig.py | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py new file mode 100644 index 0000000000..aa25c3a10e --- /dev/null +++ b/meta/lib/oe/sstatesig.py | |||
| @@ -0,0 +1,166 @@ | |||
| 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 x.endswith("-cross") or x.endswith("-cross-initial") or x.endswith("-cross-intermediate") | ||
| 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 isImage(fn): | ||
| 18 | return "/image.bbclass" in " ".join(dataCache.inherits[fn]) | ||
| 19 | |||
| 20 | # Always include our own inter-task dependencies | ||
| 21 | if recipename == depname: | ||
| 22 | return True | ||
| 23 | |||
| 24 | # Quilt (patch application) changing isn't likely to affect anything | ||
| 25 | excludelist = ['quilt-native', 'subversion-native', 'git-native'] | ||
| 26 | if depname in excludelist and recipename != depname: | ||
| 27 | return False | ||
| 28 | |||
| 29 | # Don't change native/cross/nativesdk recipe dependencies any further | ||
| 30 | if isNative(recipename) or isCross(recipename) or isNativeSDK(recipename): | ||
| 31 | return True | ||
| 32 | |||
| 33 | # Only target packages beyond here | ||
| 34 | |||
| 35 | # packagegroups are assumed to have well behaved names which don't change between architecures/tunes | ||
| 36 | if isPackageGroup(fn): | ||
| 37 | return False | ||
| 38 | |||
| 39 | # Exclude well defined machine specific configurations which don't change ABI | ||
| 40 | if depname in siggen.abisaferecipes and not isImage(fn): | ||
| 41 | return False | ||
| 42 | |||
| 43 | # Exclude well defined recipe->dependency | ||
| 44 | if "%s->%s" % (recipename, depname) in siggen.saferecipedeps: | ||
| 45 | return False | ||
| 46 | |||
| 47 | # Kernel modules are well namespaced. We don't want to depend on the kernel's checksum | ||
| 48 | # if we're just doing an RRECOMMENDS_xxx = "kernel-module-*", not least because the checksum | ||
| 49 | # is machine specific. | ||
| 50 | # Therefore if we're not a kernel or a module recipe (inheriting the kernel classes) | ||
| 51 | # and we reccomend a kernel-module, we exclude the dependency. | ||
| 52 | depfn = dep.rsplit(".", 1)[0] | ||
| 53 | if dataCache and isKernel(depfn) and not isKernel(fn): | ||
| 54 | for pkg in dataCache.runrecs[fn]: | ||
| 55 | if " ".join(dataCache.runrecs[fn][pkg]).find("kernel-module-") != -1: | ||
| 56 | return False | ||
| 57 | |||
| 58 | # Default to keep dependencies | ||
| 59 | return True | ||
| 60 | |||
| 61 | class SignatureGeneratorOEBasic(bb.siggen.SignatureGeneratorBasic): | ||
| 62 | name = "OEBasic" | ||
| 63 | def init_rundepcheck(self, data): | ||
| 64 | self.abisaferecipes = (data.getVar("SIGGEN_EXCLUDERECIPES_ABISAFE", True) or "").split() | ||
| 65 | self.saferecipedeps = (data.getVar("SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS", True) or "").split() | ||
| 66 | pass | ||
| 67 | def rundep_check(self, fn, recipename, task, dep, depname, dataCache = None): | ||
| 68 | return sstate_rundepfilter(self, fn, recipename, task, dep, depname, dataCache) | ||
| 69 | |||
| 70 | class SignatureGeneratorOEBasicHash(bb.siggen.SignatureGeneratorBasicHash): | ||
| 71 | name = "OEBasicHash" | ||
| 72 | def init_rundepcheck(self, data): | ||
| 73 | self.abisaferecipes = (data.getVar("SIGGEN_EXCLUDERECIPES_ABISAFE", True) or "").split() | ||
| 74 | self.saferecipedeps = (data.getVar("SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS", True) or "").split() | ||
| 75 | pass | ||
| 76 | def rundep_check(self, fn, recipename, task, dep, depname, dataCache = None): | ||
| 77 | return sstate_rundepfilter(self, fn, recipename, task, dep, depname, dataCache) | ||
| 78 | |||
| 79 | # Insert these classes into siggen's namespace so it can see and select them | ||
| 80 | bb.siggen.SignatureGeneratorOEBasic = SignatureGeneratorOEBasic | ||
| 81 | bb.siggen.SignatureGeneratorOEBasicHash = SignatureGeneratorOEBasicHash | ||
| 82 | |||
| 83 | |||
| 84 | def find_siginfo(pn, taskname, taskhashlist, d): | ||
| 85 | """ Find signature data files for comparison purposes """ | ||
| 86 | |||
| 87 | import fnmatch | ||
| 88 | import glob | ||
| 89 | |||
| 90 | if taskhashlist: | ||
| 91 | hashfiles = {} | ||
| 92 | |||
| 93 | if not taskname: | ||
| 94 | # We have to derive pn and taskname | ||
| 95 | key = pn | ||
| 96 | splitit = key.split('.bb.') | ||
| 97 | taskname = splitit[1] | ||
| 98 | pn = os.path.basename(splitit[0]).split('_')[0] | ||
| 99 | if key.startswith('virtual:native:'): | ||
| 100 | pn = pn + '-native' | ||
| 101 | |||
| 102 | if taskname in ['do_fetch', 'do_unpack', 'do_patch', 'do_populate_lic']: | ||
| 103 | pn.replace("-native", "") | ||
| 104 | |||
| 105 | filedates = {} | ||
| 106 | |||
| 107 | # First search in stamps dir | ||
| 108 | localdata = d.createCopy() | ||
| 109 | localdata.setVar('MULTIMACH_TARGET_SYS', '*') | ||
| 110 | localdata.setVar('PN', pn) | ||
| 111 | localdata.setVar('PV', '*') | ||
| 112 | localdata.setVar('PR', '*') | ||
| 113 | localdata.setVar('EXTENDPE', '') | ||
| 114 | stamp = localdata.getVar('STAMP', True) | ||
| 115 | filespec = '%s.%s.sigdata.*' % (stamp, taskname) | ||
| 116 | foundall = False | ||
| 117 | import glob | ||
| 118 | for fullpath in glob.glob(filespec): | ||
| 119 | match = False | ||
| 120 | if taskhashlist: | ||
| 121 | for taskhash in taskhashlist: | ||
| 122 | if fullpath.endswith('.%s' % taskhash): | ||
| 123 | hashfiles[taskhash] = fullpath | ||
| 124 | if len(hashfiles) == len(taskhashlist): | ||
| 125 | foundall = True | ||
| 126 | break | ||
| 127 | else: | ||
| 128 | filedates[fullpath] = os.stat(fullpath).st_mtime | ||
| 129 | |||
| 130 | if not taskhashlist or (len(filedates) < 2 and not foundall): | ||
| 131 | # That didn't work, look in sstate-cache | ||
| 132 | hashes = taskhashlist or ['*'] | ||
| 133 | localdata = bb.data.createCopy(d) | ||
| 134 | for hashval in hashes: | ||
| 135 | localdata.setVar('PACKAGE_ARCH', '*') | ||
| 136 | localdata.setVar('TARGET_VENDOR', '*') | ||
| 137 | localdata.setVar('TARGET_OS', '*') | ||
| 138 | localdata.setVar('PN', pn) | ||
| 139 | localdata.setVar('PV', '*') | ||
| 140 | localdata.setVar('PR', '*') | ||
| 141 | localdata.setVar('BB_TASKHASH', hashval) | ||
| 142 | if pn.endswith('-native') or pn.endswith('-crosssdk') or pn.endswith('-cross'): | ||
| 143 | localdata.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/") | ||
| 144 | sstatename = taskname[3:] | ||
| 145 | filespec = '%s_%s.*.siginfo' % (localdata.getVar('SSTATE_PKG', True), sstatename) | ||
| 146 | |||
| 147 | if hashval != '*': | ||
| 148 | sstatedir = "%s/%s" % (d.getVar('SSTATE_DIR', True), hashval[:2]) | ||
| 149 | else: | ||
| 150 | sstatedir = d.getVar('SSTATE_DIR', True) | ||
| 151 | |||
| 152 | for root, dirs, files in os.walk(sstatedir): | ||
| 153 | for fn in files: | ||
| 154 | fullpath = os.path.join(root, fn) | ||
| 155 | if fnmatch.fnmatch(fullpath, filespec): | ||
| 156 | if taskhashlist: | ||
| 157 | hashfiles[hashval] = fullpath | ||
| 158 | else: | ||
| 159 | filedates[fullpath] = os.stat(fullpath).st_mtime | ||
| 160 | |||
| 161 | if taskhashlist: | ||
| 162 | return hashfiles | ||
| 163 | else: | ||
| 164 | return filedates | ||
| 165 | |||
| 166 | bb.siggen.find_siginfo = find_siginfo | ||
