blob: efb0096c70931ebfa96e08d4166b7c0abfcbcd27 [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 Bishop6e60e8b2018-02-01 10:27:11 -050014SSTATE_PKGNAME = "${SSTATE_EXTRAPATH}${@generate_sstatefn(d.getVar('SSTATE_PKGSPEC'), d.getVar('BB_TASKHASH'), 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] = ""
26
27# For multilib rpm the allarch packagegroup files can overwrite (in theory they're identical)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080028SSTATE_DUPWHITELIST = "${DEPLOY_DIR}/licenses/"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050029# Avoid docbook/sgml catalog warnings for now
30SSTATE_DUPWHITELIST += "${STAGING_ETCDIR_NATIVE}/sgml ${STAGING_DATADIR_NATIVE}/sgml"
Brad Bishop316dfdd2018-06-25 12:45:53 -040031# sdk-provides-dummy-nativesdk and nativesdk-buildtools-perl-dummy overlap for different SDKMACHINE
32SSTATE_DUPWHITELIST += "${DEPLOY_DIR_RPM}/sdk_provides_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/sdk-provides-dummy-nativesdk/"
33SSTATE_DUPWHITELIST += "${DEPLOY_DIR_RPM}/buildtools_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/buildtools-dummy-nativesdk/"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080034# target-sdk-provides-dummy overlaps that allarch is disabled when multilib is used
35SSTATE_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 -050036# Archive the sources for many architectures in one deploy folder
37SSTATE_DUPWHITELIST += "${DEPLOY_DIR_SRC}"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080038# ovmf/grub-efi/systemd-boot/intel-microcode multilib recipes can generate identical overlapping files
39SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/ovmf"
40SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/grub-efi"
41SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/systemd-boot"
42SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/microcode"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050043
Brad Bishop6e60e8b2018-02-01 10:27:11 -050044SSTATE_SCAN_FILES ?= "*.la *-config *_config postinst-*"
45SSTATE_SCAN_CMD ??= 'find ${SSTATE_BUILDDIR} \( -name "${@"\" -o -name \"".join(d.getVar("SSTATE_SCAN_FILES").split())}" \) -type f'
46SSTATE_SCAN_CMD_NATIVE ??= 'grep -Irl -e ${RECIPE_SYSROOT} -e ${RECIPE_SYSROOT_NATIVE} -e ${HOSTTOOLS_DIR} ${SSTATE_BUILDDIR}'
Patrick Williamsc124f4f2015-09-15 14:41:29 -050047
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050048BB_HASHFILENAME = "False ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050049
50SSTATE_ARCHS = " \
51 ${BUILD_ARCH} \
52 ${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS} \
53 ${BUILD_ARCH}_${TARGET_ARCH} \
54 ${SDK_ARCH}_${SDK_OS} \
55 ${SDK_ARCH}_${PACKAGE_ARCH} \
56 allarch \
57 ${PACKAGE_ARCH} \
Brad Bishop316dfdd2018-06-25 12:45:53 -040058 ${PACKAGE_EXTRA_ARCHS} \
59 ${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060
61SSTATE_MANMACH ?= "${SSTATE_PKGARCH}"
62
63SSTATECREATEFUNCS = "sstate_hardcode_path"
64SSTATEPOSTCREATEFUNCS = ""
65SSTATEPREINSTFUNCS = ""
66SSTATEPOSTUNPACKFUNCS = "sstate_hardcode_path_unpack"
67SSTATEPOSTINSTFUNCS = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -050068EXTRA_STAGING_FIXMES ?= "HOSTTOOLS_DIR"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050070# Check whether sstate exists for tasks that support sstate and are in the
71# locked signatures file.
72SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK ?= 'error'
73
74# Check whether the task's computed hash matches the task's hash in the
75# locked signatures file.
76SIGGEN_LOCKEDSIGS_TASKSIG_CHECK ?= "error"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077
78# The GnuPG key ID and passphrase to use to sign sstate archives (or unset to
79# not sign)
80SSTATE_SIG_KEY ?= ""
81SSTATE_SIG_PASSPHRASE ?= ""
82# Whether to verify the GnUPG signatures when extracting sstate archives
83SSTATE_VERIFY_SIG ?= "0"
84
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085python () {
86 if bb.data.inherits_class('native', d):
87 d.setVar('SSTATE_PKGARCH', d.getVar('BUILD_ARCH', False))
88 elif bb.data.inherits_class('crosssdk', d):
89 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}"))
90 elif bb.data.inherits_class('cross', d):
91 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${TARGET_ARCH}"))
92 elif bb.data.inherits_class('nativesdk', d):
93 d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${SDK_OS}"))
94 elif bb.data.inherits_class('cross-canadian', d):
95 d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${PACKAGE_ARCH}"))
Brad Bishop6e60e8b2018-02-01 10:27:11 -050096 elif bb.data.inherits_class('allarch', d) and d.getVar("PACKAGE_ARCH") == "all":
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 d.setVar('SSTATE_PKGARCH', "allarch")
98 else:
99 d.setVar('SSTATE_MANMACH', d.expand("${PACKAGE_ARCH}"))
100
101 if bb.data.inherits_class('native', d) or bb.data.inherits_class('crosssdk', d) or bb.data.inherits_class('cross', d):
102 d.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500103 d.setVar('BB_HASHFILENAME', "True ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104 d.setVar('SSTATE_EXTRAPATHWILDCARD', "*/")
105
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500106 unique_tasks = sorted(set((d.getVar('SSTATETASKS') or "").split()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500107 d.setVar('SSTATETASKS', " ".join(unique_tasks))
108 for task in unique_tasks:
109 d.prependVarFlag(task, 'prefuncs', "sstate_task_prefunc ")
110 d.appendVarFlag(task, 'postfuncs', " sstate_task_postfunc")
111}
112
113def sstate_init(task, d):
114 ss = {}
115 ss['task'] = task
116 ss['dirs'] = []
117 ss['plaindirs'] = []
118 ss['lockfiles'] = []
119 ss['lockfiles-shared'] = []
120 return ss
121
122def sstate_state_fromvars(d, task = None):
123 if task is None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500124 task = d.getVar('BB_CURRENTTASK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500125 if not task:
126 bb.fatal("sstate code running without task context?!")
127 task = task.replace("_setscene", "")
128
129 if task.startswith("do_"):
130 task = task[3:]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500131 inputs = (d.getVarFlag("do_" + task, 'sstate-inputdirs') or "").split()
132 outputs = (d.getVarFlag("do_" + task, 'sstate-outputdirs') or "").split()
133 plaindirs = (d.getVarFlag("do_" + task, 'sstate-plaindirs') or "").split()
134 lockfiles = (d.getVarFlag("do_" + task, 'sstate-lockfile') or "").split()
135 lockfilesshared = (d.getVarFlag("do_" + task, 'sstate-lockfile-shared') or "").split()
136 interceptfuncs = (d.getVarFlag("do_" + task, 'sstate-interceptfuncs') or "").split()
137 fixmedir = d.getVarFlag("do_" + task, 'sstate-fixmedir') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500138 if not task or len(inputs) != len(outputs):
139 bb.fatal("sstate variables not setup correctly?!")
140
141 if task == "populate_lic":
142 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
143 d.setVar("SSTATE_EXTRAPATH", "")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500144 d.setVar('SSTATE_EXTRAPATHWILDCARD', "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500145
146 ss = sstate_init(task, d)
147 for i in range(len(inputs)):
148 sstate_add(ss, inputs[i], outputs[i], d)
149 ss['lockfiles'] = lockfiles
150 ss['lockfiles-shared'] = lockfilesshared
151 ss['plaindirs'] = plaindirs
152 ss['interceptfuncs'] = interceptfuncs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500153 ss['fixmedir'] = fixmedir
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500154 return ss
155
156def sstate_add(ss, source, dest, d):
157 if not source.endswith("/"):
158 source = source + "/"
159 if not dest.endswith("/"):
160 dest = dest + "/"
161 source = os.path.normpath(source)
162 dest = os.path.normpath(dest)
163 srcbase = os.path.basename(source)
164 ss['dirs'].append([srcbase, source, dest])
165 return ss
166
167def sstate_install(ss, d):
168 import oe.path
169 import oe.sstatesig
170 import subprocess
171
172 sharedfiles = []
173 shareddirs = []
174 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
175
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500176 sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
177
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500178 manifest, d2 = oe.sstatesig.sstate_get_manifest_filename(ss['task'], d)
179
180 if os.access(manifest, os.R_OK):
181 bb.fatal("Package already staged (%s)?!" % manifest)
182
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600183 d.setVar("SSTATE_INST_POSTRM", manifest + ".postrm")
184
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500185 locks = []
186 for lock in ss['lockfiles-shared']:
187 locks.append(bb.utils.lockfile(lock, True))
188 for lock in ss['lockfiles']:
189 locks.append(bb.utils.lockfile(lock))
190
191 for state in ss['dirs']:
192 bb.debug(2, "Staging files from %s to %s" % (state[1], state[2]))
193 for walkroot, dirs, files in os.walk(state[1]):
194 for file in files:
195 srcpath = os.path.join(walkroot, file)
196 dstpath = srcpath.replace(state[1], state[2])
197 #bb.debug(2, "Staging %s to %s" % (srcpath, dstpath))
198 sharedfiles.append(dstpath)
199 for dir in dirs:
200 srcdir = os.path.join(walkroot, dir)
201 dstdir = srcdir.replace(state[1], state[2])
202 #bb.debug(2, "Staging %s to %s" % (srcdir, dstdir))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500203 if os.path.islink(srcdir):
204 sharedfiles.append(dstdir)
205 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500206 if not dstdir.endswith("/"):
207 dstdir = dstdir + "/"
208 shareddirs.append(dstdir)
209
210 # Check the file list for conflicts against files which already exist
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500211 whitelist = (d.getVar("SSTATE_DUPWHITELIST") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500212 match = []
213 for f in sharedfiles:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500214 if os.path.exists(f) and not os.path.islink(f):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500215 f = os.path.normpath(f)
216 realmatch = True
217 for w in whitelist:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600218 w = os.path.normpath(w)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500219 if f.startswith(w):
220 realmatch = False
221 break
222 if realmatch:
223 match.append(f)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500224 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 -0500225 search_output = subprocess.Popen(sstate_search_cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500226 if search_output:
227 match.append(" (matched in %s)" % search_output.decode('utf-8').rstrip())
228 else:
229 match.append(" (not matched to any task)")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500230 if match:
231 bb.error("The recipe %s is trying to install files into a shared " \
232 "area when those files already exist. Those files and their manifest " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500233 "location are:\n %s\nPlease verify which recipe should provide the " \
234 "above files.\n\nThe build has stopped, as continuing in this scenario WILL " \
235 "break things - if not now, possibly in the future (we've seen builds fail " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500236 "several months later). If the system knew how to recover from this " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500237 "automatically it would, however there are several different scenarios " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238 "which can result in this and we don't know which one this is. It may be " \
239 "you have switched providers of something like virtual/kernel (e.g. from " \
240 "linux-yocto to linux-yocto-dev), in that case you need to execute the " \
241 "clean task for both recipes and it will resolve this error. It may be " \
242 "you changed DISTRO_FEATURES from systemd to udev or vice versa. Cleaning " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500243 "those recipes should again resolve this error, however switching " \
244 "DISTRO_FEATURES on an existing build directory is not supported - you " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500245 "should really clean out tmp and rebuild (reusing sstate should be safe). " \
246 "It could be the overlapping files detected are harmless in which case " \
247 "adding them to SSTATE_DUPWHITELIST may be the correct solution. It could " \
248 "also be your build is including two different conflicting versions of " \
249 "things (e.g. bluez 4 and bluez 5 and the correct solution for that would " \
250 "be to resolve the conflict. If in doubt, please ask on the mailing list, " \
251 "sharing the error and filelist above." % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500252 (d.getVar('PN'), "\n ".join(match)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500253 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.")
254
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500255 if ss['fixmedir'] and os.path.exists(ss['fixmedir'] + "/fixmepath.cmd"):
256 sharedfiles.append(ss['fixmedir'] + "/fixmepath.cmd")
257 sharedfiles.append(ss['fixmedir'] + "/fixmepath")
258
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500259 # Write out the manifest
260 f = open(manifest, "w")
261 for file in sharedfiles:
262 f.write(file + "\n")
263
264 # We want to ensure that directories appear at the end of the manifest
265 # so that when we test to see if they should be deleted any contents
266 # added by the task will have been removed first.
267 dirs = sorted(shareddirs, key=len)
268 # Must remove children first, which will have a longer path than the parent
269 for di in reversed(dirs):
270 f.write(di + "\n")
271 f.close()
272
273 # Append to the list of manifests for this PACKAGE_ARCH
274
275 i = d2.expand("${SSTATE_MANIFESTS}/index-${SSTATE_MANMACH}")
276 l = bb.utils.lockfile(i + ".lock")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500277 filedata = d.getVar("STAMP") + " " + d2.getVar("SSTATE_MANFILEPREFIX") + " " + d.getVar("WORKDIR") + "\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500278 manifests = []
279 if os.path.exists(i):
280 with open(i, "r") as f:
281 manifests = f.readlines()
282 if filedata not in manifests:
283 with open(i, "a+") as f:
284 f.write(filedata)
285 bb.utils.unlockfile(l)
286
287 # Run the actual file install
288 for state in ss['dirs']:
289 if os.path.exists(state[1]):
290 oe.path.copyhardlinktree(state[1], state[2])
291
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500292 for postinst in (d.getVar('SSTATEPOSTINSTFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500293 # All hooks should run in the SSTATE_INSTDIR
294 bb.build.exec_func(postinst, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500295
296 for lock in locks:
297 bb.utils.unlockfile(lock)
298
299sstate_install[vardepsexclude] += "SSTATE_DUPWHITELIST STATE_MANMACH SSTATE_MANFILEPREFIX"
300sstate_install[vardeps] += "${SSTATEPOSTINSTFUNCS}"
301
302def sstate_installpkg(ss, d):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500303 from oe.gpg_sign import get_signer
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500305 sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500306 sstatefetch = d.getVar('SSTATE_PKGNAME') + '_' + ss['task'] + ".tgz"
307 sstatepkg = d.getVar('SSTATE_PKG') + '_' + ss['task'] + ".tgz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500308
309 if not os.path.exists(sstatepkg):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800310 pstaging_fetch(sstatefetch, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311
312 if not os.path.isfile(sstatepkg):
313 bb.note("Staging package %s does not exist" % sstatepkg)
314 return False
315
316 sstate_clean(ss, d)
317
318 d.setVar('SSTATE_INSTDIR', sstateinst)
319 d.setVar('SSTATE_PKG', sstatepkg)
320
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500321 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500322 signer = get_signer(d, 'local')
323 if not signer.verify(sstatepkg + '.sig'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500324 bb.warn("Cannot verify signature on sstate package %s" % sstatepkg)
325
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500326 # Empty sstateinst directory, ensure its clean
327 if os.path.exists(sstateinst):
328 oe.path.remove(sstateinst)
329 bb.utils.mkdirhier(sstateinst)
330
331 sstateinst = d.getVar("SSTATE_INSTDIR")
332 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
333
334 for f in (d.getVar('SSTATEPREINSTFUNCS') or '').split() + ['sstate_unpack_package']:
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500335 # All hooks should run in the SSTATE_INSTDIR
336 bb.build.exec_func(f, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500337
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500338 return sstate_installpkgdir(ss, d)
339
340def sstate_installpkgdir(ss, d):
341 import oe.path
342 import subprocess
343
344 sstateinst = d.getVar("SSTATE_INSTDIR")
345 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
346
347 for f in (d.getVar('SSTATEPOSTUNPACKFUNCS') or '').split():
348 # All hooks should run in the SSTATE_INSTDIR
349 bb.build.exec_func(f, d, (sstateinst,))
350
351 def prepdir(dir):
352 # remove dir if it exists, ensure any parent directories do exist
353 if os.path.exists(dir):
354 oe.path.remove(dir)
355 bb.utils.mkdirhier(dir)
356 oe.path.remove(dir)
357
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500358 for state in ss['dirs']:
359 prepdir(state[1])
360 os.rename(sstateinst + state[0], state[1])
361 sstate_install(ss, d)
362
363 for plain in ss['plaindirs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500364 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365 src = sstateinst + "/" + plain.replace(workdir, '')
366 dest = plain
367 bb.utils.mkdirhier(src)
368 prepdir(dest)
369 os.rename(src, dest)
370
371 return True
372
373python sstate_hardcode_path_unpack () {
374 # Fixup hardcoded paths
375 #
376 # Note: The logic below must match the reverse logic in
377 # sstate_hardcode_path(d)
378 import subprocess
379
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500380 sstateinst = d.getVar('SSTATE_INSTDIR')
381 sstatefixmedir = d.getVar('SSTATE_FIXMEDIR')
382 fixmefn = sstateinst + "fixmepath"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500383 if os.path.isfile(fixmefn):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500384 staging_target = d.getVar('RECIPE_SYSROOT')
385 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500386
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500387 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500388 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRHOST:%s:g'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500389 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
390 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (staging_target, staging_host)
391 else:
392 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g'" % (staging_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500393
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500394 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500395 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500396 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500397 sstate_sed_cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
398
399 # Add sstateinst to each filename in fixmepath, use xargs to efficiently call sed
400 sstate_hardcode_cmd = "sed -e 's:^:%s:g' %s | xargs %s" % (sstateinst, fixmefn, sstate_sed_cmd)
401
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500402 # Defer do_populate_sysroot relocation command
403 if sstatefixmedir:
404 bb.utils.mkdirhier(sstatefixmedir)
405 with open(sstatefixmedir + "/fixmepath.cmd", "w") as f:
406 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(fixmefn, sstatefixmedir + "/fixmepath")
407 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(sstateinst, "FIXMEFINALSSTATEINST")
408 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_host, "FIXMEFINALSSTATEHOST")
409 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_target, "FIXMEFINALSSTATETARGET")
410 f.write(sstate_hardcode_cmd)
411 bb.utils.copyfile(fixmefn, sstatefixmedir + "/fixmepath")
412 return
413
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500414 bb.note("Replacing fixme paths in sstate package: %s" % (sstate_hardcode_cmd))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500415 subprocess.check_call(sstate_hardcode_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500416
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800417 # Need to remove this or we'd copy it into the target directory and may
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500418 # conflict with another writer
419 os.remove(fixmefn)
420}
421
422def sstate_clean_cachefile(ss, d):
423 import oe.path
424
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500425 sstatepkgfile = d.getVar('SSTATE_PATHSPEC') + "*_" + ss['task'] + ".tgz*"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500426 bb.note("Removing %s" % sstatepkgfile)
427 oe.path.remove(sstatepkgfile)
428
429def sstate_clean_cachefiles(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500430 for task in (d.getVar('SSTATETASKS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500431 ld = d.createCopy()
432 ss = sstate_state_fromvars(ld, task)
433 sstate_clean_cachefile(ss, ld)
434
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500435def sstate_clean_manifest(manifest, d, prefix=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500436 import oe.path
437
438 mfile = open(manifest)
439 entries = mfile.readlines()
440 mfile.close()
441
442 for entry in entries:
443 entry = entry.strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500444 if prefix and not entry.startswith("/"):
445 entry = prefix + "/" + entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500446 bb.debug(2, "Removing manifest: %s" % entry)
447 # We can race against another package populating directories as we're removing them
448 # so we ignore errors here.
449 try:
450 if entry.endswith("/"):
451 if os.path.islink(entry[:-1]):
452 os.remove(entry[:-1])
453 elif os.path.exists(entry) and len(os.listdir(entry)) == 0:
454 os.rmdir(entry[:-1])
455 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500456 os.remove(entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500457 except OSError:
458 pass
459
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600460 postrm = manifest + ".postrm"
461 if os.path.exists(manifest + ".postrm"):
462 import subprocess
463 os.chmod(postrm, 0o755)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500464 subprocess.check_call(postrm, shell=True)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600465 oe.path.remove(postrm)
466
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500467 oe.path.remove(manifest)
468
469def sstate_clean(ss, d):
470 import oe.path
471 import glob
472
473 d2 = d.createCopy()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500474 stamp_clean = d.getVar("STAMPCLEAN")
475 extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500476 if extrainf:
477 d2.setVar("SSTATE_MANMACH", extrainf)
478 wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
479 else:
480 wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
481
482 manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
483
484 if os.path.exists(manifest):
485 locks = []
486 for lock in ss['lockfiles-shared']:
487 locks.append(bb.utils.lockfile(lock))
488 for lock in ss['lockfiles']:
489 locks.append(bb.utils.lockfile(lock))
490
491 sstate_clean_manifest(manifest, d)
492
493 for lock in locks:
494 bb.utils.unlockfile(lock)
495
496 # Remove the current and previous stamps, but keep the sigdata.
497 #
498 # The glob() matches do_task* which may match multiple tasks, for
499 # example: do_package and do_package_write_ipk, so we need to
500 # exactly match *.do_task.* and *.do_task_setscene.*
501 rm_stamp = '.do_%s.' % ss['task']
502 rm_setscene = '.do_%s_setscene.' % ss['task']
503 # For BB_SIGNATURE_HANDLER = "noop"
504 rm_nohash = ".do_%s" % ss['task']
505 for stfile in glob.glob(wildcard_stfile):
506 # Keep the sigdata
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500507 if ".sigdata." in stfile or ".sigbasedata." in stfile:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500508 continue
509 # Preserve taint files in the stamps directory
510 if stfile.endswith('.taint'):
511 continue
512 if rm_stamp in stfile or rm_setscene in stfile or \
513 stfile.endswith(rm_nohash):
514 oe.path.remove(stfile)
515
516sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
517
518CLEANFUNCS += "sstate_cleanall"
519
520python sstate_cleanall() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500521 bb.note("Removing shared state for package %s" % d.getVar('PN'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500522
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500523 manifest_dir = d.getVar('SSTATE_MANIFESTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500524 if not os.path.exists(manifest_dir):
525 return
526
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500527 tasks = d.getVar('SSTATETASKS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500528 for name in tasks:
529 ld = d.createCopy()
530 shared_state = sstate_state_fromvars(ld, name)
531 sstate_clean(shared_state, ld)
532}
533
534python sstate_hardcode_path () {
535 import subprocess, platform
536
537 # Need to remove hardcoded paths and fix these when we install the
538 # staging packages.
539 #
540 # Note: the logic in this function needs to match the reverse logic
541 # in sstate_installpkg(ss, d)
542
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500543 staging_target = d.getVar('RECIPE_SYSROOT')
544 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
545 sstate_builddir = d.getVar('SSTATE_BUILDDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500546
Brad Bishop316dfdd2018-06-25 12:45:53 -0400547 sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500548 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500549 sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500550 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
551 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400552 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500553 else:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400554 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
555 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500557 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500558 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500559 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560 sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500561 sstate_grep_cmd += " -e '%s'" % (fixme_path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500562
563 fixmefn = sstate_builddir + "fixmepath"
564
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500565 sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500566 sstate_filelist_cmd = "tee %s" % (fixmefn)
567
568 # fixmepath file needs relative paths, drop sstate_builddir prefix
569 sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
570
571 xargs_no_empty_run_cmd = '--no-run-if-empty'
572 if platform.system() == 'Darwin':
573 xargs_no_empty_run_cmd = ''
574
575 # Limit the fixpaths and sed operations based on the initial grep search
576 # This has the side effect of making sure the vfs cache is hot
577 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)
578
579 bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500580 subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500581
582 # If the fixmefn is empty, remove it..
583 if os.stat(fixmefn).st_size == 0:
584 os.remove(fixmefn)
585 else:
586 bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500587 subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500588}
589
590def sstate_package(ss, d):
591 import oe.path
592
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500593 tmpdir = d.getVar('TMPDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500594
595 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500596 sstatepkg = d.getVar('SSTATE_PKG') + '_'+ ss['task'] + ".tgz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500597 bb.utils.remove(sstatebuild, recurse=True)
598 bb.utils.mkdirhier(sstatebuild)
599 bb.utils.mkdirhier(os.path.dirname(sstatepkg))
600 for state in ss['dirs']:
601 if not os.path.exists(state[1]):
602 continue
603 srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500604 # Find and error for absolute symlinks. We could attempt to relocate but its not
605 # clear where the symlink is relative to in this context. We could add that markup
606 # to sstate tasks but there aren't many of these so better just avoid them entirely.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500607 for walkroot, dirs, files in os.walk(state[1]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500608 for file in files + dirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500609 srcpath = os.path.join(walkroot, file)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500610 if not os.path.islink(srcpath):
611 continue
612 link = os.readlink(srcpath)
613 if not os.path.isabs(link):
614 continue
615 if not link.startswith(tmpdir):
616 continue
617 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 -0500618 bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500619 os.rename(state[1], sstatebuild + state[0])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500620
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500621 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500622 for plain in ss['plaindirs']:
623 pdir = plain.replace(workdir, sstatebuild)
624 bb.utils.mkdirhier(plain)
625 bb.utils.mkdirhier(pdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500626 os.rename(plain, pdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500627
628 d.setVar('SSTATE_BUILDDIR', sstatebuild)
629 d.setVar('SSTATE_PKG', sstatepkg)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500630 d.setVar('SSTATE_INSTDIR', sstatebuild)
631
632 if d.getVar('SSTATE_SKIP_CREATION') == '1':
633 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500634
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500635 for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500636 ['sstate_create_package', 'sstate_sign_package'] + \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500637 (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500638 # All hooks should run in SSTATE_BUILDDIR.
639 bb.build.exec_func(f, d, (sstatebuild,))
640
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641 bb.siggen.dump_this_task(sstatepkg + ".siginfo", d)
642
643 return
644
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800645def pstaging_fetch(sstatefetch, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500646 import bb.fetch2
647
648 # Only try and fetch if the user has configured a mirror
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500649 mirrors = d.getVar('SSTATE_MIRRORS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500650 if not mirrors:
651 return
652
653 # Copy the data object and override DL_DIR and SRC_URI
654 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500655
656 dldir = localdata.expand("${SSTATE_DIR}")
657 bb.utils.mkdirhier(dldir)
658
659 localdata.delVar('MIRRORS')
660 localdata.setVar('FILESPATH', dldir)
661 localdata.setVar('DL_DIR', dldir)
662 localdata.setVar('PREMIRRORS', mirrors)
663
664 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
665 # we'll want to allow network access for the current set of fetches.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500666 if localdata.getVar('BB_NO_NETWORK') == "1" and localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667 localdata.delVar('BB_NO_NETWORK')
668
669 # Try a fetch from the sstate mirror, if it fails just return and
670 # we will build the package
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600671 uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
672 'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500673 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600674 uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500675
676 for srcuri in uris:
677 localdata.setVar('SRC_URI', srcuri)
678 try:
679 fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
680 fetcher.download()
681
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500682 except bb.fetch2.BBFetchException:
683 break
684
685def sstate_setscene(d):
686 shared_state = sstate_state_fromvars(d)
687 accelerate = sstate_installpkg(shared_state, d)
688 if not accelerate:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600689 bb.fatal("No suitable staging package found")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500690
691python sstate_task_prefunc () {
692 shared_state = sstate_state_fromvars(d)
693 sstate_clean(shared_state, d)
694}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500695sstate_task_prefunc[dirs] = "${WORKDIR}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500696
697python sstate_task_postfunc () {
698 shared_state = sstate_state_fromvars(d)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500699
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500700 for intercept in shared_state['interceptfuncs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500701 bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
702
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600703 omask = os.umask(0o002)
704 if omask != 0o002:
705 bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500706 sstate_package(shared_state, d)
707 os.umask(omask)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500708
709 sstateinst = d.getVar("SSTATE_INSTDIR")
710 d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
711
712 sstate_installpkgdir(shared_state, d)
713
714 bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500715}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500716sstate_task_postfunc[dirs] = "${WORKDIR}"
717
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500718
719#
720# Shell function to generate a sstate package from a directory
721# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
722#
723sstate_create_package () {
724 TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800725
726 # Use pigz if available
727 OPT="-czS"
728 if [ -x "$(command -v pigz)" ]; then
729 OPT="-I pigz -cS"
730 fi
731
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500732 # Need to handle empty directories
733 if [ "$(ls -A)" ]; then
734 set +e
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800735 tar $OPT -f $TFILE *
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500736 ret=$?
737 if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
738 exit 1
739 fi
740 set -e
741 else
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800742 tar $OPT --file=$TFILE --files-from=/dev/null
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500743 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500744 chmod 0664 $TFILE
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500745 mv -f $TFILE ${SSTATE_PKG}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500746}
747
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500748python sstate_sign_package () {
749 from oe.gpg_sign import get_signer
750
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500751 if d.getVar('SSTATE_SIG_KEY'):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500752 signer = get_signer(d, 'local')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500753 sstate_pkg = d.getVar('SSTATE_PKG')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500754 if os.path.exists(sstate_pkg + '.sig'):
755 os.unlink(sstate_pkg + '.sig')
756 signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500757 d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500758}
759
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500760#
761# Shell function to decompress and prepare a package for installation
762# Will be run from within SSTATE_INSTDIR.
763#
764sstate_unpack_package () {
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500765 tar -xvzf ${SSTATE_PKG}
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500766 # update .siginfo atime on local/NFS mirror
767 [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500768 # Use "! -w ||" to return true for read only files
769 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500770 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig
771 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500772}
773
774BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
775
776def sstate_checkhashes(sq_fn, sq_task, sq_hash, sq_hashfn, d, siginfo=False):
777
778 ret = []
779 missed = []
780 extension = ".tgz"
781 if siginfo:
782 extension = extension + ".siginfo"
783
784 def getpathcomponents(task, d):
785 # Magic data from BB_HASHFILENAME
786 splithashfn = sq_hashfn[task].split(" ")
787 spec = splithashfn[1]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500788 if splithashfn[0] == "True":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500789 extrapath = d.getVar("NATIVELSBSTRING") + "/"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500790 else:
791 extrapath = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500792
793 tname = sq_task[task][3:]
794
795 if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
796 spec = splithashfn[2]
797 extrapath = ""
798
799 return spec, extrapath, tname
800
801
802 for task in range(len(sq_fn)):
803
804 spec, extrapath, tname = getpathcomponents(task, d)
805
806 sstatefile = d.expand("${SSTATE_DIR}/" + extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + extension)
807
808 if os.path.exists(sstatefile):
809 bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
810 ret.append(task)
811 continue
812 else:
813 missed.append(task)
814 bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
815
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500816 mirrors = d.getVar("SSTATE_MIRRORS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500817 if mirrors:
818 # Copy the data object and override DL_DIR and SRC_URI
819 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500820
821 dldir = localdata.expand("${SSTATE_DIR}")
822 localdata.delVar('MIRRORS')
823 localdata.setVar('FILESPATH', dldir)
824 localdata.setVar('DL_DIR', dldir)
825 localdata.setVar('PREMIRRORS', mirrors)
826
827 bb.debug(2, "SState using premirror of: %s" % mirrors)
828
829 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
830 # we'll want to allow network access for the current set of fetches.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500831 if localdata.getVar('BB_NO_NETWORK') == "1" and localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500832 localdata.delVar('BB_NO_NETWORK')
833
834 from bb.fetch2 import FetchConnectionCache
835 def checkstatus_init(thread_worker):
836 thread_worker.connection_cache = FetchConnectionCache()
837
838 def checkstatus_end(thread_worker):
839 thread_worker.connection_cache.close_connections()
840
841 def checkstatus(thread_worker, arg):
842 (task, sstatefile) = arg
843
844 localdata2 = bb.data.createCopy(localdata)
845 srcuri = "file://" + sstatefile
846 localdata.setVar('SRC_URI', srcuri)
847 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
848
849 try:
850 fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
851 connection_cache=thread_worker.connection_cache)
852 fetcher.checkstatus()
853 bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
854 ret.append(task)
855 if task in missed:
856 missed.remove(task)
857 except:
858 missed.append(task)
859 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600860 pass
Brad Bishop316dfdd2018-06-25 12:45:53 -0400861 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500862
863 tasklist = []
864 for task in range(len(sq_fn)):
865 if task in ret:
866 continue
867 spec, extrapath, tname = getpathcomponents(task, d)
868 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + extension)
869 tasklist.append((task, sstatefile))
870
871 if tasklist:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400872 msg = "Checking sstate mirror object availability"
873 bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600874
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500875 import multiprocessing
876 nproc = min(multiprocessing.cpu_count(), len(tasklist))
877
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600878 bb.event.enable_threadlock()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500879 pool = oe.utils.ThreadedPool(nproc, len(tasklist),
880 worker_init=checkstatus_init, worker_end=checkstatus_end)
881 for t in tasklist:
882 pool.add_task(checkstatus, t)
883 pool.start()
884 pool.wait_completion()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600885 bb.event.disable_threadlock()
886
Brad Bishop316dfdd2018-06-25 12:45:53 -0400887 bb.event.fire(bb.event.ProcessFinished(msg), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500888
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500889 inheritlist = d.getVar("INHERIT")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500890 if "toaster" in inheritlist:
891 evdata = {'missed': [], 'found': []};
892 for task in missed:
893 spec, extrapath, tname = getpathcomponents(task, d)
894 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + ".tgz")
895 evdata['missed'].append( (sq_fn[task], sq_task[task], sq_hash[task], sstatefile ) )
896 for task in ret:
897 spec, extrapath, tname = getpathcomponents(task, d)
898 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + ".tgz")
899 evdata['found'].append( (sq_fn[task], sq_task[task], sq_hash[task], sstatefile ) )
900 bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
901
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800902 # Print some summary statistics about the current task completion and how much sstate
903 # reuse there was. Avoid divide by zero errors.
904 total = len(sq_fn)
905 currentcount = d.getVar("BB_SETSCENE_STAMPCURRENT_COUNT") or 0
906 complete = 0
907 if currentcount:
908 complete = (len(ret) + currentcount) / (total + currentcount) * 100
909 match = 0
910 if total:
911 match = len(ret) / total * 100
912 bb.plain("Sstate summary: Wanted %d Found %d Missed %d Current %d (%d%% match, %d%% complete)" % (total, len(ret), len(missed), currentcount, match, complete))
913
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500914 if hasattr(bb.parse.siggen, "checkhashes"):
915 bb.parse.siggen.checkhashes(missed, ret, sq_fn, sq_task, sq_hash, sq_hashfn, d)
916
917 return ret
918
919BB_SETSCENE_DEPVALID = "setscene_depvalid"
920
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500921def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500922 # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
923 # task is included in taskdependees too
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500924 # Return - False - We need this dependency
925 # - True - We can skip this dependency
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800926 import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500927
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500928 def logit(msg, log):
929 if log is not None:
930 log.append(msg)
931 else:
932 bb.debug(2, msg)
933
934 logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500935
936 def isNativeCross(x):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500937 return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500938
939 # We only need to trigger populate_lic through direct dependencies
940 if taskdependees[task][1] == "do_populate_lic":
941 return True
942
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500943 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
944 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
945 return True
946
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500947 # We only need to trigger packagedata through direct dependencies
948 # but need to preserve packagedata on packagedata links
949 if taskdependees[task][1] == "do_packagedata":
950 for dep in taskdependees:
951 if taskdependees[dep][1] == "do_packagedata":
952 return False
953 return True
954
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500955 for dep in taskdependees:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500956 logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500957 if task == dep:
958 continue
959 if dep in notneeded:
960 continue
961 # do_package_write_* and do_package doesn't need do_package
962 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']:
963 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500964 # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
965 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
966 return False
967 # do_package/packagedata/package_qa don't need do_populate_sysroot
968 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 -0500969 continue
970 # Native/Cross packages don't exist and are noexec anyway
971 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']:
972 continue
973
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500974 # This is due to the [depends] in useradd.bbclass complicating matters
975 # The logic *is* reversed here due to the way hard setscene dependencies are injected
976 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':
977 continue
978
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500979 # Consider sysroot depending on sysroot tasks
980 if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800981 # Allow excluding certain recursive dependencies. If a recipe needs it should add a
982 # specific dependency itself, rather than relying on one of its dependees to pull
983 # them in.
984 # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
985 not_needed = False
986 excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
987 if excludedeps is None:
988 # Cache the regular expressions for speed
989 excludedeps = []
990 for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
991 excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
992 d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
993 for excl in excludedeps:
994 if excl[0].match(taskdependees[dep][0]):
995 if excl[1].match(taskdependees[task][0]):
996 not_needed = True
997 break
998 if not_needed:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500999 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001000 # For meta-extsdk-toolchain we want all sysroot dependencies
1001 if taskdependees[dep][0] == 'meta-extsdk-toolchain':
1002 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001003 # Native/Cross populate_sysroot need their dependencies
1004 if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
1005 return False
1006 # Target populate_sysroot depended on by cross tools need to be installed
1007 if isNativeCross(taskdependees[dep][0]):
1008 return False
1009 # Native/cross tools depended upon by target sysroot are not needed
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001010 # Add an exception for shadow-native as required by useradd.bbclass
1011 if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001012 continue
1013 # Target populate_sysroot need their dependencies
1014 return False
1015
1016 if taskdependees[task][1] == 'do_shared_workdir':
1017 continue
1018
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001019 if taskdependees[dep][1] == "do_populate_lic":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001020 continue
1021
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001022
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001023 # Safe fallthrough default
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001024 logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001025 return False
1026 return True
1027
1028addhandler sstate_eventhandler
1029sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
1030python sstate_eventhandler() {
1031 d = e.data
1032 # When we write an sstate package we rewrite the SSTATE_PKG
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001033 spkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001034 if not spkg.endswith(".tgz"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001035 taskname = d.getVar("BB_RUNTASK")[3:]
1036 spec = d.getVar('SSTATE_PKGSPEC')
1037 swspec = d.getVar('SSTATE_SWSPEC')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001038 if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
1039 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
1040 d.setVar("SSTATE_EXTRAPATH", "")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001041 sstatepkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001042 bb.siggen.dump_this_task(sstatepkg + '_' + taskname + ".tgz" ".siginfo", d)
1043}
1044
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001045SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001046
1047# Event handler which removes manifests and stamps file for
1048# recipes which are no longer reachable in a build where they
1049# once were.
1050# Also optionally removes the workdir of those tasks/recipes
1051#
1052addhandler sstate_eventhandler2
1053sstate_eventhandler2[eventmask] = "bb.event.ReachableStamps"
1054python sstate_eventhandler2() {
1055 import glob
1056 d = e.data
1057 stamps = e.stamps.values()
1058 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001059 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1060 preservestamps = []
1061 if os.path.exists(preservestampfile):
1062 with open(preservestampfile, 'r') as f:
1063 preservestamps = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001064 seen = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001065
1066 # The machine index contains all the stamps this machine has ever seen in this build directory.
1067 # We should only remove things which this machine once accessed but no longer does.
1068 machineindex = set()
1069 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
1070 mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
1071 if os.path.exists(mi):
1072 with open(mi, "r") as f:
1073 machineindex = set(line.strip() for line in f.readlines())
1074
Brad Bishop316dfdd2018-06-25 12:45:53 -04001075 for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001076 toremove = []
1077 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1078 if not os.path.exists(i):
1079 continue
1080 with open(i, "r") as f:
1081 lines = f.readlines()
1082 for l in lines:
1083 (stamp, manifest, workdir) = l.split()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001084 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001085 toremove.append(l)
1086 if stamp not in seen:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001087 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001088 seen.append(stamp)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001089
1090 if toremove:
Brad Bishop316dfdd2018-06-25 12:45:53 -04001091 msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
1092 bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001093
Brad Bishop316dfdd2018-06-25 12:45:53 -04001094 removed = 0
1095 for r in toremove:
1096 (stamp, manifest, workdir) = r.split()
1097 for m in glob.glob(manifest + ".*"):
1098 if m.endswith(".postrm"):
1099 continue
1100 sstate_clean_manifest(m, d)
1101 bb.utils.remove(stamp + "*")
1102 if removeworkdir:
1103 bb.utils.remove(workdir, recurse = True)
1104 lines.remove(r)
1105 removed = removed + 1
1106 bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
1107
1108 bb.event.fire(bb.event.ProcessFinished(msg), d)
1109
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001110 with open(i, "w") as f:
1111 for l in lines:
1112 f.write(l)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001113 machineindex |= set(stamps)
1114 with open(mi, "w") as f:
1115 for l in machineindex:
1116 f.write(l + "\n")
1117
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001118 if preservestamps:
1119 os.remove(preservestampfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001120}