blob: 9f059a04a07e04a836e9e4ad2d718ab08e271d2d [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*"
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300426 if d.getVarFlag('do_%s' % ss['task'], 'task'):
427 bb.note("Removing %s" % sstatepkgfile)
428 oe.path.remove(sstatepkgfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500429
430def sstate_clean_cachefiles(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500431 for task in (d.getVar('SSTATETASKS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500432 ld = d.createCopy()
433 ss = sstate_state_fromvars(ld, task)
434 sstate_clean_cachefile(ss, ld)
435
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500436def sstate_clean_manifest(manifest, d, prefix=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500437 import oe.path
438
439 mfile = open(manifest)
440 entries = mfile.readlines()
441 mfile.close()
442
443 for entry in entries:
444 entry = entry.strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500445 if prefix and not entry.startswith("/"):
446 entry = prefix + "/" + entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500447 bb.debug(2, "Removing manifest: %s" % entry)
448 # We can race against another package populating directories as we're removing them
449 # so we ignore errors here.
450 try:
451 if entry.endswith("/"):
452 if os.path.islink(entry[:-1]):
453 os.remove(entry[:-1])
454 elif os.path.exists(entry) and len(os.listdir(entry)) == 0:
455 os.rmdir(entry[:-1])
456 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500457 os.remove(entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500458 except OSError:
459 pass
460
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600461 postrm = manifest + ".postrm"
462 if os.path.exists(manifest + ".postrm"):
463 import subprocess
464 os.chmod(postrm, 0o755)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500465 subprocess.check_call(postrm, shell=True)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600466 oe.path.remove(postrm)
467
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500468 oe.path.remove(manifest)
469
470def sstate_clean(ss, d):
471 import oe.path
472 import glob
473
474 d2 = d.createCopy()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500475 stamp_clean = d.getVar("STAMPCLEAN")
476 extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500477 if extrainf:
478 d2.setVar("SSTATE_MANMACH", extrainf)
479 wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
480 else:
481 wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
482
483 manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
484
485 if os.path.exists(manifest):
486 locks = []
487 for lock in ss['lockfiles-shared']:
488 locks.append(bb.utils.lockfile(lock))
489 for lock in ss['lockfiles']:
490 locks.append(bb.utils.lockfile(lock))
491
492 sstate_clean_manifest(manifest, d)
493
494 for lock in locks:
495 bb.utils.unlockfile(lock)
496
497 # Remove the current and previous stamps, but keep the sigdata.
498 #
499 # The glob() matches do_task* which may match multiple tasks, for
500 # example: do_package and do_package_write_ipk, so we need to
501 # exactly match *.do_task.* and *.do_task_setscene.*
502 rm_stamp = '.do_%s.' % ss['task']
503 rm_setscene = '.do_%s_setscene.' % ss['task']
504 # For BB_SIGNATURE_HANDLER = "noop"
505 rm_nohash = ".do_%s" % ss['task']
506 for stfile in glob.glob(wildcard_stfile):
507 # Keep the sigdata
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500508 if ".sigdata." in stfile or ".sigbasedata." in stfile:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500509 continue
510 # Preserve taint files in the stamps directory
511 if stfile.endswith('.taint'):
512 continue
513 if rm_stamp in stfile or rm_setscene in stfile or \
514 stfile.endswith(rm_nohash):
515 oe.path.remove(stfile)
516
517sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
518
519CLEANFUNCS += "sstate_cleanall"
520
521python sstate_cleanall() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500522 bb.note("Removing shared state for package %s" % d.getVar('PN'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500523
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500524 manifest_dir = d.getVar('SSTATE_MANIFESTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500525 if not os.path.exists(manifest_dir):
526 return
527
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500528 tasks = d.getVar('SSTATETASKS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500529 for name in tasks:
530 ld = d.createCopy()
531 shared_state = sstate_state_fromvars(ld, name)
532 sstate_clean(shared_state, ld)
533}
534
535python sstate_hardcode_path () {
536 import subprocess, platform
537
538 # Need to remove hardcoded paths and fix these when we install the
539 # staging packages.
540 #
541 # Note: the logic in this function needs to match the reverse logic
542 # in sstate_installpkg(ss, d)
543
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500544 staging_target = d.getVar('RECIPE_SYSROOT')
545 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
546 sstate_builddir = d.getVar('SSTATE_BUILDDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500547
Brad Bishop316dfdd2018-06-25 12:45:53 -0400548 sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500549 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550 sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500551 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
552 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400553 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500554 else:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400555 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
556 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500558 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500559 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500560 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500561 sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500562 sstate_grep_cmd += " -e '%s'" % (fixme_path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500563
564 fixmefn = sstate_builddir + "fixmepath"
565
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500566 sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500567 sstate_filelist_cmd = "tee %s" % (fixmefn)
568
569 # fixmepath file needs relative paths, drop sstate_builddir prefix
570 sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
571
572 xargs_no_empty_run_cmd = '--no-run-if-empty'
573 if platform.system() == 'Darwin':
574 xargs_no_empty_run_cmd = ''
575
576 # Limit the fixpaths and sed operations based on the initial grep search
577 # This has the side effect of making sure the vfs cache is hot
578 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)
579
580 bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500581 subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500582
583 # If the fixmefn is empty, remove it..
584 if os.stat(fixmefn).st_size == 0:
585 os.remove(fixmefn)
586 else:
587 bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500588 subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500589}
590
591def sstate_package(ss, d):
592 import oe.path
593
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500594 tmpdir = d.getVar('TMPDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500595
596 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500597 sstatepkg = d.getVar('SSTATE_PKG') + '_'+ ss['task'] + ".tgz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500598 bb.utils.remove(sstatebuild, recurse=True)
599 bb.utils.mkdirhier(sstatebuild)
600 bb.utils.mkdirhier(os.path.dirname(sstatepkg))
601 for state in ss['dirs']:
602 if not os.path.exists(state[1]):
603 continue
604 srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500605 # Find and error for absolute symlinks. We could attempt to relocate but its not
606 # clear where the symlink is relative to in this context. We could add that markup
607 # to sstate tasks but there aren't many of these so better just avoid them entirely.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500608 for walkroot, dirs, files in os.walk(state[1]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500609 for file in files + dirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500610 srcpath = os.path.join(walkroot, file)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500611 if not os.path.islink(srcpath):
612 continue
613 link = os.readlink(srcpath)
614 if not os.path.isabs(link):
615 continue
616 if not link.startswith(tmpdir):
617 continue
618 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 -0500619 bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500620 os.rename(state[1], sstatebuild + state[0])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500621
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500622 workdir = d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623 for plain in ss['plaindirs']:
624 pdir = plain.replace(workdir, sstatebuild)
625 bb.utils.mkdirhier(plain)
626 bb.utils.mkdirhier(pdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500627 os.rename(plain, pdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500628
629 d.setVar('SSTATE_BUILDDIR', sstatebuild)
630 d.setVar('SSTATE_PKG', sstatepkg)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500631 d.setVar('SSTATE_INSTDIR', sstatebuild)
632
633 if d.getVar('SSTATE_SKIP_CREATION') == '1':
634 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500635
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500636 for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500637 ['sstate_create_package', 'sstate_sign_package'] + \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500638 (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500639 # All hooks should run in SSTATE_BUILDDIR.
640 bb.build.exec_func(f, d, (sstatebuild,))
641
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500642 bb.siggen.dump_this_task(sstatepkg + ".siginfo", d)
643
644 return
645
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800646def pstaging_fetch(sstatefetch, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500647 import bb.fetch2
648
649 # Only try and fetch if the user has configured a mirror
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500650 mirrors = d.getVar('SSTATE_MIRRORS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500651 if not mirrors:
652 return
653
654 # Copy the data object and override DL_DIR and SRC_URI
655 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500656
657 dldir = localdata.expand("${SSTATE_DIR}")
658 bb.utils.mkdirhier(dldir)
659
660 localdata.delVar('MIRRORS')
661 localdata.setVar('FILESPATH', dldir)
662 localdata.setVar('DL_DIR', dldir)
663 localdata.setVar('PREMIRRORS', mirrors)
664
665 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
666 # we'll want to allow network access for the current set of fetches.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500667 if localdata.getVar('BB_NO_NETWORK') == "1" and localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500668 localdata.delVar('BB_NO_NETWORK')
669
670 # Try a fetch from the sstate mirror, if it fails just return and
671 # we will build the package
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600672 uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
673 'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500674 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600675 uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500676
677 for srcuri in uris:
678 localdata.setVar('SRC_URI', srcuri)
679 try:
680 fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
681 fetcher.download()
682
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500683 except bb.fetch2.BBFetchException:
684 break
685
686def sstate_setscene(d):
687 shared_state = sstate_state_fromvars(d)
688 accelerate = sstate_installpkg(shared_state, d)
689 if not accelerate:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600690 bb.fatal("No suitable staging package found")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500691
692python sstate_task_prefunc () {
693 shared_state = sstate_state_fromvars(d)
694 sstate_clean(shared_state, d)
695}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500696sstate_task_prefunc[dirs] = "${WORKDIR}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500697
698python sstate_task_postfunc () {
699 shared_state = sstate_state_fromvars(d)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500700
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500701 for intercept in shared_state['interceptfuncs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500702 bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
703
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600704 omask = os.umask(0o002)
705 if omask != 0o002:
706 bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500707 sstate_package(shared_state, d)
708 os.umask(omask)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500709
710 sstateinst = d.getVar("SSTATE_INSTDIR")
711 d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
712
713 sstate_installpkgdir(shared_state, d)
714
715 bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500716}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500717sstate_task_postfunc[dirs] = "${WORKDIR}"
718
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500719
720#
721# Shell function to generate a sstate package from a directory
722# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
723#
724sstate_create_package () {
725 TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800726
727 # Use pigz if available
728 OPT="-czS"
729 if [ -x "$(command -v pigz)" ]; then
730 OPT="-I pigz -cS"
731 fi
732
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500733 # Need to handle empty directories
734 if [ "$(ls -A)" ]; then
735 set +e
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800736 tar $OPT -f $TFILE *
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500737 ret=$?
738 if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
739 exit 1
740 fi
741 set -e
742 else
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800743 tar $OPT --file=$TFILE --files-from=/dev/null
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500744 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500745 chmod 0664 $TFILE
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500746 mv -f $TFILE ${SSTATE_PKG}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500747}
748
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500749python sstate_sign_package () {
750 from oe.gpg_sign import get_signer
751
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500752 if d.getVar('SSTATE_SIG_KEY'):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500753 signer = get_signer(d, 'local')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500754 sstate_pkg = d.getVar('SSTATE_PKG')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500755 if os.path.exists(sstate_pkg + '.sig'):
756 os.unlink(sstate_pkg + '.sig')
757 signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500758 d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500759}
760
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500761#
762# Shell function to decompress and prepare a package for installation
763# Will be run from within SSTATE_INSTDIR.
764#
765sstate_unpack_package () {
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500766 tar -xvzf ${SSTATE_PKG}
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500767 # update .siginfo atime on local/NFS mirror
768 [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500769 # Use "! -w ||" to return true for read only files
770 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500771 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig
772 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500773}
774
775BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
776
777def sstate_checkhashes(sq_fn, sq_task, sq_hash, sq_hashfn, d, siginfo=False):
778
779 ret = []
780 missed = []
781 extension = ".tgz"
782 if siginfo:
783 extension = extension + ".siginfo"
784
785 def getpathcomponents(task, d):
786 # Magic data from BB_HASHFILENAME
787 splithashfn = sq_hashfn[task].split(" ")
788 spec = splithashfn[1]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500789 if splithashfn[0] == "True":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500790 extrapath = d.getVar("NATIVELSBSTRING") + "/"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500791 else:
792 extrapath = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500793
794 tname = sq_task[task][3:]
795
796 if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
797 spec = splithashfn[2]
798 extrapath = ""
799
800 return spec, extrapath, tname
801
802
803 for task in range(len(sq_fn)):
804
805 spec, extrapath, tname = getpathcomponents(task, d)
806
807 sstatefile = d.expand("${SSTATE_DIR}/" + extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + extension)
808
809 if os.path.exists(sstatefile):
810 bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
811 ret.append(task)
812 continue
813 else:
814 missed.append(task)
815 bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
816
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500817 mirrors = d.getVar("SSTATE_MIRRORS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500818 if mirrors:
819 # Copy the data object and override DL_DIR and SRC_URI
820 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500821
822 dldir = localdata.expand("${SSTATE_DIR}")
823 localdata.delVar('MIRRORS')
824 localdata.setVar('FILESPATH', dldir)
825 localdata.setVar('DL_DIR', dldir)
826 localdata.setVar('PREMIRRORS', mirrors)
827
828 bb.debug(2, "SState using premirror of: %s" % mirrors)
829
830 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
831 # we'll want to allow network access for the current set of fetches.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500832 if localdata.getVar('BB_NO_NETWORK') == "1" and localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500833 localdata.delVar('BB_NO_NETWORK')
834
835 from bb.fetch2 import FetchConnectionCache
836 def checkstatus_init(thread_worker):
837 thread_worker.connection_cache = FetchConnectionCache()
838
839 def checkstatus_end(thread_worker):
840 thread_worker.connection_cache.close_connections()
841
842 def checkstatus(thread_worker, arg):
843 (task, sstatefile) = arg
844
845 localdata2 = bb.data.createCopy(localdata)
846 srcuri = "file://" + sstatefile
847 localdata.setVar('SRC_URI', srcuri)
848 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
849
850 try:
851 fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
852 connection_cache=thread_worker.connection_cache)
853 fetcher.checkstatus()
854 bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
855 ret.append(task)
856 if task in missed:
857 missed.remove(task)
858 except:
859 missed.append(task)
860 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600861 pass
Brad Bishop316dfdd2018-06-25 12:45:53 -0400862 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500863
864 tasklist = []
865 for task in range(len(sq_fn)):
866 if task in ret:
867 continue
868 spec, extrapath, tname = getpathcomponents(task, d)
869 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + extension)
870 tasklist.append((task, sstatefile))
871
872 if tasklist:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400873 msg = "Checking sstate mirror object availability"
874 bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600875
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500876 import multiprocessing
877 nproc = min(multiprocessing.cpu_count(), len(tasklist))
878
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600879 bb.event.enable_threadlock()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500880 pool = oe.utils.ThreadedPool(nproc, len(tasklist),
881 worker_init=checkstatus_init, worker_end=checkstatus_end)
882 for t in tasklist:
883 pool.add_task(checkstatus, t)
884 pool.start()
885 pool.wait_completion()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600886 bb.event.disable_threadlock()
887
Brad Bishop316dfdd2018-06-25 12:45:53 -0400888 bb.event.fire(bb.event.ProcessFinished(msg), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500889
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500890 inheritlist = d.getVar("INHERIT")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500891 if "toaster" in inheritlist:
892 evdata = {'missed': [], 'found': []};
893 for task in missed:
894 spec, extrapath, tname = getpathcomponents(task, d)
895 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + ".tgz")
896 evdata['missed'].append( (sq_fn[task], sq_task[task], sq_hash[task], sstatefile ) )
897 for task in ret:
898 spec, extrapath, tname = getpathcomponents(task, d)
899 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + ".tgz")
900 evdata['found'].append( (sq_fn[task], sq_task[task], sq_hash[task], sstatefile ) )
901 bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
902
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800903 # Print some summary statistics about the current task completion and how much sstate
904 # reuse there was. Avoid divide by zero errors.
905 total = len(sq_fn)
906 currentcount = d.getVar("BB_SETSCENE_STAMPCURRENT_COUNT") or 0
907 complete = 0
908 if currentcount:
909 complete = (len(ret) + currentcount) / (total + currentcount) * 100
910 match = 0
911 if total:
912 match = len(ret) / total * 100
913 bb.plain("Sstate summary: Wanted %d Found %d Missed %d Current %d (%d%% match, %d%% complete)" % (total, len(ret), len(missed), currentcount, match, complete))
914
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500915 if hasattr(bb.parse.siggen, "checkhashes"):
916 bb.parse.siggen.checkhashes(missed, ret, sq_fn, sq_task, sq_hash, sq_hashfn, d)
917
918 return ret
919
920BB_SETSCENE_DEPVALID = "setscene_depvalid"
921
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500922def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500923 # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
924 # task is included in taskdependees too
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500925 # Return - False - We need this dependency
926 # - True - We can skip this dependency
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800927 import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500928
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500929 def logit(msg, log):
930 if log is not None:
931 log.append(msg)
932 else:
933 bb.debug(2, msg)
934
935 logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500936
937 def isNativeCross(x):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500938 return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500939
940 # We only need to trigger populate_lic through direct dependencies
941 if taskdependees[task][1] == "do_populate_lic":
942 return True
943
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500944 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
945 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
946 return True
947
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500948 # We only need to trigger packagedata through direct dependencies
949 # but need to preserve packagedata on packagedata links
950 if taskdependees[task][1] == "do_packagedata":
951 for dep in taskdependees:
952 if taskdependees[dep][1] == "do_packagedata":
953 return False
954 return True
955
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500956 for dep in taskdependees:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500957 logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500958 if task == dep:
959 continue
960 if dep in notneeded:
961 continue
962 # do_package_write_* and do_package doesn't need do_package
963 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']:
964 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500965 # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
966 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
967 return False
968 # do_package/packagedata/package_qa don't need do_populate_sysroot
969 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 -0500970 continue
971 # Native/Cross packages don't exist and are noexec anyway
972 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']:
973 continue
974
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500975 # This is due to the [depends] in useradd.bbclass complicating matters
976 # The logic *is* reversed here due to the way hard setscene dependencies are injected
977 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':
978 continue
979
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500980 # Consider sysroot depending on sysroot tasks
981 if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800982 # Allow excluding certain recursive dependencies. If a recipe needs it should add a
983 # specific dependency itself, rather than relying on one of its dependees to pull
984 # them in.
985 # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
986 not_needed = False
987 excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
988 if excludedeps is None:
989 # Cache the regular expressions for speed
990 excludedeps = []
991 for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
992 excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
993 d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
994 for excl in excludedeps:
995 if excl[0].match(taskdependees[dep][0]):
996 if excl[1].match(taskdependees[task][0]):
997 not_needed = True
998 break
999 if not_needed:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001000 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001001 # For meta-extsdk-toolchain we want all sysroot dependencies
1002 if taskdependees[dep][0] == 'meta-extsdk-toolchain':
1003 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001004 # Native/Cross populate_sysroot need their dependencies
1005 if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
1006 return False
1007 # Target populate_sysroot depended on by cross tools need to be installed
1008 if isNativeCross(taskdependees[dep][0]):
1009 return False
1010 # Native/cross tools depended upon by target sysroot are not needed
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001011 # Add an exception for shadow-native as required by useradd.bbclass
1012 if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001013 continue
1014 # Target populate_sysroot need their dependencies
1015 return False
1016
1017 if taskdependees[task][1] == 'do_shared_workdir':
1018 continue
1019
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001020 if taskdependees[dep][1] == "do_populate_lic":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001021 continue
1022
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001023
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001024 # Safe fallthrough default
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001025 logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001026 return False
1027 return True
1028
1029addhandler sstate_eventhandler
1030sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
1031python sstate_eventhandler() {
1032 d = e.data
1033 # When we write an sstate package we rewrite the SSTATE_PKG
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001034 spkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001035 if not spkg.endswith(".tgz"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001036 taskname = d.getVar("BB_RUNTASK")[3:]
1037 spec = d.getVar('SSTATE_PKGSPEC')
1038 swspec = d.getVar('SSTATE_SWSPEC')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001039 if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
1040 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
1041 d.setVar("SSTATE_EXTRAPATH", "")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001042 sstatepkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001043 bb.siggen.dump_this_task(sstatepkg + '_' + taskname + ".tgz" ".siginfo", d)
1044}
1045
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001046SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001047
1048# Event handler which removes manifests and stamps file for
1049# recipes which are no longer reachable in a build where they
1050# once were.
1051# Also optionally removes the workdir of those tasks/recipes
1052#
1053addhandler sstate_eventhandler2
1054sstate_eventhandler2[eventmask] = "bb.event.ReachableStamps"
1055python sstate_eventhandler2() {
1056 import glob
1057 d = e.data
1058 stamps = e.stamps.values()
1059 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001060 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1061 preservestamps = []
1062 if os.path.exists(preservestampfile):
1063 with open(preservestampfile, 'r') as f:
1064 preservestamps = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001065 seen = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001066
1067 # The machine index contains all the stamps this machine has ever seen in this build directory.
1068 # We should only remove things which this machine once accessed but no longer does.
1069 machineindex = set()
1070 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
1071 mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
1072 if os.path.exists(mi):
1073 with open(mi, "r") as f:
1074 machineindex = set(line.strip() for line in f.readlines())
1075
Brad Bishop316dfdd2018-06-25 12:45:53 -04001076 for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001077 toremove = []
1078 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1079 if not os.path.exists(i):
1080 continue
1081 with open(i, "r") as f:
1082 lines = f.readlines()
1083 for l in lines:
1084 (stamp, manifest, workdir) = l.split()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001085 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001086 toremove.append(l)
1087 if stamp not in seen:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001088 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001089 seen.append(stamp)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001090
1091 if toremove:
Brad Bishop316dfdd2018-06-25 12:45:53 -04001092 msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
1093 bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001094
Brad Bishop316dfdd2018-06-25 12:45:53 -04001095 removed = 0
1096 for r in toremove:
1097 (stamp, manifest, workdir) = r.split()
1098 for m in glob.glob(manifest + ".*"):
1099 if m.endswith(".postrm"):
1100 continue
1101 sstate_clean_manifest(m, d)
1102 bb.utils.remove(stamp + "*")
1103 if removeworkdir:
1104 bb.utils.remove(workdir, recurse = True)
1105 lines.remove(r)
1106 removed = removed + 1
1107 bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
1108
1109 bb.event.fire(bb.event.ProcessFinished(msg), d)
1110
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001111 with open(i, "w") as f:
1112 for l in lines:
1113 f.write(l)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001114 machineindex |= set(stamps)
1115 with open(mi, "w") as f:
1116 for l in machineindex:
1117 f.write(l + "\n")
1118
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001119 if preservestamps:
1120 os.remove(preservestampfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001121}