blob: edbfba5de331e271387b0d966a6303cda7d5ceb4 [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')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500365 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500366 src = sstateinst + "/" + plain.replace(workdir, '')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500367 if sharedworkdir in plain:
368 src = sstateinst + "/" + plain.replace(sharedworkdir, '')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500369 dest = plain
370 bb.utils.mkdirhier(src)
371 prepdir(dest)
372 os.rename(src, dest)
373
374 return True
375
376python sstate_hardcode_path_unpack () {
377 # Fixup hardcoded paths
378 #
379 # Note: The logic below must match the reverse logic in
380 # sstate_hardcode_path(d)
381 import subprocess
382
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500383 sstateinst = d.getVar('SSTATE_INSTDIR')
384 sstatefixmedir = d.getVar('SSTATE_FIXMEDIR')
385 fixmefn = sstateinst + "fixmepath"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500386 if os.path.isfile(fixmefn):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500387 staging_target = d.getVar('RECIPE_SYSROOT')
388 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500389
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500390 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500391 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRHOST:%s:g'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500392 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
393 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (staging_target, staging_host)
394 else:
395 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g'" % (staging_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500396
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500397 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500398 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500399 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500400 sstate_sed_cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
401
402 # Add sstateinst to each filename in fixmepath, use xargs to efficiently call sed
403 sstate_hardcode_cmd = "sed -e 's:^:%s:g' %s | xargs %s" % (sstateinst, fixmefn, sstate_sed_cmd)
404
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500405 # Defer do_populate_sysroot relocation command
406 if sstatefixmedir:
407 bb.utils.mkdirhier(sstatefixmedir)
408 with open(sstatefixmedir + "/fixmepath.cmd", "w") as f:
409 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(fixmefn, sstatefixmedir + "/fixmepath")
410 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(sstateinst, "FIXMEFINALSSTATEINST")
411 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_host, "FIXMEFINALSSTATEHOST")
412 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_target, "FIXMEFINALSSTATETARGET")
413 f.write(sstate_hardcode_cmd)
414 bb.utils.copyfile(fixmefn, sstatefixmedir + "/fixmepath")
415 return
416
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500417 bb.note("Replacing fixme paths in sstate package: %s" % (sstate_hardcode_cmd))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500418 subprocess.check_call(sstate_hardcode_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500419
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800420 # Need to remove this or we'd copy it into the target directory and may
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500421 # conflict with another writer
422 os.remove(fixmefn)
423}
424
425def sstate_clean_cachefile(ss, d):
426 import oe.path
427
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500428 sstatepkgfile = d.getVar('SSTATE_PATHSPEC') + "*_" + ss['task'] + ".tgz*"
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300429 if d.getVarFlag('do_%s' % ss['task'], 'task'):
430 bb.note("Removing %s" % sstatepkgfile)
431 oe.path.remove(sstatepkgfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500432
433def sstate_clean_cachefiles(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500434 for task in (d.getVar('SSTATETASKS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500435 ld = d.createCopy()
436 ss = sstate_state_fromvars(ld, task)
437 sstate_clean_cachefile(ss, ld)
438
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500439def sstate_clean_manifest(manifest, d, prefix=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500440 import oe.path
441
442 mfile = open(manifest)
443 entries = mfile.readlines()
444 mfile.close()
445
446 for entry in entries:
447 entry = entry.strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500448 if prefix and not entry.startswith("/"):
449 entry = prefix + "/" + entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 bb.debug(2, "Removing manifest: %s" % entry)
451 # We can race against another package populating directories as we're removing them
452 # so we ignore errors here.
453 try:
454 if entry.endswith("/"):
455 if os.path.islink(entry[:-1]):
456 os.remove(entry[:-1])
457 elif os.path.exists(entry) and len(os.listdir(entry)) == 0:
458 os.rmdir(entry[:-1])
459 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500460 os.remove(entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500461 except OSError:
462 pass
463
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600464 postrm = manifest + ".postrm"
465 if os.path.exists(manifest + ".postrm"):
466 import subprocess
467 os.chmod(postrm, 0o755)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500468 subprocess.check_call(postrm, shell=True)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600469 oe.path.remove(postrm)
470
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500471 oe.path.remove(manifest)
472
473def sstate_clean(ss, d):
474 import oe.path
475 import glob
476
477 d2 = d.createCopy()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500478 stamp_clean = d.getVar("STAMPCLEAN")
479 extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500480 if extrainf:
481 d2.setVar("SSTATE_MANMACH", extrainf)
482 wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
483 else:
484 wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
485
486 manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
487
488 if os.path.exists(manifest):
489 locks = []
490 for lock in ss['lockfiles-shared']:
491 locks.append(bb.utils.lockfile(lock))
492 for lock in ss['lockfiles']:
493 locks.append(bb.utils.lockfile(lock))
494
495 sstate_clean_manifest(manifest, d)
496
497 for lock in locks:
498 bb.utils.unlockfile(lock)
499
500 # Remove the current and previous stamps, but keep the sigdata.
501 #
502 # The glob() matches do_task* which may match multiple tasks, for
503 # example: do_package and do_package_write_ipk, so we need to
504 # exactly match *.do_task.* and *.do_task_setscene.*
505 rm_stamp = '.do_%s.' % ss['task']
506 rm_setscene = '.do_%s_setscene.' % ss['task']
507 # For BB_SIGNATURE_HANDLER = "noop"
508 rm_nohash = ".do_%s" % ss['task']
509 for stfile in glob.glob(wildcard_stfile):
510 # Keep the sigdata
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500511 if ".sigdata." in stfile or ".sigbasedata." in stfile:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500512 continue
513 # Preserve taint files in the stamps directory
514 if stfile.endswith('.taint'):
515 continue
516 if rm_stamp in stfile or rm_setscene in stfile or \
517 stfile.endswith(rm_nohash):
518 oe.path.remove(stfile)
519
520sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
521
522CLEANFUNCS += "sstate_cleanall"
523
524python sstate_cleanall() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500525 bb.note("Removing shared state for package %s" % d.getVar('PN'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500526
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500527 manifest_dir = d.getVar('SSTATE_MANIFESTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500528 if not os.path.exists(manifest_dir):
529 return
530
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500531 tasks = d.getVar('SSTATETASKS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500532 for name in tasks:
533 ld = d.createCopy()
534 shared_state = sstate_state_fromvars(ld, name)
535 sstate_clean(shared_state, ld)
536}
537
538python sstate_hardcode_path () {
539 import subprocess, platform
540
541 # Need to remove hardcoded paths and fix these when we install the
542 # staging packages.
543 #
544 # Note: the logic in this function needs to match the reverse logic
545 # in sstate_installpkg(ss, d)
546
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500547 staging_target = d.getVar('RECIPE_SYSROOT')
548 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
549 sstate_builddir = d.getVar('SSTATE_BUILDDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550
Brad Bishop316dfdd2018-06-25 12:45:53 -0400551 sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500552 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500553 sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500554 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
555 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400556 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500557 else:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400558 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
559 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500561 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500562 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500563 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500564 sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500565 sstate_grep_cmd += " -e '%s'" % (fixme_path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500566
567 fixmefn = sstate_builddir + "fixmepath"
568
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500569 sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500570 sstate_filelist_cmd = "tee %s" % (fixmefn)
571
572 # fixmepath file needs relative paths, drop sstate_builddir prefix
573 sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
574
575 xargs_no_empty_run_cmd = '--no-run-if-empty'
576 if platform.system() == 'Darwin':
577 xargs_no_empty_run_cmd = ''
578
579 # Limit the fixpaths and sed operations based on the initial grep search
580 # This has the side effect of making sure the vfs cache is hot
581 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)
582
583 bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500584 subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500585
586 # If the fixmefn is empty, remove it..
587 if os.stat(fixmefn).st_size == 0:
588 os.remove(fixmefn)
589 else:
590 bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500591 subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500592}
593
594def sstate_package(ss, d):
595 import oe.path
596
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500597 tmpdir = d.getVar('TMPDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500598
599 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500600 sstatepkg = d.getVar('SSTATE_PKG') + '_'+ ss['task'] + ".tgz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500601 bb.utils.remove(sstatebuild, recurse=True)
602 bb.utils.mkdirhier(sstatebuild)
603 bb.utils.mkdirhier(os.path.dirname(sstatepkg))
604 for state in ss['dirs']:
605 if not os.path.exists(state[1]):
606 continue
607 srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500608 # Find and error for absolute symlinks. We could attempt to relocate but its not
609 # clear where the symlink is relative to in this context. We could add that markup
610 # to sstate tasks but there aren't many of these so better just avoid them entirely.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500611 for walkroot, dirs, files in os.walk(state[1]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500612 for file in files + dirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500613 srcpath = os.path.join(walkroot, file)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500614 if not os.path.islink(srcpath):
615 continue
616 link = os.readlink(srcpath)
617 if not os.path.isabs(link):
618 continue
619 if not link.startswith(tmpdir):
620 continue
621 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 -0500622 bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500623 os.rename(state[1], sstatebuild + state[0])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500624
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500625 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500626 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500627 for plain in ss['plaindirs']:
628 pdir = plain.replace(workdir, sstatebuild)
Brad Bishop977dc1a2019-02-06 16:01:43 -0500629 if sharedworkdir in plain:
630 pdir = plain.replace(sharedworkdir, sstatebuild)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500631 bb.utils.mkdirhier(plain)
632 bb.utils.mkdirhier(pdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500633 os.rename(plain, pdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500634
635 d.setVar('SSTATE_BUILDDIR', sstatebuild)
636 d.setVar('SSTATE_PKG', sstatepkg)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500637 d.setVar('SSTATE_INSTDIR', sstatebuild)
638
639 if d.getVar('SSTATE_SKIP_CREATION') == '1':
640 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500642 for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500643 ['sstate_create_package', 'sstate_sign_package'] + \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500644 (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500645 # All hooks should run in SSTATE_BUILDDIR.
646 bb.build.exec_func(f, d, (sstatebuild,))
647
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500648 bb.siggen.dump_this_task(sstatepkg + ".siginfo", d)
649
650 return
651
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800652def pstaging_fetch(sstatefetch, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500653 import bb.fetch2
654
655 # Only try and fetch if the user has configured a mirror
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500656 mirrors = d.getVar('SSTATE_MIRRORS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500657 if not mirrors:
658 return
659
660 # Copy the data object and override DL_DIR and SRC_URI
661 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500662
663 dldir = localdata.expand("${SSTATE_DIR}")
664 bb.utils.mkdirhier(dldir)
665
666 localdata.delVar('MIRRORS')
667 localdata.setVar('FILESPATH', dldir)
668 localdata.setVar('DL_DIR', dldir)
669 localdata.setVar('PREMIRRORS', mirrors)
670
671 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
672 # we'll want to allow network access for the current set of fetches.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500673 if localdata.getVar('BB_NO_NETWORK') == "1" and localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500674 localdata.delVar('BB_NO_NETWORK')
675
676 # Try a fetch from the sstate mirror, if it fails just return and
677 # we will build the package
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600678 uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
679 'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500680 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600681 uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500682
683 for srcuri in uris:
684 localdata.setVar('SRC_URI', srcuri)
685 try:
686 fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
687 fetcher.download()
688
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500689 except bb.fetch2.BBFetchException:
690 break
691
692def sstate_setscene(d):
693 shared_state = sstate_state_fromvars(d)
694 accelerate = sstate_installpkg(shared_state, d)
695 if not accelerate:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600696 bb.fatal("No suitable staging package found")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500697
698python sstate_task_prefunc () {
699 shared_state = sstate_state_fromvars(d)
700 sstate_clean(shared_state, d)
701}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500702sstate_task_prefunc[dirs] = "${WORKDIR}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500703
704python sstate_task_postfunc () {
705 shared_state = sstate_state_fromvars(d)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500706
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500707 for intercept in shared_state['interceptfuncs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500708 bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
709
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600710 omask = os.umask(0o002)
711 if omask != 0o002:
712 bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500713 sstate_package(shared_state, d)
714 os.umask(omask)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500715
716 sstateinst = d.getVar("SSTATE_INSTDIR")
717 d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
718
719 sstate_installpkgdir(shared_state, d)
720
721 bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500722}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500723sstate_task_postfunc[dirs] = "${WORKDIR}"
724
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500725
726#
727# Shell function to generate a sstate package from a directory
728# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
729#
730sstate_create_package () {
731 TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800732
733 # Use pigz if available
734 OPT="-czS"
735 if [ -x "$(command -v pigz)" ]; then
736 OPT="-I pigz -cS"
737 fi
738
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500739 # Need to handle empty directories
740 if [ "$(ls -A)" ]; then
741 set +e
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800742 tar $OPT -f $TFILE *
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500743 ret=$?
744 if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
745 exit 1
746 fi
747 set -e
748 else
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800749 tar $OPT --file=$TFILE --files-from=/dev/null
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500751 chmod 0664 $TFILE
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500752 mv -f $TFILE ${SSTATE_PKG}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500753}
754
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500755python sstate_sign_package () {
756 from oe.gpg_sign import get_signer
757
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500758 if d.getVar('SSTATE_SIG_KEY'):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500759 signer = get_signer(d, 'local')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500760 sstate_pkg = d.getVar('SSTATE_PKG')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500761 if os.path.exists(sstate_pkg + '.sig'):
762 os.unlink(sstate_pkg + '.sig')
763 signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500764 d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500765}
766
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500767#
768# Shell function to decompress and prepare a package for installation
769# Will be run from within SSTATE_INSTDIR.
770#
771sstate_unpack_package () {
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500772 tar -xvzf ${SSTATE_PKG}
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500773 # update .siginfo atime on local/NFS mirror
774 [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500775 # Use "! -w ||" to return true for read only files
776 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500777 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig
778 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500779}
780
781BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
782
783def sstate_checkhashes(sq_fn, sq_task, sq_hash, sq_hashfn, d, siginfo=False):
784
785 ret = []
786 missed = []
787 extension = ".tgz"
788 if siginfo:
789 extension = extension + ".siginfo"
790
791 def getpathcomponents(task, d):
792 # Magic data from BB_HASHFILENAME
793 splithashfn = sq_hashfn[task].split(" ")
794 spec = splithashfn[1]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500795 if splithashfn[0] == "True":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500796 extrapath = d.getVar("NATIVELSBSTRING") + "/"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500797 else:
798 extrapath = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500799
800 tname = sq_task[task][3:]
801
802 if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
803 spec = splithashfn[2]
804 extrapath = ""
805
806 return spec, extrapath, tname
807
808
809 for task in range(len(sq_fn)):
810
811 spec, extrapath, tname = getpathcomponents(task, d)
812
813 sstatefile = d.expand("${SSTATE_DIR}/" + extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + extension)
814
815 if os.path.exists(sstatefile):
816 bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
817 ret.append(task)
818 continue
819 else:
820 missed.append(task)
821 bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
822
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500823 mirrors = d.getVar("SSTATE_MIRRORS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500824 if mirrors:
825 # Copy the data object and override DL_DIR and SRC_URI
826 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500827
828 dldir = localdata.expand("${SSTATE_DIR}")
829 localdata.delVar('MIRRORS')
830 localdata.setVar('FILESPATH', dldir)
831 localdata.setVar('DL_DIR', dldir)
832 localdata.setVar('PREMIRRORS', mirrors)
833
834 bb.debug(2, "SState using premirror of: %s" % mirrors)
835
836 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
837 # we'll want to allow network access for the current set of fetches.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500838 if localdata.getVar('BB_NO_NETWORK') == "1" and localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK') == "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500839 localdata.delVar('BB_NO_NETWORK')
840
841 from bb.fetch2 import FetchConnectionCache
842 def checkstatus_init(thread_worker):
843 thread_worker.connection_cache = FetchConnectionCache()
844
845 def checkstatus_end(thread_worker):
846 thread_worker.connection_cache.close_connections()
847
848 def checkstatus(thread_worker, arg):
849 (task, sstatefile) = arg
850
851 localdata2 = bb.data.createCopy(localdata)
852 srcuri = "file://" + sstatefile
853 localdata.setVar('SRC_URI', srcuri)
854 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
855
856 try:
857 fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
858 connection_cache=thread_worker.connection_cache)
859 fetcher.checkstatus()
860 bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
861 ret.append(task)
862 if task in missed:
863 missed.remove(task)
864 except:
865 missed.append(task)
866 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600867 pass
Brad Bishop316dfdd2018-06-25 12:45:53 -0400868 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869
870 tasklist = []
871 for task in range(len(sq_fn)):
872 if task in ret:
873 continue
874 spec, extrapath, tname = getpathcomponents(task, d)
875 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + extension)
876 tasklist.append((task, sstatefile))
877
878 if tasklist:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400879 msg = "Checking sstate mirror object availability"
880 bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600881
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500882 import multiprocessing
883 nproc = min(multiprocessing.cpu_count(), len(tasklist))
884
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600885 bb.event.enable_threadlock()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500886 pool = oe.utils.ThreadedPool(nproc, len(tasklist),
887 worker_init=checkstatus_init, worker_end=checkstatus_end)
888 for t in tasklist:
889 pool.add_task(checkstatus, t)
890 pool.start()
891 pool.wait_completion()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600892 bb.event.disable_threadlock()
893
Brad Bishop316dfdd2018-06-25 12:45:53 -0400894 bb.event.fire(bb.event.ProcessFinished(msg), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500895
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500896 inheritlist = d.getVar("INHERIT")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500897 if "toaster" in inheritlist:
898 evdata = {'missed': [], 'found': []};
899 for task in missed:
900 spec, extrapath, tname = getpathcomponents(task, d)
901 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + ".tgz")
902 evdata['missed'].append( (sq_fn[task], sq_task[task], sq_hash[task], sstatefile ) )
903 for task in ret:
904 spec, extrapath, tname = getpathcomponents(task, d)
905 sstatefile = d.expand(extrapath + generate_sstatefn(spec, sq_hash[task], d) + "_" + tname + ".tgz")
906 evdata['found'].append( (sq_fn[task], sq_task[task], sq_hash[task], sstatefile ) )
907 bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
908
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800909 # Print some summary statistics about the current task completion and how much sstate
910 # reuse there was. Avoid divide by zero errors.
911 total = len(sq_fn)
912 currentcount = d.getVar("BB_SETSCENE_STAMPCURRENT_COUNT") or 0
913 complete = 0
914 if currentcount:
915 complete = (len(ret) + currentcount) / (total + currentcount) * 100
916 match = 0
917 if total:
918 match = len(ret) / total * 100
919 bb.plain("Sstate summary: Wanted %d Found %d Missed %d Current %d (%d%% match, %d%% complete)" % (total, len(ret), len(missed), currentcount, match, complete))
920
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500921 if hasattr(bb.parse.siggen, "checkhashes"):
922 bb.parse.siggen.checkhashes(missed, ret, sq_fn, sq_task, sq_hash, sq_hashfn, d)
923
924 return ret
925
926BB_SETSCENE_DEPVALID = "setscene_depvalid"
927
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500928def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500929 # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
930 # task is included in taskdependees too
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500931 # Return - False - We need this dependency
932 # - True - We can skip this dependency
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800933 import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500934
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500935 def logit(msg, log):
936 if log is not None:
937 log.append(msg)
938 else:
939 bb.debug(2, msg)
940
941 logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500942
943 def isNativeCross(x):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500944 return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500945
946 # We only need to trigger populate_lic through direct dependencies
947 if taskdependees[task][1] == "do_populate_lic":
948 return True
949
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500950 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
951 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
952 return True
953
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500954 # We only need to trigger packagedata through direct dependencies
955 # but need to preserve packagedata on packagedata links
956 if taskdependees[task][1] == "do_packagedata":
957 for dep in taskdependees:
958 if taskdependees[dep][1] == "do_packagedata":
959 return False
960 return True
961
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500962 for dep in taskdependees:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500963 logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500964 if task == dep:
965 continue
966 if dep in notneeded:
967 continue
968 # do_package_write_* and do_package doesn't need do_package
969 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']:
970 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500971 # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
972 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
973 return False
974 # do_package/packagedata/package_qa don't need do_populate_sysroot
975 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 -0500976 continue
977 # Native/Cross packages don't exist and are noexec anyway
978 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']:
979 continue
980
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500981 # This is due to the [depends] in useradd.bbclass complicating matters
982 # The logic *is* reversed here due to the way hard setscene dependencies are injected
983 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':
984 continue
985
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500986 # Consider sysroot depending on sysroot tasks
987 if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800988 # Allow excluding certain recursive dependencies. If a recipe needs it should add a
989 # specific dependency itself, rather than relying on one of its dependees to pull
990 # them in.
991 # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
992 not_needed = False
993 excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
994 if excludedeps is None:
995 # Cache the regular expressions for speed
996 excludedeps = []
997 for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
998 excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
999 d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
1000 for excl in excludedeps:
1001 if excl[0].match(taskdependees[dep][0]):
1002 if excl[1].match(taskdependees[task][0]):
1003 not_needed = True
1004 break
1005 if not_needed:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001006 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001007 # For meta-extsdk-toolchain we want all sysroot dependencies
1008 if taskdependees[dep][0] == 'meta-extsdk-toolchain':
1009 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001010 # Native/Cross populate_sysroot need their dependencies
1011 if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
1012 return False
1013 # Target populate_sysroot depended on by cross tools need to be installed
1014 if isNativeCross(taskdependees[dep][0]):
1015 return False
1016 # Native/cross tools depended upon by target sysroot are not needed
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001017 # Add an exception for shadow-native as required by useradd.bbclass
1018 if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001019 continue
1020 # Target populate_sysroot need their dependencies
1021 return False
1022
1023 if taskdependees[task][1] == 'do_shared_workdir':
1024 continue
1025
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001026 if taskdependees[dep][1] == "do_populate_lic":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001027 continue
1028
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001029
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001030 # Safe fallthrough default
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001031 logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001032 return False
1033 return True
1034
1035addhandler sstate_eventhandler
1036sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
1037python sstate_eventhandler() {
1038 d = e.data
1039 # When we write an sstate package we rewrite the SSTATE_PKG
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001040 spkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001041 if not spkg.endswith(".tgz"):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001042 taskname = d.getVar("BB_RUNTASK")[3:]
1043 spec = d.getVar('SSTATE_PKGSPEC')
1044 swspec = d.getVar('SSTATE_SWSPEC')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001045 if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
1046 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
1047 d.setVar("SSTATE_EXTRAPATH", "")
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001048 sstatepkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001049 bb.siggen.dump_this_task(sstatepkg + '_' + taskname + ".tgz" ".siginfo", d)
1050}
1051
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001052SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001053
1054# Event handler which removes manifests and stamps file for
1055# recipes which are no longer reachable in a build where they
1056# once were.
1057# Also optionally removes the workdir of those tasks/recipes
1058#
1059addhandler sstate_eventhandler2
1060sstate_eventhandler2[eventmask] = "bb.event.ReachableStamps"
1061python sstate_eventhandler2() {
1062 import glob
1063 d = e.data
1064 stamps = e.stamps.values()
1065 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001066 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1067 preservestamps = []
1068 if os.path.exists(preservestampfile):
1069 with open(preservestampfile, 'r') as f:
1070 preservestamps = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001071 seen = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001072
1073 # The machine index contains all the stamps this machine has ever seen in this build directory.
1074 # We should only remove things which this machine once accessed but no longer does.
1075 machineindex = set()
1076 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
1077 mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
1078 if os.path.exists(mi):
1079 with open(mi, "r") as f:
1080 machineindex = set(line.strip() for line in f.readlines())
1081
Brad Bishop316dfdd2018-06-25 12:45:53 -04001082 for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001083 toremove = []
1084 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1085 if not os.path.exists(i):
1086 continue
1087 with open(i, "r") as f:
1088 lines = f.readlines()
1089 for l in lines:
1090 (stamp, manifest, workdir) = l.split()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001091 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001092 toremove.append(l)
1093 if stamp not in seen:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001094 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001095 seen.append(stamp)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001096
1097 if toremove:
Brad Bishop316dfdd2018-06-25 12:45:53 -04001098 msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
1099 bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001100
Brad Bishop316dfdd2018-06-25 12:45:53 -04001101 removed = 0
1102 for r in toremove:
1103 (stamp, manifest, workdir) = r.split()
1104 for m in glob.glob(manifest + ".*"):
1105 if m.endswith(".postrm"):
1106 continue
1107 sstate_clean_manifest(m, d)
1108 bb.utils.remove(stamp + "*")
1109 if removeworkdir:
1110 bb.utils.remove(workdir, recurse = True)
1111 lines.remove(r)
1112 removed = removed + 1
1113 bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
1114
1115 bb.event.fire(bb.event.ProcessFinished(msg), d)
1116
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001117 with open(i, "w") as f:
1118 for l in lines:
1119 f.write(l)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001120 machineindex |= set(stamps)
1121 with open(mi, "w") as f:
1122 for l in machineindex:
1123 f.write(l + "\n")
1124
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001125 if preservestamps:
1126 os.remove(preservestampfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001127}