blob: 11222223a9b003dadb419f059b86655bff6b6ec6 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001SSTATE_VERSION = "3"
2
3SSTATE_MANIFESTS ?= "${TMPDIR}/sstate-control"
4SSTATE_MANFILEPREFIX = "${SSTATE_MANIFESTS}/manifest-${SSTATE_MANMACH}-${PN}"
5
6def generate_sstatefn(spec, hash, d):
7 if not hash:
8 hash = "INVALID"
9 return hash[:2] + "/" + spec + hash
10
11SSTATE_PKGARCH = "${PACKAGE_ARCH}"
12SSTATE_PKGSPEC = "sstate:${PN}:${PACKAGE_ARCH}${TARGET_VENDOR}-${TARGET_OS}:${PV}:${PR}:${SSTATE_PKGARCH}:${SSTATE_VERSION}:"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050013SSTATE_SWSPEC = "sstate:${PN}::${PV}:${PR}::${SSTATE_VERSION}:"
Brad Bishop19323692019-04-05 15:28:33 -040014SSTATE_PKGNAME = "${SSTATE_EXTRAPATH}${@generate_sstatefn(d.getVar('SSTATE_PKGSPEC'), d.getVar('BB_UNIHASH'), d)}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015SSTATE_PKG = "${SSTATE_DIR}/${SSTATE_PKGNAME}"
16SSTATE_EXTRAPATH = ""
17SSTATE_EXTRAPATHWILDCARD = ""
18SSTATE_PATHSPEC = "${SSTATE_DIR}/${SSTATE_EXTRAPATHWILDCARD}*/${SSTATE_PKGSPEC}"
19
Patrick Williamsc0f7c042017-02-23 20:41:17 -060020# explicitly make PV to depend on evaluated value of PV variable
21PV[vardepvalue] = "${PV}"
22
Patrick Williamsc124f4f2015-09-15 14:41:29 -050023# We don't want the sstate to depend on things like the distro string
24# of the system, we let the sstate paths take care of this.
25SSTATE_EXTRAPATH[vardepvalue] = ""
Brad Bishop19323692019-04-05 15:28:33 -040026SSTATE_EXTRAPATHWILDCARD[vardepvalue] = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -050027
28# For multilib rpm the allarch packagegroup files can overwrite (in theory they're identical)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080029SSTATE_DUPWHITELIST = "${DEPLOY_DIR}/licenses/"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030# Avoid docbook/sgml catalog warnings for now
31SSTATE_DUPWHITELIST += "${STAGING_ETCDIR_NATIVE}/sgml ${STAGING_DATADIR_NATIVE}/sgml"
Brad Bishop316dfdd2018-06-25 12:45:53 -040032# sdk-provides-dummy-nativesdk and nativesdk-buildtools-perl-dummy overlap for different SDKMACHINE
33SSTATE_DUPWHITELIST += "${DEPLOY_DIR_RPM}/sdk_provides_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/sdk-provides-dummy-nativesdk/"
34SSTATE_DUPWHITELIST += "${DEPLOY_DIR_RPM}/buildtools_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/buildtools-dummy-nativesdk/"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080035# target-sdk-provides-dummy overlaps that allarch is disabled when multilib is used
36SSTATE_DUPWHITELIST += "${COMPONENTS_DIR}/sdk-provides-dummy-target/ ${DEPLOY_DIR_RPM}/sdk_provides_dummy_target/ ${DEPLOY_DIR_IPK}/sdk-provides-dummy-target/"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050037# Archive the sources for many architectures in one deploy folder
38SSTATE_DUPWHITELIST += "${DEPLOY_DIR_SRC}"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080039# ovmf/grub-efi/systemd-boot/intel-microcode multilib recipes can generate identical overlapping files
40SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/ovmf"
41SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/grub-efi"
42SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/systemd-boot"
43SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/microcode"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050044
Brad Bishop6e60e8b2018-02-01 10:27:11 -050045SSTATE_SCAN_FILES ?= "*.la *-config *_config postinst-*"
46SSTATE_SCAN_CMD ??= 'find ${SSTATE_BUILDDIR} \( -name "${@"\" -o -name \"".join(d.getVar("SSTATE_SCAN_FILES").split())}" \) -type f'
47SSTATE_SCAN_CMD_NATIVE ??= 'grep -Irl -e ${RECIPE_SYSROOT} -e ${RECIPE_SYSROOT_NATIVE} -e ${HOSTTOOLS_DIR} ${SSTATE_BUILDDIR}'
Patrick Williamsc124f4f2015-09-15 14:41:29 -050048
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050049BB_HASHFILENAME = "False ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050050
51SSTATE_ARCHS = " \
52 ${BUILD_ARCH} \
53 ${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS} \
54 ${BUILD_ARCH}_${TARGET_ARCH} \
55 ${SDK_ARCH}_${SDK_OS} \
56 ${SDK_ARCH}_${PACKAGE_ARCH} \
57 allarch \
58 ${PACKAGE_ARCH} \
Brad Bishop316dfdd2018-06-25 12:45:53 -040059 ${PACKAGE_EXTRA_ARCHS} \
60 ${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050061
62SSTATE_MANMACH ?= "${SSTATE_PKGARCH}"
63
64SSTATECREATEFUNCS = "sstate_hardcode_path"
Brad Bishop19323692019-04-05 15:28:33 -040065SSTATECREATEFUNCS[vardeps] = "SSTATE_SCAN_FILES"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066SSTATEPOSTCREATEFUNCS = ""
67SSTATEPREINSTFUNCS = ""
68SSTATEPOSTUNPACKFUNCS = "sstate_hardcode_path_unpack"
69SSTATEPOSTINSTFUNCS = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -050070EXTRA_STAGING_FIXMES ?= "HOSTTOOLS_DIR"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050072# Check whether sstate exists for tasks that support sstate and are in the
73# locked signatures file.
74SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK ?= 'error'
75
76# Check whether the task's computed hash matches the task's hash in the
77# locked signatures file.
78SIGGEN_LOCKEDSIGS_TASKSIG_CHECK ?= "error"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050079
80# The GnuPG key ID and passphrase to use to sign sstate archives (or unset to
81# not sign)
82SSTATE_SIG_KEY ?= ""
83SSTATE_SIG_PASSPHRASE ?= ""
84# Whether to verify the GnUPG signatures when extracting sstate archives
85SSTATE_VERIFY_SIG ?= "0"
86
Brad Bishop19323692019-04-05 15:28:33 -040087SSTATE_HASHEQUIV_METHOD ?= "oe.sstatesig.OEOuthashBasic"
88SSTATE_HASHEQUIV_METHOD[doc] = "The fully-qualified function used to calculate \
89 the output hash for a task, which in turn is used to determine equivalency. \
90 "
91
92SSTATE_HASHEQUIV_SERVER ?= ""
93SSTATE_HASHEQUIV_SERVER[doc] = "The hash equivalence sever. For example, \
94 'http://192.168.0.1:5000'. Do not include a trailing slash \
95 "
96
97SSTATE_HASHEQUIV_REPORT_TASKDATA ?= "0"
98SSTATE_HASHEQUIV_REPORT_TASKDATA[doc] = "Report additional useful data to the \
99 hash equivalency server, such as PN, PV, taskname, etc. This information \
100 is very useful for developers looking at task data, but may leak sensitive \
101 data if the equivalence server is public. \
102 "
103
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104python () {
105 if bb.data.inherits_class('native', d):
106 d.setVar('SSTATE_PKGARCH', d.getVar('BUILD_ARCH', False))
107 elif bb.data.inherits_class('crosssdk', d):
108 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}"))
109 elif bb.data.inherits_class('cross', d):
110 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${TARGET_ARCH}"))
111 elif bb.data.inherits_class('nativesdk', d):
112 d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${SDK_OS}"))
113 elif bb.data.inherits_class('cross-canadian', d):
114 d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${PACKAGE_ARCH}"))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500115 elif bb.data.inherits_class('allarch', d) and d.getVar("PACKAGE_ARCH") == "all":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500116 d.setVar('SSTATE_PKGARCH', "allarch")
117 else:
118 d.setVar('SSTATE_MANMACH', d.expand("${PACKAGE_ARCH}"))
119
120 if bb.data.inherits_class('native', d) or bb.data.inherits_class('crosssdk', d) or bb.data.inherits_class('cross', d):
121 d.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500122 d.setVar('BB_HASHFILENAME', "True ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}")
Brad Bishop19323692019-04-05 15:28:33 -0400123 d.setVar('SSTATE_EXTRAPATHWILDCARD', "${NATIVELSBSTRING}/")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500125 unique_tasks = sorted(set((d.getVar('SSTATETASKS') or "").split()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500126 d.setVar('SSTATETASKS', " ".join(unique_tasks))
127 for task in unique_tasks:
128 d.prependVarFlag(task, 'prefuncs', "sstate_task_prefunc ")
129 d.appendVarFlag(task, 'postfuncs', " sstate_task_postfunc")
130}
131
132def sstate_init(task, d):
133 ss = {}
134 ss['task'] = task
135 ss['dirs'] = []
136 ss['plaindirs'] = []
137 ss['lockfiles'] = []
138 ss['lockfiles-shared'] = []
139 return ss
140
141def sstate_state_fromvars(d, task = None):
142 if task is None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500143 task = d.getVar('BB_CURRENTTASK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500144 if not task:
145 bb.fatal("sstate code running without task context?!")
146 task = task.replace("_setscene", "")
147
148 if task.startswith("do_"):
149 task = task[3:]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500150 inputs = (d.getVarFlag("do_" + task, 'sstate-inputdirs') or "").split()
151 outputs = (d.getVarFlag("do_" + task, 'sstate-outputdirs') or "").split()
152 plaindirs = (d.getVarFlag("do_" + task, 'sstate-plaindirs') or "").split()
153 lockfiles = (d.getVarFlag("do_" + task, 'sstate-lockfile') or "").split()
154 lockfilesshared = (d.getVarFlag("do_" + task, 'sstate-lockfile-shared') or "").split()
155 interceptfuncs = (d.getVarFlag("do_" + task, 'sstate-interceptfuncs') or "").split()
156 fixmedir = d.getVarFlag("do_" + task, 'sstate-fixmedir') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500157 if not task or len(inputs) != len(outputs):
158 bb.fatal("sstate variables not setup correctly?!")
159
160 if task == "populate_lic":
161 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
162 d.setVar("SSTATE_EXTRAPATH", "")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500163 d.setVar('SSTATE_EXTRAPATHWILDCARD', "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500164
165 ss = sstate_init(task, d)
166 for i in range(len(inputs)):
167 sstate_add(ss, inputs[i], outputs[i], d)
168 ss['lockfiles'] = lockfiles
169 ss['lockfiles-shared'] = lockfilesshared
170 ss['plaindirs'] = plaindirs
171 ss['interceptfuncs'] = interceptfuncs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500172 ss['fixmedir'] = fixmedir
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500173 return ss
174
175def sstate_add(ss, source, dest, d):
176 if not source.endswith("/"):
177 source = source + "/"
178 if not dest.endswith("/"):
179 dest = dest + "/"
180 source = os.path.normpath(source)
181 dest = os.path.normpath(dest)
182 srcbase = os.path.basename(source)
183 ss['dirs'].append([srcbase, source, dest])
184 return ss
185
186def sstate_install(ss, d):
187 import oe.path
188 import oe.sstatesig
189 import subprocess
190
191 sharedfiles = []
192 shareddirs = []
193 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
194
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500195 sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
196
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500197 manifest, d2 = oe.sstatesig.sstate_get_manifest_filename(ss['task'], d)
198
199 if os.access(manifest, os.R_OK):
200 bb.fatal("Package already staged (%s)?!" % manifest)
201
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600202 d.setVar("SSTATE_INST_POSTRM", manifest + ".postrm")
203
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500204 locks = []
205 for lock in ss['lockfiles-shared']:
206 locks.append(bb.utils.lockfile(lock, True))
207 for lock in ss['lockfiles']:
208 locks.append(bb.utils.lockfile(lock))
209
210 for state in ss['dirs']:
211 bb.debug(2, "Staging files from %s to %s" % (state[1], state[2]))
212 for walkroot, dirs, files in os.walk(state[1]):
213 for file in files:
214 srcpath = os.path.join(walkroot, file)
215 dstpath = srcpath.replace(state[1], state[2])
216 #bb.debug(2, "Staging %s to %s" % (srcpath, dstpath))
217 sharedfiles.append(dstpath)
218 for dir in dirs:
219 srcdir = os.path.join(walkroot, dir)
220 dstdir = srcdir.replace(state[1], state[2])
221 #bb.debug(2, "Staging %s to %s" % (srcdir, dstdir))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500222 if os.path.islink(srcdir):
223 sharedfiles.append(dstdir)
224 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500225 if not dstdir.endswith("/"):
226 dstdir = dstdir + "/"
227 shareddirs.append(dstdir)
228
229 # Check the file list for conflicts against files which already exist
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500230 whitelist = (d.getVar("SSTATE_DUPWHITELIST") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500231 match = []
232 for f in sharedfiles:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500233 if os.path.exists(f) and not os.path.islink(f):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500234 f = os.path.normpath(f)
235 realmatch = True
236 for w in whitelist:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600237 w = os.path.normpath(w)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238 if f.startswith(w):
239 realmatch = False
240 break
241 if realmatch:
242 match.append(f)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500243 sstate_search_cmd = "grep -rlF '%s' %s --exclude=master.list | sed -e 's:^.*/::'" % (f, d.expand("${SSTATE_MANIFESTS}"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500244 search_output = subprocess.Popen(sstate_search_cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500245 if search_output:
246 match.append(" (matched in %s)" % search_output.decode('utf-8').rstrip())
247 else:
248 match.append(" (not matched to any task)")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500249 if match:
250 bb.error("The recipe %s is trying to install files into a shared " \
251 "area when those files already exist. Those files and their manifest " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500252 "location are:\n %s\nPlease verify which recipe should provide the " \
253 "above files.\n\nThe build has stopped, as continuing in this scenario WILL " \
254 "break things - if not now, possibly in the future (we've seen builds fail " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500255 "several months later). If the system knew how to recover from this " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500256 "automatically it would, however there are several different scenarios " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500257 "which can result in this and we don't know which one this is. It may be " \
258 "you have switched providers of something like virtual/kernel (e.g. from " \
259 "linux-yocto to linux-yocto-dev), in that case you need to execute the " \
260 "clean task for both recipes and it will resolve this error. It may be " \
261 "you changed DISTRO_FEATURES from systemd to udev or vice versa. Cleaning " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500262 "those recipes should again resolve this error, however switching " \
263 "DISTRO_FEATURES on an existing build directory is not supported - you " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500264 "should really clean out tmp and rebuild (reusing sstate should be safe). " \
265 "It could be the overlapping files detected are harmless in which case " \
266 "adding them to SSTATE_DUPWHITELIST may be the correct solution. It could " \
267 "also be your build is including two different conflicting versions of " \
268 "things (e.g. bluez 4 and bluez 5 and the correct solution for that would " \
269 "be to resolve the conflict. If in doubt, please ask on the mailing list, " \
270 "sharing the error and filelist above." % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500271 (d.getVar('PN'), "\n ".join(match)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500272 bb.fatal("If the above message is too much, the simpler version is you're advised to wipe out tmp and rebuild (reusing sstate is fine). That will likely fix things in most (but not all) cases.")
273
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500274 if ss['fixmedir'] and os.path.exists(ss['fixmedir'] + "/fixmepath.cmd"):
275 sharedfiles.append(ss['fixmedir'] + "/fixmepath.cmd")
276 sharedfiles.append(ss['fixmedir'] + "/fixmepath")
277
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500278 # Write out the manifest
279 f = open(manifest, "w")
280 for file in sharedfiles:
281 f.write(file + "\n")
282
283 # We want to ensure that directories appear at the end of the manifest
284 # so that when we test to see if they should be deleted any contents
285 # added by the task will have been removed first.
286 dirs = sorted(shareddirs, key=len)
287 # Must remove children first, which will have a longer path than the parent
288 for di in reversed(dirs):
289 f.write(di + "\n")
290 f.close()
291
292 # Append to the list of manifests for this PACKAGE_ARCH
293
294 i = d2.expand("${SSTATE_MANIFESTS}/index-${SSTATE_MANMACH}")
295 l = bb.utils.lockfile(i + ".lock")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500296 filedata = d.getVar("STAMP") + " " + d2.getVar("SSTATE_MANFILEPREFIX") + " " + d.getVar("WORKDIR") + "\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500297 manifests = []
298 if os.path.exists(i):
299 with open(i, "r") as f:
300 manifests = f.readlines()
301 if filedata not in manifests:
302 with open(i, "a+") as f:
303 f.write(filedata)
304 bb.utils.unlockfile(l)
305
306 # Run the actual file install
307 for state in ss['dirs']:
308 if os.path.exists(state[1]):
309 oe.path.copyhardlinktree(state[1], state[2])
310
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500311 for postinst in (d.getVar('SSTATEPOSTINSTFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500312 # All hooks should run in the SSTATE_INSTDIR
313 bb.build.exec_func(postinst, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500314
315 for lock in locks:
316 bb.utils.unlockfile(lock)
317
318sstate_install[vardepsexclude] += "SSTATE_DUPWHITELIST STATE_MANMACH SSTATE_MANFILEPREFIX"
319sstate_install[vardeps] += "${SSTATEPOSTINSTFUNCS}"
320
321def sstate_installpkg(ss, d):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500322 from oe.gpg_sign import get_signer
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500323
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500324 sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500325 sstatefetch = d.getVar('SSTATE_PKGNAME') + '_' + ss['task'] + ".tgz"
326 sstatepkg = d.getVar('SSTATE_PKG') + '_' + ss['task'] + ".tgz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500327
328 if not os.path.exists(sstatepkg):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800329 pstaging_fetch(sstatefetch, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500330
331 if not os.path.isfile(sstatepkg):
Brad Bishop08902b02019-08-20 09:16:51 -0400332 bb.note("Sstate package %s does not exist" % sstatepkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500333 return False
334
335 sstate_clean(ss, d)
336
337 d.setVar('SSTATE_INSTDIR', sstateinst)
338 d.setVar('SSTATE_PKG', sstatepkg)
339
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500340 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500341 signer = get_signer(d, 'local')
342 if not signer.verify(sstatepkg + '.sig'):
Brad Bishop08902b02019-08-20 09:16:51 -0400343 bb.warn("Cannot verify signature on sstate package %s, skipping acceleration..." % sstatepkg)
344 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500345
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500346 # Empty sstateinst directory, ensure its clean
347 if os.path.exists(sstateinst):
348 oe.path.remove(sstateinst)
349 bb.utils.mkdirhier(sstateinst)
350
351 sstateinst = d.getVar("SSTATE_INSTDIR")
352 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
353
354 for f in (d.getVar('SSTATEPREINSTFUNCS') or '').split() + ['sstate_unpack_package']:
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500355 # All hooks should run in the SSTATE_INSTDIR
356 bb.build.exec_func(f, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500357
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500358 return sstate_installpkgdir(ss, d)
359
360def sstate_installpkgdir(ss, d):
361 import oe.path
362 import subprocess
363
364 sstateinst = d.getVar("SSTATE_INSTDIR")
365 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
366
367 for f in (d.getVar('SSTATEPOSTUNPACKFUNCS') or '').split():
368 # All hooks should run in the SSTATE_INSTDIR
369 bb.build.exec_func(f, d, (sstateinst,))
370
371 def prepdir(dir):
372 # remove dir if it exists, ensure any parent directories do exist
373 if os.path.exists(dir):
374 oe.path.remove(dir)
375 bb.utils.mkdirhier(dir)
376 oe.path.remove(dir)
377
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500378 for state in ss['dirs']:
379 prepdir(state[1])
380 os.rename(sstateinst + state[0], state[1])
381 sstate_install(ss, d)
382
383 for plain in ss['plaindirs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500384 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500385 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500386 src = sstateinst + "/" + plain.replace(workdir, '')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500387 if sharedworkdir in plain:
388 src = sstateinst + "/" + plain.replace(sharedworkdir, '')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500389 dest = plain
390 bb.utils.mkdirhier(src)
391 prepdir(dest)
392 os.rename(src, dest)
393
394 return True
395
396python sstate_hardcode_path_unpack () {
397 # Fixup hardcoded paths
398 #
399 # Note: The logic below must match the reverse logic in
400 # sstate_hardcode_path(d)
401 import subprocess
402
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500403 sstateinst = d.getVar('SSTATE_INSTDIR')
404 sstatefixmedir = d.getVar('SSTATE_FIXMEDIR')
405 fixmefn = sstateinst + "fixmepath"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406 if os.path.isfile(fixmefn):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500407 staging_target = d.getVar('RECIPE_SYSROOT')
408 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500409
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500410 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500411 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRHOST:%s:g'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500412 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
413 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (staging_target, staging_host)
414 else:
415 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g'" % (staging_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500416
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500417 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500418 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500419 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500420 sstate_sed_cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
421
422 # Add sstateinst to each filename in fixmepath, use xargs to efficiently call sed
423 sstate_hardcode_cmd = "sed -e 's:^:%s:g' %s | xargs %s" % (sstateinst, fixmefn, sstate_sed_cmd)
424
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500425 # Defer do_populate_sysroot relocation command
426 if sstatefixmedir:
427 bb.utils.mkdirhier(sstatefixmedir)
428 with open(sstatefixmedir + "/fixmepath.cmd", "w") as f:
429 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(fixmefn, sstatefixmedir + "/fixmepath")
430 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(sstateinst, "FIXMEFINALSSTATEINST")
431 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_host, "FIXMEFINALSSTATEHOST")
432 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_target, "FIXMEFINALSSTATETARGET")
433 f.write(sstate_hardcode_cmd)
434 bb.utils.copyfile(fixmefn, sstatefixmedir + "/fixmepath")
435 return
436
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500437 bb.note("Replacing fixme paths in sstate package: %s" % (sstate_hardcode_cmd))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500438 subprocess.check_call(sstate_hardcode_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500439
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800440 # Need to remove this or we'd copy it into the target directory and may
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500441 # conflict with another writer
442 os.remove(fixmefn)
443}
444
445def sstate_clean_cachefile(ss, d):
446 import oe.path
447
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500448 sstatepkgfile = d.getVar('SSTATE_PATHSPEC') + "*_" + ss['task'] + ".tgz*"
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300449 if d.getVarFlag('do_%s' % ss['task'], 'task'):
450 bb.note("Removing %s" % sstatepkgfile)
451 oe.path.remove(sstatepkgfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500452
453def sstate_clean_cachefiles(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500454 for task in (d.getVar('SSTATETASKS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500455 ld = d.createCopy()
456 ss = sstate_state_fromvars(ld, task)
457 sstate_clean_cachefile(ss, ld)
458
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500459def sstate_clean_manifest(manifest, d, prefix=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500460 import oe.path
461
462 mfile = open(manifest)
463 entries = mfile.readlines()
464 mfile.close()
465
466 for entry in entries:
467 entry = entry.strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500468 if prefix and not entry.startswith("/"):
469 entry = prefix + "/" + entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500470 bb.debug(2, "Removing manifest: %s" % entry)
471 # We can race against another package populating directories as we're removing them
472 # so we ignore errors here.
473 try:
474 if entry.endswith("/"):
475 if os.path.islink(entry[:-1]):
476 os.remove(entry[:-1])
477 elif os.path.exists(entry) and len(os.listdir(entry)) == 0:
478 os.rmdir(entry[:-1])
479 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500480 os.remove(entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500481 except OSError:
482 pass
483
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600484 postrm = manifest + ".postrm"
485 if os.path.exists(manifest + ".postrm"):
486 import subprocess
487 os.chmod(postrm, 0o755)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500488 subprocess.check_call(postrm, shell=True)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600489 oe.path.remove(postrm)
490
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500491 oe.path.remove(manifest)
492
493def sstate_clean(ss, d):
494 import oe.path
495 import glob
496
497 d2 = d.createCopy()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500498 stamp_clean = d.getVar("STAMPCLEAN")
499 extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500500 if extrainf:
501 d2.setVar("SSTATE_MANMACH", extrainf)
502 wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
503 else:
504 wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
505
506 manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
507
508 if os.path.exists(manifest):
509 locks = []
510 for lock in ss['lockfiles-shared']:
511 locks.append(bb.utils.lockfile(lock))
512 for lock in ss['lockfiles']:
513 locks.append(bb.utils.lockfile(lock))
514
515 sstate_clean_manifest(manifest, d)
516
517 for lock in locks:
518 bb.utils.unlockfile(lock)
519
520 # Remove the current and previous stamps, but keep the sigdata.
521 #
522 # The glob() matches do_task* which may match multiple tasks, for
523 # example: do_package and do_package_write_ipk, so we need to
524 # exactly match *.do_task.* and *.do_task_setscene.*
525 rm_stamp = '.do_%s.' % ss['task']
526 rm_setscene = '.do_%s_setscene.' % ss['task']
527 # For BB_SIGNATURE_HANDLER = "noop"
528 rm_nohash = ".do_%s" % ss['task']
529 for stfile in glob.glob(wildcard_stfile):
530 # Keep the sigdata
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500531 if ".sigdata." in stfile or ".sigbasedata." in stfile:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500532 continue
533 # Preserve taint files in the stamps directory
534 if stfile.endswith('.taint'):
535 continue
536 if rm_stamp in stfile or rm_setscene in stfile or \
537 stfile.endswith(rm_nohash):
538 oe.path.remove(stfile)
539
540sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
541
542CLEANFUNCS += "sstate_cleanall"
543
544python sstate_cleanall() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500545 bb.note("Removing shared state for package %s" % d.getVar('PN'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500546
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500547 manifest_dir = d.getVar('SSTATE_MANIFESTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500548 if not os.path.exists(manifest_dir):
549 return
550
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500551 tasks = d.getVar('SSTATETASKS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500552 for name in tasks:
553 ld = d.createCopy()
554 shared_state = sstate_state_fromvars(ld, name)
555 sstate_clean(shared_state, ld)
556}
557
558python sstate_hardcode_path () {
559 import subprocess, platform
560
561 # Need to remove hardcoded paths and fix these when we install the
562 # staging packages.
563 #
564 # Note: the logic in this function needs to match the reverse logic
565 # in sstate_installpkg(ss, d)
566
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500567 staging_target = d.getVar('RECIPE_SYSROOT')
568 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
569 sstate_builddir = d.getVar('SSTATE_BUILDDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500570
Brad Bishop316dfdd2018-06-25 12:45:53 -0400571 sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500572 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500573 sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500574 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
575 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400576 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500577 else:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400578 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
579 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500580
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500581 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500582 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500583 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500584 sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500585 sstate_grep_cmd += " -e '%s'" % (fixme_path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500586
587 fixmefn = sstate_builddir + "fixmepath"
588
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500589 sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500590 sstate_filelist_cmd = "tee %s" % (fixmefn)
591
592 # fixmepath file needs relative paths, drop sstate_builddir prefix
593 sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
594
595 xargs_no_empty_run_cmd = '--no-run-if-empty'
596 if platform.system() == 'Darwin':
597 xargs_no_empty_run_cmd = ''
598
599 # Limit the fixpaths and sed operations based on the initial grep search
600 # This has the side effect of making sure the vfs cache is hot
601 sstate_hardcode_cmd = "%s | xargs %s | %s | xargs %s %s" % (sstate_scan_cmd, sstate_grep_cmd, sstate_filelist_cmd, xargs_no_empty_run_cmd, sstate_sed_cmd)
602
603 bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500604 subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500605
606 # If the fixmefn is empty, remove it..
607 if os.stat(fixmefn).st_size == 0:
608 os.remove(fixmefn)
609 else:
610 bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500611 subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500612}
613
614def sstate_package(ss, d):
615 import oe.path
616
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500617 tmpdir = d.getVar('TMPDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500618
619 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500620 sstatepkg = d.getVar('SSTATE_PKG') + '_'+ ss['task'] + ".tgz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500621 bb.utils.remove(sstatebuild, recurse=True)
622 bb.utils.mkdirhier(sstatebuild)
623 bb.utils.mkdirhier(os.path.dirname(sstatepkg))
624 for state in ss['dirs']:
625 if not os.path.exists(state[1]):
626 continue
627 srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500628 # Find and error for absolute symlinks. We could attempt to relocate but its not
629 # clear where the symlink is relative to in this context. We could add that markup
630 # to sstate tasks but there aren't many of these so better just avoid them entirely.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500631 for walkroot, dirs, files in os.walk(state[1]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500632 for file in files + dirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500633 srcpath = os.path.join(walkroot, file)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500634 if not os.path.islink(srcpath):
635 continue
636 link = os.readlink(srcpath)
637 if not os.path.isabs(link):
638 continue
639 if not link.startswith(tmpdir):
640 continue
641 bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500642 bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500643 os.rename(state[1], sstatebuild + state[0])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500644
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500645 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500646 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500647 for plain in ss['plaindirs']:
648 pdir = plain.replace(workdir, sstatebuild)
Brad Bishop977dc1a2019-02-06 16:01:43 -0500649 if sharedworkdir in plain:
650 pdir = plain.replace(sharedworkdir, sstatebuild)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500651 bb.utils.mkdirhier(plain)
652 bb.utils.mkdirhier(pdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500653 os.rename(plain, pdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500654
655 d.setVar('SSTATE_BUILDDIR', sstatebuild)
656 d.setVar('SSTATE_PKG', sstatepkg)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500657 d.setVar('SSTATE_INSTDIR', sstatebuild)
658
659 if d.getVar('SSTATE_SKIP_CREATION') == '1':
660 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500661
Brad Bishop08902b02019-08-20 09:16:51 -0400662 sstate_create_package = ['sstate_report_unihash', 'sstate_create_package']
663 if d.getVar('SSTATE_SIG_KEY'):
664 sstate_create_package.append('sstate_sign_package')
665
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500666 for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
Brad Bishop08902b02019-08-20 09:16:51 -0400667 sstate_create_package + \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500668 (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500669 # All hooks should run in SSTATE_BUILDDIR.
670 bb.build.exec_func(f, d, (sstatebuild,))
671
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500672 bb.siggen.dump_this_task(sstatepkg + ".siginfo", d)
673
674 return
675
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800676def pstaging_fetch(sstatefetch, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500677 import bb.fetch2
678
679 # Only try and fetch if the user has configured a mirror
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500680 mirrors = d.getVar('SSTATE_MIRRORS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500681 if not mirrors:
682 return
683
684 # Copy the data object and override DL_DIR and SRC_URI
685 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500686
687 dldir = localdata.expand("${SSTATE_DIR}")
688 bb.utils.mkdirhier(dldir)
689
690 localdata.delVar('MIRRORS')
691 localdata.setVar('FILESPATH', dldir)
692 localdata.setVar('DL_DIR', dldir)
693 localdata.setVar('PREMIRRORS', mirrors)
694
695 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
696 # we'll want to allow network access for the current set of fetches.
Brad Bishopd89cb5f2019-04-10 09:02:41 -0400697 if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
698 bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500699 localdata.delVar('BB_NO_NETWORK')
700
701 # Try a fetch from the sstate mirror, if it fails just return and
702 # we will build the package
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600703 uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
704 'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500705 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600706 uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500707
708 for srcuri in uris:
709 localdata.setVar('SRC_URI', srcuri)
710 try:
711 fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
712 fetcher.download()
713
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500714 except bb.fetch2.BBFetchException:
715 break
716
717def sstate_setscene(d):
718 shared_state = sstate_state_fromvars(d)
719 accelerate = sstate_installpkg(shared_state, d)
720 if not accelerate:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600721 bb.fatal("No suitable staging package found")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500722
723python sstate_task_prefunc () {
724 shared_state = sstate_state_fromvars(d)
725 sstate_clean(shared_state, d)
726}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500727sstate_task_prefunc[dirs] = "${WORKDIR}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500728
729python sstate_task_postfunc () {
730 shared_state = sstate_state_fromvars(d)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500731
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500732 for intercept in shared_state['interceptfuncs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500733 bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
734
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600735 omask = os.umask(0o002)
736 if omask != 0o002:
737 bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500738 sstate_package(shared_state, d)
739 os.umask(omask)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500740
741 sstateinst = d.getVar("SSTATE_INSTDIR")
742 d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
743
744 sstate_installpkgdir(shared_state, d)
745
746 bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500747}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500748sstate_task_postfunc[dirs] = "${WORKDIR}"
749
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750
751#
752# Shell function to generate a sstate package from a directory
753# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
754#
755sstate_create_package () {
756 TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800757
Brad Bishop08902b02019-08-20 09:16:51 -0400758 # Exit earlu if it already exists
759 if [ -e ${SSTATE_PKG} ]; then
760 return
761 fi
762
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800763 # Use pigz if available
764 OPT="-czS"
765 if [ -x "$(command -v pigz)" ]; then
766 OPT="-I pigz -cS"
767 fi
768
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500769 # Need to handle empty directories
770 if [ "$(ls -A)" ]; then
771 set +e
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800772 tar $OPT -f $TFILE *
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500773 ret=$?
774 if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
775 exit 1
776 fi
777 set -e
778 else
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800779 tar $OPT --file=$TFILE --files-from=/dev/null
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500780 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500781 chmod 0664 $TFILE
Brad Bishop08902b02019-08-20 09:16:51 -0400782 # Skip if it was already created by some other process
783 if [ ! -e ${SSTATE_PKG} ]; then
784 mv -f $TFILE ${SSTATE_PKG}
785 else
786 rm $TFILE
787 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500788}
789
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500790python sstate_sign_package () {
791 from oe.gpg_sign import get_signer
792
Brad Bishop08902b02019-08-20 09:16:51 -0400793
794 signer = get_signer(d, 'local')
795 sstate_pkg = d.getVar('SSTATE_PKG')
796 if os.path.exists(sstate_pkg + '.sig'):
797 os.unlink(sstate_pkg + '.sig')
798 signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
799 d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500800}
801
Brad Bishop19323692019-04-05 15:28:33 -0400802python sstate_report_unihash() {
803 report_unihash = getattr(bb.parse.siggen, 'report_unihash', None)
804
805 if report_unihash:
806 ss = sstate_state_fromvars(d)
807 report_unihash(os.getcwd(), ss['task'], d)
808}
809
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500810#
811# Shell function to decompress and prepare a package for installation
812# Will be run from within SSTATE_INSTDIR.
813#
814sstate_unpack_package () {
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500815 tar -xvzf ${SSTATE_PKG}
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500816 # update .siginfo atime on local/NFS mirror
817 [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500818 # Use "! -w ||" to return true for read only files
819 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500820 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig
821 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500822}
823
824BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
825
Brad Bishop08902b02019-08-20 09:16:51 -0400826def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, **kwargs):
827 found = set()
828 missed = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500829 extension = ".tgz"
830 if siginfo:
831 extension = extension + ".siginfo"
832
Brad Bishop19323692019-04-05 15:28:33 -0400833 def gethash(task):
Brad Bishop08902b02019-08-20 09:16:51 -0400834 return sq_data['unihash'][task]
Brad Bishop19323692019-04-05 15:28:33 -0400835
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500836 def getpathcomponents(task, d):
837 # Magic data from BB_HASHFILENAME
Brad Bishop08902b02019-08-20 09:16:51 -0400838 splithashfn = sq_data['hashfn'][task].split(" ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500839 spec = splithashfn[1]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500840 if splithashfn[0] == "True":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500841 extrapath = d.getVar("NATIVELSBSTRING") + "/"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500842 else:
843 extrapath = ""
Brad Bishop08902b02019-08-20 09:16:51 -0400844
845 tname = bb.runqueue.taskname_from_tid(task)[3:]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500846
847 if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
848 spec = splithashfn[2]
849 extrapath = ""
850
851 return spec, extrapath, tname
852
853
Brad Bishop08902b02019-08-20 09:16:51 -0400854 for tid in sq_data['hash']:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500855
Brad Bishop08902b02019-08-20 09:16:51 -0400856 spec, extrapath, tname = getpathcomponents(tid, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500857
Brad Bishop08902b02019-08-20 09:16:51 -0400858 sstatefile = d.expand("${SSTATE_DIR}/" + extrapath + generate_sstatefn(spec, gethash(tid), d) + "_" + tname + extension)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500859
860 if os.path.exists(sstatefile):
861 bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
Brad Bishop08902b02019-08-20 09:16:51 -0400862 found.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500863 continue
864 else:
Brad Bishop08902b02019-08-20 09:16:51 -0400865 missed.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500866 bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
867
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500868 mirrors = d.getVar("SSTATE_MIRRORS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 if mirrors:
870 # Copy the data object and override DL_DIR and SRC_URI
871 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500872
873 dldir = localdata.expand("${SSTATE_DIR}")
874 localdata.delVar('MIRRORS')
875 localdata.setVar('FILESPATH', dldir)
876 localdata.setVar('DL_DIR', dldir)
877 localdata.setVar('PREMIRRORS', mirrors)
878
879 bb.debug(2, "SState using premirror of: %s" % mirrors)
880
881 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
882 # we'll want to allow network access for the current set of fetches.
Brad Bishopd89cb5f2019-04-10 09:02:41 -0400883 if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
884 bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500885 localdata.delVar('BB_NO_NETWORK')
886
887 from bb.fetch2 import FetchConnectionCache
888 def checkstatus_init(thread_worker):
889 thread_worker.connection_cache = FetchConnectionCache()
890
891 def checkstatus_end(thread_worker):
892 thread_worker.connection_cache.close_connections()
893
894 def checkstatus(thread_worker, arg):
Brad Bishop08902b02019-08-20 09:16:51 -0400895 (tid, sstatefile) = arg
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500896
897 localdata2 = bb.data.createCopy(localdata)
898 srcuri = "file://" + sstatefile
899 localdata.setVar('SRC_URI', srcuri)
900 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
901
902 try:
903 fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
904 connection_cache=thread_worker.connection_cache)
905 fetcher.checkstatus()
906 bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
Brad Bishop08902b02019-08-20 09:16:51 -0400907 found.add(tid)
908 if tid in missed:
909 missed.remove(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500910 except:
Brad Bishop08902b02019-08-20 09:16:51 -0400911 missed.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500912 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600913 pass
Brad Bishop316dfdd2018-06-25 12:45:53 -0400914 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500915
916 tasklist = []
Brad Bishop08902b02019-08-20 09:16:51 -0400917 for tid in sq_data['hash']:
918 if tid in found:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500919 continue
Brad Bishop08902b02019-08-20 09:16:51 -0400920 spec, extrapath, tname = getpathcomponents(tid, d)
921 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), d) + "_" + tname + extension)
922 tasklist.append((tid, sstatefile))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500923
924 if tasklist:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400925 msg = "Checking sstate mirror object availability"
926 bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600927
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500928 import multiprocessing
929 nproc = min(multiprocessing.cpu_count(), len(tasklist))
930
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600931 bb.event.enable_threadlock()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500932 pool = oe.utils.ThreadedPool(nproc, len(tasklist),
933 worker_init=checkstatus_init, worker_end=checkstatus_end)
934 for t in tasklist:
935 pool.add_task(checkstatus, t)
936 pool.start()
937 pool.wait_completion()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600938 bb.event.disable_threadlock()
939
Brad Bishop316dfdd2018-06-25 12:45:53 -0400940 bb.event.fire(bb.event.ProcessFinished(msg), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500941
Brad Bishop96ff1982019-08-19 13:50:42 -0400942 # Likely checking an individual task hash again for multiconfig sharing of sstate tasks so skip reporting
Brad Bishop08902b02019-08-20 09:16:51 -0400943 if len(sq_data['hash']) == 1:
944 return found
Brad Bishop96ff1982019-08-19 13:50:42 -0400945
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500946 inheritlist = d.getVar("INHERIT")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500947 if "toaster" in inheritlist:
948 evdata = {'missed': [], 'found': []};
Brad Bishop08902b02019-08-20 09:16:51 -0400949 for tid in missed:
950 spec, extrapath, tname = getpathcomponents(tid, d)
951 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), d) + "_" + tname + ".tgz")
952 evdata['missed'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
953 for tid in found:
954 spec, extrapath, tname = getpathcomponents(tid, d)
955 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), d) + "_" + tname + ".tgz")
956 evdata['found'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500957 bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
958
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800959 # Print some summary statistics about the current task completion and how much sstate
960 # reuse there was. Avoid divide by zero errors.
Brad Bishop08902b02019-08-20 09:16:51 -0400961 total = len(sq_data['hash'])
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800962 complete = 0
963 if currentcount:
Brad Bishop08902b02019-08-20 09:16:51 -0400964 complete = (len(found) + currentcount) / (total + currentcount) * 100
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800965 match = 0
966 if total:
Brad Bishop08902b02019-08-20 09:16:51 -0400967 match = len(found) / total * 100
968 bb.plain("Sstate summary: Wanted %d Found %d Missed %d Current %d (%d%% match, %d%% complete)" % (total, len(found), len(missed), currentcount, match, complete))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800969
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500970 if hasattr(bb.parse.siggen, "checkhashes"):
Brad Bishop08902b02019-08-20 09:16:51 -0400971 bb.parse.siggen.checkhashes(sq_data, missed, found, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500972
Brad Bishop08902b02019-08-20 09:16:51 -0400973 return found
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500974
975BB_SETSCENE_DEPVALID = "setscene_depvalid"
976
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500977def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500978 # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
979 # task is included in taskdependees too
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500980 # Return - False - We need this dependency
981 # - True - We can skip this dependency
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800982 import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500983
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500984 def logit(msg, log):
985 if log is not None:
986 log.append(msg)
987 else:
988 bb.debug(2, msg)
989
990 logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500991
992 def isNativeCross(x):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500993 return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500994
995 # We only need to trigger populate_lic through direct dependencies
996 if taskdependees[task][1] == "do_populate_lic":
997 return True
998
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500999 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
1000 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
1001 return True
1002
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001003 # We only need to trigger packagedata through direct dependencies
1004 # but need to preserve packagedata on packagedata links
1005 if taskdependees[task][1] == "do_packagedata":
1006 for dep in taskdependees:
1007 if taskdependees[dep][1] == "do_packagedata":
1008 return False
1009 return True
1010
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001011 for dep in taskdependees:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001012 logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001013 if task == dep:
1014 continue
1015 if dep in notneeded:
1016 continue
1017 # do_package_write_* and do_package doesn't need do_package
1018 if taskdependees[task][1] == "do_package" and taskdependees[dep][1] in ['do_package', 'do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm', 'do_packagedata', 'do_package_qa']:
1019 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001020 # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
1021 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
1022 return False
1023 # do_package/packagedata/package_qa don't need do_populate_sysroot
1024 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package', 'do_packagedata', 'do_package_qa']:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001025 continue
1026 # Native/Cross packages don't exist and are noexec anyway
1027 if isNativeCross(taskdependees[dep][0]) and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm', 'do_packagedata', 'do_package', 'do_package_qa']:
1028 continue
1029
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001030 # This is due to the [depends] in useradd.bbclass complicating matters
1031 # The logic *is* reversed here due to the way hard setscene dependencies are injected
1032 if (taskdependees[task][1] == 'do_package' or taskdependees[task][1] == 'do_populate_sysroot') and taskdependees[dep][0].endswith(('shadow-native', 'shadow-sysroot', 'base-passwd', 'pseudo-native')) and taskdependees[dep][1] == 'do_populate_sysroot':
1033 continue
1034
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001035 # Consider sysroot depending on sysroot tasks
1036 if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001037 # Allow excluding certain recursive dependencies. If a recipe needs it should add a
1038 # specific dependency itself, rather than relying on one of its dependees to pull
1039 # them in.
1040 # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
1041 not_needed = False
1042 excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
1043 if excludedeps is None:
1044 # Cache the regular expressions for speed
1045 excludedeps = []
1046 for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
1047 excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
1048 d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
1049 for excl in excludedeps:
1050 if excl[0].match(taskdependees[dep][0]):
1051 if excl[1].match(taskdependees[task][0]):
1052 not_needed = True
1053 break
1054 if not_needed:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001055 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001056 # For meta-extsdk-toolchain we want all sysroot dependencies
1057 if taskdependees[dep][0] == 'meta-extsdk-toolchain':
1058 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001059 # Native/Cross populate_sysroot need their dependencies
1060 if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
1061 return False
1062 # Target populate_sysroot depended on by cross tools need to be installed
1063 if isNativeCross(taskdependees[dep][0]):
1064 return False
1065 # Native/cross tools depended upon by target sysroot are not needed
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001066 # Add an exception for shadow-native as required by useradd.bbclass
1067 if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001068 continue
1069 # Target populate_sysroot need their dependencies
1070 return False
1071
1072 if taskdependees[task][1] == 'do_shared_workdir':
1073 continue
1074
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001075 if taskdependees[dep][1] == "do_populate_lic":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001076 continue
1077
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001078
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001079 # Safe fallthrough default
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001080 logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001081 return False
1082 return True
1083
1084addhandler sstate_eventhandler
1085sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
1086python sstate_eventhandler() {
1087 d = e.data
1088 # When we write an sstate package we rewrite the SSTATE_PKG
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001089 spkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001090 if not spkg.endswith(".tgz"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001091 taskname = d.getVar("BB_RUNTASK")[3:]
1092 spec = d.getVar('SSTATE_PKGSPEC')
1093 swspec = d.getVar('SSTATE_SWSPEC')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001094 if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
1095 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
1096 d.setVar("SSTATE_EXTRAPATH", "")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001097 sstatepkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001098 bb.siggen.dump_this_task(sstatepkg + '_' + taskname + ".tgz" ".siginfo", d)
1099}
1100
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001101SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001102
1103# Event handler which removes manifests and stamps file for
1104# recipes which are no longer reachable in a build where they
1105# once were.
1106# Also optionally removes the workdir of those tasks/recipes
1107#
1108addhandler sstate_eventhandler2
1109sstate_eventhandler2[eventmask] = "bb.event.ReachableStamps"
1110python sstate_eventhandler2() {
1111 import glob
1112 d = e.data
1113 stamps = e.stamps.values()
1114 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001115 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1116 preservestamps = []
1117 if os.path.exists(preservestampfile):
1118 with open(preservestampfile, 'r') as f:
1119 preservestamps = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001120 seen = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001121
1122 # The machine index contains all the stamps this machine has ever seen in this build directory.
1123 # We should only remove things which this machine once accessed but no longer does.
1124 machineindex = set()
1125 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
1126 mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
1127 if os.path.exists(mi):
1128 with open(mi, "r") as f:
1129 machineindex = set(line.strip() for line in f.readlines())
1130
Brad Bishop316dfdd2018-06-25 12:45:53 -04001131 for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001132 toremove = []
1133 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1134 if not os.path.exists(i):
1135 continue
1136 with open(i, "r") as f:
1137 lines = f.readlines()
1138 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001139 try:
1140 (stamp, manifest, workdir) = l.split()
1141 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
1142 toremove.append(l)
1143 if stamp not in seen:
1144 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
1145 seen.append(stamp)
1146 except ValueError:
1147 bb.fatal("Invalid line '%s' in sstate manifest '%s'" % (l, i))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001148
1149 if toremove:
Brad Bishop316dfdd2018-06-25 12:45:53 -04001150 msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
1151 bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001152
Brad Bishop316dfdd2018-06-25 12:45:53 -04001153 removed = 0
1154 for r in toremove:
1155 (stamp, manifest, workdir) = r.split()
1156 for m in glob.glob(manifest + ".*"):
1157 if m.endswith(".postrm"):
1158 continue
1159 sstate_clean_manifest(m, d)
1160 bb.utils.remove(stamp + "*")
1161 if removeworkdir:
1162 bb.utils.remove(workdir, recurse = True)
1163 lines.remove(r)
1164 removed = removed + 1
1165 bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
1166
1167 bb.event.fire(bb.event.ProcessFinished(msg), d)
1168
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001169 with open(i, "w") as f:
1170 for l in lines:
1171 f.write(l)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001172 machineindex |= set(stamps)
1173 with open(mi, "w") as f:
1174 for l in machineindex:
1175 f.write(l + "\n")
1176
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001177 if preservestamps:
1178 os.remove(preservestampfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001179}