blob: 375196ef21c94c00eb427fa3360f88d0f6d7fef1 [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
Andrew Geissler82c905d2020-04-13 13:39:40 -05006def generate_sstatefn(spec, hash, taskname, siginfo, d):
7 if taskname is None:
8 return ""
9 extension = ".tgz"
10 # 8 chars reserved for siginfo
11 limit = 254 - 8
12 if siginfo:
13 limit = 254
14 extension = ".tgz.siginfo"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015 if not hash:
16 hash = "INVALID"
Andrew Geissler82c905d2020-04-13 13:39:40 -050017 fn = spec + hash + "_" + taskname + extension
18 # If the filename is too long, attempt to reduce it
19 if len(fn) > limit:
20 components = spec.split(":")
21 # Fields 0,5,6 are mandatory, 1 is most useful, 2,3,4 are just for information
22 # 7 is for the separators
23 avail = (254 - len(hash + "_" + taskname + extension) - len(components[0]) - len(components[1]) - len(components[5]) - len(components[6]) - 7) // 3
24 components[2] = components[2][:avail]
25 components[3] = components[3][:avail]
26 components[4] = components[4][:avail]
27 spec = ":".join(components)
28 fn = spec + hash + "_" + taskname + extension
29 if len(fn) > limit:
30 bb.fatal("Unable to reduce sstate name to less than 255 chararacters")
31 return hash[:2] + "/" + hash[2:4] + "/" + fn
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032
33SSTATE_PKGARCH = "${PACKAGE_ARCH}"
34SSTATE_PKGSPEC = "sstate:${PN}:${PACKAGE_ARCH}${TARGET_VENDOR}-${TARGET_OS}:${PV}:${PR}:${SSTATE_PKGARCH}:${SSTATE_VERSION}:"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050035SSTATE_SWSPEC = "sstate:${PN}::${PV}:${PR}::${SSTATE_VERSION}:"
Andrew Geissler82c905d2020-04-13 13:39:40 -050036SSTATE_PKGNAME = "${SSTATE_EXTRAPATH}${@generate_sstatefn(d.getVar('SSTATE_PKGSPEC'), d.getVar('BB_UNIHASH'), d.getVar('SSTATE_CURRTASK'), False, d)}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050037SSTATE_PKG = "${SSTATE_DIR}/${SSTATE_PKGNAME}"
38SSTATE_EXTRAPATH = ""
39SSTATE_EXTRAPATHWILDCARD = ""
Andrew Geissler82c905d2020-04-13 13:39:40 -050040SSTATE_PATHSPEC = "${SSTATE_DIR}/${SSTATE_EXTRAPATHWILDCARD}*/*/${SSTATE_PKGSPEC}*_${SSTATE_PATH_CURRTASK}.tgz*"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050041
Patrick Williamsc0f7c042017-02-23 20:41:17 -060042# explicitly make PV to depend on evaluated value of PV variable
43PV[vardepvalue] = "${PV}"
44
Patrick Williamsc124f4f2015-09-15 14:41:29 -050045# We don't want the sstate to depend on things like the distro string
46# of the system, we let the sstate paths take care of this.
47SSTATE_EXTRAPATH[vardepvalue] = ""
Brad Bishop19323692019-04-05 15:28:33 -040048SSTATE_EXTRAPATHWILDCARD[vardepvalue] = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -050049
50# For multilib rpm the allarch packagegroup files can overwrite (in theory they're identical)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080051SSTATE_DUPWHITELIST = "${DEPLOY_DIR}/licenses/"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050052# Avoid docbook/sgml catalog warnings for now
53SSTATE_DUPWHITELIST += "${STAGING_ETCDIR_NATIVE}/sgml ${STAGING_DATADIR_NATIVE}/sgml"
Brad Bishop316dfdd2018-06-25 12:45:53 -040054# sdk-provides-dummy-nativesdk and nativesdk-buildtools-perl-dummy overlap for different SDKMACHINE
55SSTATE_DUPWHITELIST += "${DEPLOY_DIR_RPM}/sdk_provides_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/sdk-provides-dummy-nativesdk/"
56SSTATE_DUPWHITELIST += "${DEPLOY_DIR_RPM}/buildtools_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/buildtools-dummy-nativesdk/"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080057# target-sdk-provides-dummy overlaps that allarch is disabled when multilib is used
58SSTATE_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 -050059# Archive the sources for many architectures in one deploy folder
60SSTATE_DUPWHITELIST += "${DEPLOY_DIR_SRC}"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080061# ovmf/grub-efi/systemd-boot/intel-microcode multilib recipes can generate identical overlapping files
62SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/ovmf"
63SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/grub-efi"
64SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/systemd-boot"
65SSTATE_DUPWHITELIST += "${DEPLOY_DIR_IMAGE}/microcode"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066
Brad Bishop6e60e8b2018-02-01 10:27:11 -050067SSTATE_SCAN_FILES ?= "*.la *-config *_config postinst-*"
68SSTATE_SCAN_CMD ??= 'find ${SSTATE_BUILDDIR} \( -name "${@"\" -o -name \"".join(d.getVar("SSTATE_SCAN_FILES").split())}" \) -type f'
69SSTATE_SCAN_CMD_NATIVE ??= 'grep -Irl -e ${RECIPE_SYSROOT} -e ${RECIPE_SYSROOT_NATIVE} -e ${HOSTTOOLS_DIR} ${SSTATE_BUILDDIR}'
Patrick Williamsc124f4f2015-09-15 14:41:29 -050070
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050071BB_HASHFILENAME = "False ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050072
73SSTATE_ARCHS = " \
74 ${BUILD_ARCH} \
75 ${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS} \
76 ${BUILD_ARCH}_${TARGET_ARCH} \
77 ${SDK_ARCH}_${SDK_OS} \
78 ${SDK_ARCH}_${PACKAGE_ARCH} \
79 allarch \
80 ${PACKAGE_ARCH} \
Brad Bishop316dfdd2018-06-25 12:45:53 -040081 ${PACKAGE_EXTRA_ARCHS} \
82 ${MACHINE_ARCH}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050083
84SSTATE_MANMACH ?= "${SSTATE_PKGARCH}"
85
86SSTATECREATEFUNCS = "sstate_hardcode_path"
Brad Bishop19323692019-04-05 15:28:33 -040087SSTATECREATEFUNCS[vardeps] = "SSTATE_SCAN_FILES"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050088SSTATEPOSTCREATEFUNCS = ""
89SSTATEPREINSTFUNCS = ""
90SSTATEPOSTUNPACKFUNCS = "sstate_hardcode_path_unpack"
91SSTATEPOSTINSTFUNCS = ""
Brad Bishop6e60e8b2018-02-01 10:27:11 -050092EXTRA_STAGING_FIXMES ?= "HOSTTOOLS_DIR"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050094# Check whether sstate exists for tasks that support sstate and are in the
95# locked signatures file.
96SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK ?= 'error'
97
98# Check whether the task's computed hash matches the task's hash in the
99# locked signatures file.
100SIGGEN_LOCKEDSIGS_TASKSIG_CHECK ?= "error"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500101
102# The GnuPG key ID and passphrase to use to sign sstate archives (or unset to
103# not sign)
104SSTATE_SIG_KEY ?= ""
105SSTATE_SIG_PASSPHRASE ?= ""
106# Whether to verify the GnUPG signatures when extracting sstate archives
107SSTATE_VERIFY_SIG ?= "0"
108
Brad Bishop19323692019-04-05 15:28:33 -0400109SSTATE_HASHEQUIV_METHOD ?= "oe.sstatesig.OEOuthashBasic"
110SSTATE_HASHEQUIV_METHOD[doc] = "The fully-qualified function used to calculate \
111 the output hash for a task, which in turn is used to determine equivalency. \
112 "
113
Brad Bishop19323692019-04-05 15:28:33 -0400114SSTATE_HASHEQUIV_REPORT_TASKDATA ?= "0"
115SSTATE_HASHEQUIV_REPORT_TASKDATA[doc] = "Report additional useful data to the \
116 hash equivalency server, such as PN, PV, taskname, etc. This information \
117 is very useful for developers looking at task data, but may leak sensitive \
118 data if the equivalence server is public. \
119 "
120
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500121python () {
122 if bb.data.inherits_class('native', d):
123 d.setVar('SSTATE_PKGARCH', d.getVar('BUILD_ARCH', False))
124 elif bb.data.inherits_class('crosssdk', d):
125 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}"))
126 elif bb.data.inherits_class('cross', d):
127 d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${TARGET_ARCH}"))
128 elif bb.data.inherits_class('nativesdk', d):
129 d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${SDK_OS}"))
130 elif bb.data.inherits_class('cross-canadian', d):
131 d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${PACKAGE_ARCH}"))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500132 elif bb.data.inherits_class('allarch', d) and d.getVar("PACKAGE_ARCH") == "all":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500133 d.setVar('SSTATE_PKGARCH', "allarch")
134 else:
135 d.setVar('SSTATE_MANMACH', d.expand("${PACKAGE_ARCH}"))
136
137 if bb.data.inherits_class('native', d) or bb.data.inherits_class('crosssdk', d) or bb.data.inherits_class('cross', d):
138 d.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500139 d.setVar('BB_HASHFILENAME', "True ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}")
Brad Bishop19323692019-04-05 15:28:33 -0400140 d.setVar('SSTATE_EXTRAPATHWILDCARD', "${NATIVELSBSTRING}/")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500141
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500142 unique_tasks = sorted(set((d.getVar('SSTATETASKS') or "").split()))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500143 d.setVar('SSTATETASKS', " ".join(unique_tasks))
144 for task in unique_tasks:
145 d.prependVarFlag(task, 'prefuncs', "sstate_task_prefunc ")
146 d.appendVarFlag(task, 'postfuncs', " sstate_task_postfunc")
147}
148
149def sstate_init(task, d):
150 ss = {}
151 ss['task'] = task
152 ss['dirs'] = []
153 ss['plaindirs'] = []
154 ss['lockfiles'] = []
155 ss['lockfiles-shared'] = []
156 return ss
157
158def sstate_state_fromvars(d, task = None):
159 if task is None:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500160 task = d.getVar('BB_CURRENTTASK')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500161 if not task:
162 bb.fatal("sstate code running without task context?!")
163 task = task.replace("_setscene", "")
164
165 if task.startswith("do_"):
166 task = task[3:]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500167 inputs = (d.getVarFlag("do_" + task, 'sstate-inputdirs') or "").split()
168 outputs = (d.getVarFlag("do_" + task, 'sstate-outputdirs') or "").split()
169 plaindirs = (d.getVarFlag("do_" + task, 'sstate-plaindirs') or "").split()
170 lockfiles = (d.getVarFlag("do_" + task, 'sstate-lockfile') or "").split()
171 lockfilesshared = (d.getVarFlag("do_" + task, 'sstate-lockfile-shared') or "").split()
172 interceptfuncs = (d.getVarFlag("do_" + task, 'sstate-interceptfuncs') or "").split()
173 fixmedir = d.getVarFlag("do_" + task, 'sstate-fixmedir') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500174 if not task or len(inputs) != len(outputs):
175 bb.fatal("sstate variables not setup correctly?!")
176
177 if task == "populate_lic":
178 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
179 d.setVar("SSTATE_EXTRAPATH", "")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500180 d.setVar('SSTATE_EXTRAPATHWILDCARD', "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500181
182 ss = sstate_init(task, d)
183 for i in range(len(inputs)):
184 sstate_add(ss, inputs[i], outputs[i], d)
185 ss['lockfiles'] = lockfiles
186 ss['lockfiles-shared'] = lockfilesshared
187 ss['plaindirs'] = plaindirs
188 ss['interceptfuncs'] = interceptfuncs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500189 ss['fixmedir'] = fixmedir
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500190 return ss
191
192def sstate_add(ss, source, dest, d):
193 if not source.endswith("/"):
194 source = source + "/"
195 if not dest.endswith("/"):
196 dest = dest + "/"
197 source = os.path.normpath(source)
198 dest = os.path.normpath(dest)
199 srcbase = os.path.basename(source)
200 ss['dirs'].append([srcbase, source, dest])
201 return ss
202
203def sstate_install(ss, d):
204 import oe.path
205 import oe.sstatesig
206 import subprocess
207
208 sharedfiles = []
209 shareddirs = []
210 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
211
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500212 sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
213
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500214 manifest, d2 = oe.sstatesig.sstate_get_manifest_filename(ss['task'], d)
215
216 if os.access(manifest, os.R_OK):
217 bb.fatal("Package already staged (%s)?!" % manifest)
218
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600219 d.setVar("SSTATE_INST_POSTRM", manifest + ".postrm")
220
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500221 locks = []
222 for lock in ss['lockfiles-shared']:
223 locks.append(bb.utils.lockfile(lock, True))
224 for lock in ss['lockfiles']:
225 locks.append(bb.utils.lockfile(lock))
226
227 for state in ss['dirs']:
228 bb.debug(2, "Staging files from %s to %s" % (state[1], state[2]))
229 for walkroot, dirs, files in os.walk(state[1]):
230 for file in files:
231 srcpath = os.path.join(walkroot, file)
232 dstpath = srcpath.replace(state[1], state[2])
233 #bb.debug(2, "Staging %s to %s" % (srcpath, dstpath))
234 sharedfiles.append(dstpath)
235 for dir in dirs:
236 srcdir = os.path.join(walkroot, dir)
237 dstdir = srcdir.replace(state[1], state[2])
238 #bb.debug(2, "Staging %s to %s" % (srcdir, dstdir))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500239 if os.path.islink(srcdir):
240 sharedfiles.append(dstdir)
241 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500242 if not dstdir.endswith("/"):
243 dstdir = dstdir + "/"
244 shareddirs.append(dstdir)
245
246 # Check the file list for conflicts against files which already exist
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500247 whitelist = (d.getVar("SSTATE_DUPWHITELIST") or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500248 match = []
249 for f in sharedfiles:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500250 if os.path.exists(f) and not os.path.islink(f):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500251 f = os.path.normpath(f)
252 realmatch = True
253 for w in whitelist:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600254 w = os.path.normpath(w)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500255 if f.startswith(w):
256 realmatch = False
257 break
258 if realmatch:
259 match.append(f)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500260 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 -0500261 search_output = subprocess.Popen(sstate_search_cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500262 if search_output:
263 match.append(" (matched in %s)" % search_output.decode('utf-8').rstrip())
264 else:
265 match.append(" (not matched to any task)")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500266 if match:
267 bb.error("The recipe %s is trying to install files into a shared " \
268 "area when those files already exist. Those files and their manifest " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500269 "location are:\n %s\nPlease verify which recipe should provide the " \
270 "above files.\n\nThe build has stopped, as continuing in this scenario WILL " \
271 "break things - if not now, possibly in the future (we've seen builds fail " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500272 "several months later). If the system knew how to recover from this " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500273 "automatically it would, however there are several different scenarios " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274 "which can result in this and we don't know which one this is. It may be " \
275 "you have switched providers of something like virtual/kernel (e.g. from " \
276 "linux-yocto to linux-yocto-dev), in that case you need to execute the " \
277 "clean task for both recipes and it will resolve this error. It may be " \
278 "you changed DISTRO_FEATURES from systemd to udev or vice versa. Cleaning " \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500279 "those recipes should again resolve this error, however switching " \
280 "DISTRO_FEATURES on an existing build directory is not supported - you " \
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500281 "should really clean out tmp and rebuild (reusing sstate should be safe). " \
282 "It could be the overlapping files detected are harmless in which case " \
283 "adding them to SSTATE_DUPWHITELIST may be the correct solution. It could " \
284 "also be your build is including two different conflicting versions of " \
285 "things (e.g. bluez 4 and bluez 5 and the correct solution for that would " \
286 "be to resolve the conflict. If in doubt, please ask on the mailing list, " \
287 "sharing the error and filelist above." % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500288 (d.getVar('PN'), "\n ".join(match)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500289 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.")
290
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500291 if ss['fixmedir'] and os.path.exists(ss['fixmedir'] + "/fixmepath.cmd"):
292 sharedfiles.append(ss['fixmedir'] + "/fixmepath.cmd")
293 sharedfiles.append(ss['fixmedir'] + "/fixmepath")
294
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500295 # Write out the manifest
296 f = open(manifest, "w")
297 for file in sharedfiles:
298 f.write(file + "\n")
299
300 # We want to ensure that directories appear at the end of the manifest
301 # so that when we test to see if they should be deleted any contents
302 # added by the task will have been removed first.
303 dirs = sorted(shareddirs, key=len)
304 # Must remove children first, which will have a longer path than the parent
305 for di in reversed(dirs):
306 f.write(di + "\n")
307 f.close()
308
309 # Append to the list of manifests for this PACKAGE_ARCH
310
311 i = d2.expand("${SSTATE_MANIFESTS}/index-${SSTATE_MANMACH}")
312 l = bb.utils.lockfile(i + ".lock")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500313 filedata = d.getVar("STAMP") + " " + d2.getVar("SSTATE_MANFILEPREFIX") + " " + d.getVar("WORKDIR") + "\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500314 manifests = []
315 if os.path.exists(i):
316 with open(i, "r") as f:
317 manifests = f.readlines()
318 if filedata not in manifests:
319 with open(i, "a+") as f:
320 f.write(filedata)
321 bb.utils.unlockfile(l)
322
323 # Run the actual file install
324 for state in ss['dirs']:
325 if os.path.exists(state[1]):
326 oe.path.copyhardlinktree(state[1], state[2])
327
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500328 for postinst in (d.getVar('SSTATEPOSTINSTFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500329 # All hooks should run in the SSTATE_INSTDIR
330 bb.build.exec_func(postinst, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500331
332 for lock in locks:
333 bb.utils.unlockfile(lock)
334
335sstate_install[vardepsexclude] += "SSTATE_DUPWHITELIST STATE_MANMACH SSTATE_MANFILEPREFIX"
336sstate_install[vardeps] += "${SSTATEPOSTINSTFUNCS}"
337
338def sstate_installpkg(ss, d):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500339 from oe.gpg_sign import get_signer
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500340
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500341 sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
Andrew Geissler82c905d2020-04-13 13:39:40 -0500342 d.setVar("SSTATE_CURRTASK", ss['task'])
343 sstatefetch = d.getVar('SSTATE_PKGNAME')
344 sstatepkg = d.getVar('SSTATE_PKG')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500345
346 if not os.path.exists(sstatepkg):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800347 pstaging_fetch(sstatefetch, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500348
349 if not os.path.isfile(sstatepkg):
Brad Bishop08902b02019-08-20 09:16:51 -0400350 bb.note("Sstate package %s does not exist" % sstatepkg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500351 return False
352
353 sstate_clean(ss, d)
354
355 d.setVar('SSTATE_INSTDIR', sstateinst)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500356
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500357 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Andrew Geissler4ed12e12020-06-05 18:00:41 -0500358 if not os.path.isfile(sstatepkg + '.sig'):
359 bb.warn("No signature file for sstate package %s, skipping acceleration..." % sstatepkg)
360 return False
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500361 signer = get_signer(d, 'local')
362 if not signer.verify(sstatepkg + '.sig'):
Brad Bishop08902b02019-08-20 09:16:51 -0400363 bb.warn("Cannot verify signature on sstate package %s, skipping acceleration..." % sstatepkg)
364 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500366 # Empty sstateinst directory, ensure its clean
367 if os.path.exists(sstateinst):
368 oe.path.remove(sstateinst)
369 bb.utils.mkdirhier(sstateinst)
370
371 sstateinst = d.getVar("SSTATE_INSTDIR")
372 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
373
374 for f in (d.getVar('SSTATEPREINSTFUNCS') or '').split() + ['sstate_unpack_package']:
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500375 # All hooks should run in the SSTATE_INSTDIR
376 bb.build.exec_func(f, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500377
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500378 return sstate_installpkgdir(ss, d)
379
380def sstate_installpkgdir(ss, d):
381 import oe.path
382 import subprocess
383
384 sstateinst = d.getVar("SSTATE_INSTDIR")
385 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
386
387 for f in (d.getVar('SSTATEPOSTUNPACKFUNCS') or '').split():
388 # All hooks should run in the SSTATE_INSTDIR
389 bb.build.exec_func(f, d, (sstateinst,))
390
391 def prepdir(dir):
392 # remove dir if it exists, ensure any parent directories do exist
393 if os.path.exists(dir):
394 oe.path.remove(dir)
395 bb.utils.mkdirhier(dir)
396 oe.path.remove(dir)
397
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500398 for state in ss['dirs']:
399 prepdir(state[1])
400 os.rename(sstateinst + state[0], state[1])
401 sstate_install(ss, d)
402
403 for plain in ss['plaindirs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500404 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500405 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406 src = sstateinst + "/" + plain.replace(workdir, '')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500407 if sharedworkdir in plain:
408 src = sstateinst + "/" + plain.replace(sharedworkdir, '')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500409 dest = plain
410 bb.utils.mkdirhier(src)
411 prepdir(dest)
412 os.rename(src, dest)
413
414 return True
415
416python sstate_hardcode_path_unpack () {
417 # Fixup hardcoded paths
418 #
419 # Note: The logic below must match the reverse logic in
420 # sstate_hardcode_path(d)
421 import subprocess
422
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500423 sstateinst = d.getVar('SSTATE_INSTDIR')
424 sstatefixmedir = d.getVar('SSTATE_FIXMEDIR')
425 fixmefn = sstateinst + "fixmepath"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500426 if os.path.isfile(fixmefn):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500427 staging_target = d.getVar('RECIPE_SYSROOT')
428 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500429
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500430 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500431 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRHOST:%s:g'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500432 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
433 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (staging_target, staging_host)
434 else:
435 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g'" % (staging_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500436
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500437 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500438 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500439 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500440 sstate_sed_cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
441
442 # Add sstateinst to each filename in fixmepath, use xargs to efficiently call sed
443 sstate_hardcode_cmd = "sed -e 's:^:%s:g' %s | xargs %s" % (sstateinst, fixmefn, sstate_sed_cmd)
444
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500445 # Defer do_populate_sysroot relocation command
446 if sstatefixmedir:
447 bb.utils.mkdirhier(sstatefixmedir)
448 with open(sstatefixmedir + "/fixmepath.cmd", "w") as f:
449 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(fixmefn, sstatefixmedir + "/fixmepath")
450 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(sstateinst, "FIXMEFINALSSTATEINST")
451 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_host, "FIXMEFINALSSTATEHOST")
452 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_target, "FIXMEFINALSSTATETARGET")
453 f.write(sstate_hardcode_cmd)
454 bb.utils.copyfile(fixmefn, sstatefixmedir + "/fixmepath")
455 return
456
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500457 bb.note("Replacing fixme paths in sstate package: %s" % (sstate_hardcode_cmd))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500458 subprocess.check_call(sstate_hardcode_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500459
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800460 # Need to remove this or we'd copy it into the target directory and may
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500461 # conflict with another writer
462 os.remove(fixmefn)
463}
464
465def sstate_clean_cachefile(ss, d):
466 import oe.path
467
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300468 if d.getVarFlag('do_%s' % ss['task'], 'task'):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500469 d.setVar("SSTATE_PATH_CURRTASK", ss['task'])
470 sstatepkgfile = d.getVar('SSTATE_PATHSPEC')
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300471 bb.note("Removing %s" % sstatepkgfile)
472 oe.path.remove(sstatepkgfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500473
474def sstate_clean_cachefiles(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500475 for task in (d.getVar('SSTATETASKS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500476 ld = d.createCopy()
477 ss = sstate_state_fromvars(ld, task)
478 sstate_clean_cachefile(ss, ld)
479
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500480def sstate_clean_manifest(manifest, d, prefix=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500481 import oe.path
482
483 mfile = open(manifest)
484 entries = mfile.readlines()
485 mfile.close()
486
487 for entry in entries:
488 entry = entry.strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500489 if prefix and not entry.startswith("/"):
490 entry = prefix + "/" + entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500491 bb.debug(2, "Removing manifest: %s" % entry)
492 # We can race against another package populating directories as we're removing them
493 # so we ignore errors here.
494 try:
495 if entry.endswith("/"):
496 if os.path.islink(entry[:-1]):
497 os.remove(entry[:-1])
498 elif os.path.exists(entry) and len(os.listdir(entry)) == 0:
499 os.rmdir(entry[:-1])
500 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500501 os.remove(entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500502 except OSError:
503 pass
504
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600505 postrm = manifest + ".postrm"
506 if os.path.exists(manifest + ".postrm"):
507 import subprocess
508 os.chmod(postrm, 0o755)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500509 subprocess.check_call(postrm, shell=True)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600510 oe.path.remove(postrm)
511
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500512 oe.path.remove(manifest)
513
514def sstate_clean(ss, d):
515 import oe.path
516 import glob
517
518 d2 = d.createCopy()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500519 stamp_clean = d.getVar("STAMPCLEAN")
520 extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500521 if extrainf:
522 d2.setVar("SSTATE_MANMACH", extrainf)
523 wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
524 else:
525 wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
526
527 manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
528
529 if os.path.exists(manifest):
530 locks = []
531 for lock in ss['lockfiles-shared']:
532 locks.append(bb.utils.lockfile(lock))
533 for lock in ss['lockfiles']:
534 locks.append(bb.utils.lockfile(lock))
535
536 sstate_clean_manifest(manifest, d)
537
538 for lock in locks:
539 bb.utils.unlockfile(lock)
540
541 # Remove the current and previous stamps, but keep the sigdata.
542 #
543 # The glob() matches do_task* which may match multiple tasks, for
544 # example: do_package and do_package_write_ipk, so we need to
545 # exactly match *.do_task.* and *.do_task_setscene.*
546 rm_stamp = '.do_%s.' % ss['task']
547 rm_setscene = '.do_%s_setscene.' % ss['task']
548 # For BB_SIGNATURE_HANDLER = "noop"
549 rm_nohash = ".do_%s" % ss['task']
550 for stfile in glob.glob(wildcard_stfile):
551 # Keep the sigdata
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500552 if ".sigdata." in stfile or ".sigbasedata." in stfile:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500553 continue
554 # Preserve taint files in the stamps directory
555 if stfile.endswith('.taint'):
556 continue
557 if rm_stamp in stfile or rm_setscene in stfile or \
558 stfile.endswith(rm_nohash):
559 oe.path.remove(stfile)
560
561sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
562
563CLEANFUNCS += "sstate_cleanall"
564
565python sstate_cleanall() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500566 bb.note("Removing shared state for package %s" % d.getVar('PN'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500567
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500568 manifest_dir = d.getVar('SSTATE_MANIFESTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500569 if not os.path.exists(manifest_dir):
570 return
571
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500572 tasks = d.getVar('SSTATETASKS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500573 for name in tasks:
574 ld = d.createCopy()
575 shared_state = sstate_state_fromvars(ld, name)
576 sstate_clean(shared_state, ld)
577}
578
579python sstate_hardcode_path () {
580 import subprocess, platform
581
582 # Need to remove hardcoded paths and fix these when we install the
583 # staging packages.
584 #
585 # Note: the logic in this function needs to match the reverse logic
586 # in sstate_installpkg(ss, d)
587
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500588 staging_target = d.getVar('RECIPE_SYSROOT')
589 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
590 sstate_builddir = d.getVar('SSTATE_BUILDDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500591
Brad Bishop316dfdd2018-06-25 12:45:53 -0400592 sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500593 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500594 sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500595 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
596 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400597 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500598 else:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400599 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
600 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500601
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500602 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500603 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500604 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500605 sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500606 sstate_grep_cmd += " -e '%s'" % (fixme_path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500607
608 fixmefn = sstate_builddir + "fixmepath"
609
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500610 sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500611 sstate_filelist_cmd = "tee %s" % (fixmefn)
612
613 # fixmepath file needs relative paths, drop sstate_builddir prefix
614 sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
615
616 xargs_no_empty_run_cmd = '--no-run-if-empty'
617 if platform.system() == 'Darwin':
618 xargs_no_empty_run_cmd = ''
619
620 # Limit the fixpaths and sed operations based on the initial grep search
621 # This has the side effect of making sure the vfs cache is hot
622 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)
623
624 bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500625 subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500626
627 # If the fixmefn is empty, remove it..
628 if os.stat(fixmefn).st_size == 0:
629 os.remove(fixmefn)
630 else:
631 bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500632 subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500633}
634
635def sstate_package(ss, d):
636 import oe.path
637
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500638 tmpdir = d.getVar('TMPDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500639
640 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
Andrew Geissler82c905d2020-04-13 13:39:40 -0500641 d.setVar("SSTATE_CURRTASK", ss['task'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500642 bb.utils.remove(sstatebuild, recurse=True)
643 bb.utils.mkdirhier(sstatebuild)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500644 for state in ss['dirs']:
645 if not os.path.exists(state[1]):
646 continue
647 srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500648 # Find and error for absolute symlinks. We could attempt to relocate but its not
649 # clear where the symlink is relative to in this context. We could add that markup
650 # to sstate tasks but there aren't many of these so better just avoid them entirely.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500651 for walkroot, dirs, files in os.walk(state[1]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500652 for file in files + dirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500653 srcpath = os.path.join(walkroot, file)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500654 if not os.path.islink(srcpath):
655 continue
656 link = os.readlink(srcpath)
657 if not os.path.isabs(link):
658 continue
659 if not link.startswith(tmpdir):
660 continue
661 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 -0500662 bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500663 os.rename(state[1], sstatebuild + state[0])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500665 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500666 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667 for plain in ss['plaindirs']:
668 pdir = plain.replace(workdir, sstatebuild)
Brad Bishop977dc1a2019-02-06 16:01:43 -0500669 if sharedworkdir in plain:
670 pdir = plain.replace(sharedworkdir, sstatebuild)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500671 bb.utils.mkdirhier(plain)
672 bb.utils.mkdirhier(pdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500673 os.rename(plain, pdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500674
675 d.setVar('SSTATE_BUILDDIR', sstatebuild)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500676 d.setVar('SSTATE_INSTDIR', sstatebuild)
677
678 if d.getVar('SSTATE_SKIP_CREATION') == '1':
679 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500680
Brad Bishop08902b02019-08-20 09:16:51 -0400681 sstate_create_package = ['sstate_report_unihash', 'sstate_create_package']
682 if d.getVar('SSTATE_SIG_KEY'):
683 sstate_create_package.append('sstate_sign_package')
684
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500685 for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
Brad Bishop08902b02019-08-20 09:16:51 -0400686 sstate_create_package + \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500687 (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500688 # All hooks should run in SSTATE_BUILDDIR.
689 bb.build.exec_func(f, d, (sstatebuild,))
690
Andrew Geissler82c905d2020-04-13 13:39:40 -0500691 # SSTATE_PKG may have been changed by sstate_report_unihash
692 siginfo = d.getVar('SSTATE_PKG') + ".siginfo"
693 if not os.path.exists(siginfo):
694 bb.siggen.dump_this_task(siginfo, d)
695 else:
Andrew Geisslerc182c622020-05-15 14:13:32 -0500696 try:
697 os.utime(siginfo, None)
698 except PermissionError:
699 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500700
701 return
702
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800703def pstaging_fetch(sstatefetch, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500704 import bb.fetch2
705
706 # Only try and fetch if the user has configured a mirror
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500707 mirrors = d.getVar('SSTATE_MIRRORS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500708 if not mirrors:
709 return
710
711 # Copy the data object and override DL_DIR and SRC_URI
712 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500713
714 dldir = localdata.expand("${SSTATE_DIR}")
715 bb.utils.mkdirhier(dldir)
716
717 localdata.delVar('MIRRORS')
718 localdata.setVar('FILESPATH', dldir)
719 localdata.setVar('DL_DIR', dldir)
720 localdata.setVar('PREMIRRORS', mirrors)
721
722 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
723 # we'll want to allow network access for the current set of fetches.
Brad Bishopd89cb5f2019-04-10 09:02:41 -0400724 if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
725 bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500726 localdata.delVar('BB_NO_NETWORK')
727
728 # Try a fetch from the sstate mirror, if it fails just return and
729 # we will build the package
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600730 uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
731 'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500732 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600733 uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500734
735 for srcuri in uris:
736 localdata.setVar('SRC_URI', srcuri)
737 try:
738 fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
Andrew Geissler4ed12e12020-06-05 18:00:41 -0500739 fetcher.checkstatus()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500740 fetcher.download()
741
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500742 except bb.fetch2.BBFetchException:
Andrew Geissler4ed12e12020-06-05 18:00:41 -0500743 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500744
745def sstate_setscene(d):
746 shared_state = sstate_state_fromvars(d)
747 accelerate = sstate_installpkg(shared_state, d)
748 if not accelerate:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600749 bb.fatal("No suitable staging package found")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750
751python sstate_task_prefunc () {
752 shared_state = sstate_state_fromvars(d)
753 sstate_clean(shared_state, d)
754}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500755sstate_task_prefunc[dirs] = "${WORKDIR}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500756
757python sstate_task_postfunc () {
758 shared_state = sstate_state_fromvars(d)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500759
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500760 for intercept in shared_state['interceptfuncs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500761 bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
762
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600763 omask = os.umask(0o002)
764 if omask != 0o002:
765 bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500766 sstate_package(shared_state, d)
767 os.umask(omask)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500768
769 sstateinst = d.getVar("SSTATE_INSTDIR")
770 d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
771
772 sstate_installpkgdir(shared_state, d)
773
774 bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500775}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500776sstate_task_postfunc[dirs] = "${WORKDIR}"
777
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500778
779#
780# Shell function to generate a sstate package from a directory
781# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
782#
783sstate_create_package () {
Andrew Geissler82c905d2020-04-13 13:39:40 -0500784 # Exit early if it already exists
Brad Bishop08902b02019-08-20 09:16:51 -0400785 if [ -e ${SSTATE_PKG} ]; then
Andrew Geisslerc182c622020-05-15 14:13:32 -0500786 [ ! -w ${SSTATE_PKG} ] || touch ${SSTATE_PKG}
Brad Bishop08902b02019-08-20 09:16:51 -0400787 return
788 fi
789
Andrew Geissler82c905d2020-04-13 13:39:40 -0500790 mkdir -p `dirname ${SSTATE_PKG}`
791 TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
792
793 # Use pigz if available
794 OPT="-czS"
795 if [ -x "$(command -v pigz)" ]; then
796 OPT="-I pigz -cS"
797 fi
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800798
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500799 # Need to handle empty directories
800 if [ "$(ls -A)" ]; then
801 set +e
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800802 tar $OPT -f $TFILE *
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500803 ret=$?
804 if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
805 exit 1
806 fi
807 set -e
808 else
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800809 tar $OPT --file=$TFILE --files-from=/dev/null
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500810 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500811 chmod 0664 $TFILE
Brad Bishop08902b02019-08-20 09:16:51 -0400812 # Skip if it was already created by some other process
813 if [ ! -e ${SSTATE_PKG} ]; then
Andrew Geissler82c905d2020-04-13 13:39:40 -0500814 # Move into place using ln to attempt an atomic op.
815 # Abort if it already exists
816 ln $TFILE ${SSTATE_PKG} && rm $TFILE
Brad Bishop08902b02019-08-20 09:16:51 -0400817 else
818 rm $TFILE
819 fi
Andrew Geisslerc182c622020-05-15 14:13:32 -0500820 [ ! -w ${SSTATE_PKG} ] || touch ${SSTATE_PKG}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500821}
822
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500823python sstate_sign_package () {
824 from oe.gpg_sign import get_signer
825
Brad Bishop08902b02019-08-20 09:16:51 -0400826
827 signer = get_signer(d, 'local')
828 sstate_pkg = d.getVar('SSTATE_PKG')
829 if os.path.exists(sstate_pkg + '.sig'):
830 os.unlink(sstate_pkg + '.sig')
831 signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
832 d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500833}
834
Brad Bishop19323692019-04-05 15:28:33 -0400835python sstate_report_unihash() {
836 report_unihash = getattr(bb.parse.siggen, 'report_unihash', None)
837
838 if report_unihash:
839 ss = sstate_state_fromvars(d)
840 report_unihash(os.getcwd(), ss['task'], d)
841}
842
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500843#
844# Shell function to decompress and prepare a package for installation
845# Will be run from within SSTATE_INSTDIR.
846#
847sstate_unpack_package () {
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500848 tar -xvzf ${SSTATE_PKG}
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500849 # update .siginfo atime on local/NFS mirror
850 [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500851 # Use "! -w ||" to return true for read only files
852 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500853 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig
854 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500855}
856
857BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
858
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500859def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, summary=True, **kwargs):
Brad Bishop08902b02019-08-20 09:16:51 -0400860 found = set()
861 missed = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500862
Brad Bishop19323692019-04-05 15:28:33 -0400863 def gethash(task):
Brad Bishop08902b02019-08-20 09:16:51 -0400864 return sq_data['unihash'][task]
Brad Bishop19323692019-04-05 15:28:33 -0400865
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500866 def getpathcomponents(task, d):
867 # Magic data from BB_HASHFILENAME
Brad Bishop08902b02019-08-20 09:16:51 -0400868 splithashfn = sq_data['hashfn'][task].split(" ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 spec = splithashfn[1]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500870 if splithashfn[0] == "True":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500871 extrapath = d.getVar("NATIVELSBSTRING") + "/"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500872 else:
873 extrapath = ""
Brad Bishop08902b02019-08-20 09:16:51 -0400874
875 tname = bb.runqueue.taskname_from_tid(task)[3:]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500876
877 if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
878 spec = splithashfn[2]
879 extrapath = ""
880
881 return spec, extrapath, tname
882
883
Brad Bishop08902b02019-08-20 09:16:51 -0400884 for tid in sq_data['hash']:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500885
Brad Bishop08902b02019-08-20 09:16:51 -0400886 spec, extrapath, tname = getpathcomponents(tid, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500887
Andrew Geissler82c905d2020-04-13 13:39:40 -0500888 sstatefile = d.expand("${SSTATE_DIR}/" + extrapath + generate_sstatefn(spec, gethash(tid), tname, siginfo, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500889
890 if os.path.exists(sstatefile):
891 bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
Brad Bishop08902b02019-08-20 09:16:51 -0400892 found.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500893 continue
894 else:
Brad Bishop08902b02019-08-20 09:16:51 -0400895 missed.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500896 bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
897
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500898 mirrors = d.getVar("SSTATE_MIRRORS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500899 if mirrors:
900 # Copy the data object and override DL_DIR and SRC_URI
901 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500902
903 dldir = localdata.expand("${SSTATE_DIR}")
904 localdata.delVar('MIRRORS')
905 localdata.setVar('FILESPATH', dldir)
906 localdata.setVar('DL_DIR', dldir)
907 localdata.setVar('PREMIRRORS', mirrors)
908
909 bb.debug(2, "SState using premirror of: %s" % mirrors)
910
911 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
912 # we'll want to allow network access for the current set of fetches.
Brad Bishopd89cb5f2019-04-10 09:02:41 -0400913 if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
914 bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500915 localdata.delVar('BB_NO_NETWORK')
916
917 from bb.fetch2 import FetchConnectionCache
918 def checkstatus_init(thread_worker):
919 thread_worker.connection_cache = FetchConnectionCache()
920
921 def checkstatus_end(thread_worker):
922 thread_worker.connection_cache.close_connections()
923
924 def checkstatus(thread_worker, arg):
Brad Bishop08902b02019-08-20 09:16:51 -0400925 (tid, sstatefile) = arg
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500926
927 localdata2 = bb.data.createCopy(localdata)
928 srcuri = "file://" + sstatefile
929 localdata.setVar('SRC_URI', srcuri)
930 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
931
932 try:
933 fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
934 connection_cache=thread_worker.connection_cache)
935 fetcher.checkstatus()
936 bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
Brad Bishop08902b02019-08-20 09:16:51 -0400937 found.add(tid)
938 if tid in missed:
939 missed.remove(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500940 except:
Brad Bishop08902b02019-08-20 09:16:51 -0400941 missed.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500942 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600943 pass
Andrew Geissler82c905d2020-04-13 13:39:40 -0500944 if len(tasklist) >= min_tasks:
945 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500946
947 tasklist = []
Andrew Geissler82c905d2020-04-13 13:39:40 -0500948 min_tasks = 100
Brad Bishop08902b02019-08-20 09:16:51 -0400949 for tid in sq_data['hash']:
950 if tid in found:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500951 continue
Brad Bishop08902b02019-08-20 09:16:51 -0400952 spec, extrapath, tname = getpathcomponents(tid, d)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500953 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), tname, siginfo, d))
Brad Bishop08902b02019-08-20 09:16:51 -0400954 tasklist.append((tid, sstatefile))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500955
956 if tasklist:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500957 if len(tasklist) >= min_tasks:
958 msg = "Checking sstate mirror object availability"
959 bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600960
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500961 import multiprocessing
962 nproc = min(multiprocessing.cpu_count(), len(tasklist))
963
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600964 bb.event.enable_threadlock()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500965 pool = oe.utils.ThreadedPool(nproc, len(tasklist),
966 worker_init=checkstatus_init, worker_end=checkstatus_end)
967 for t in tasklist:
968 pool.add_task(checkstatus, t)
969 pool.start()
970 pool.wait_completion()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600971 bb.event.disable_threadlock()
972
Andrew Geissler82c905d2020-04-13 13:39:40 -0500973 if len(tasklist) >= min_tasks:
974 bb.event.fire(bb.event.ProcessFinished(msg), d)
Brad Bishop96ff1982019-08-19 13:50:42 -0400975
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500976 inheritlist = d.getVar("INHERIT")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500977 if "toaster" in inheritlist:
978 evdata = {'missed': [], 'found': []};
Brad Bishop08902b02019-08-20 09:16:51 -0400979 for tid in missed:
980 spec, extrapath, tname = getpathcomponents(tid, d)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500981 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), tname, False, d))
Brad Bishop08902b02019-08-20 09:16:51 -0400982 evdata['missed'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
983 for tid in found:
984 spec, extrapath, tname = getpathcomponents(tid, d)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500985 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), tname, False, d))
Brad Bishop08902b02019-08-20 09:16:51 -0400986 evdata['found'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500987 bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
988
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500989 if summary:
990 # Print some summary statistics about the current task completion and how much sstate
991 # reuse there was. Avoid divide by zero errors.
992 total = len(sq_data['hash'])
993 complete = 0
994 if currentcount:
995 complete = (len(found) + currentcount) / (total + currentcount) * 100
996 match = 0
997 if total:
998 match = len(found) / total * 100
999 bb.plain("Sstate summary: Wanted %d Found %d Missed %d Current %d (%d%% match, %d%% complete)" % (total, len(found), len(missed), currentcount, match, complete))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001000
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001001 if hasattr(bb.parse.siggen, "checkhashes"):
Brad Bishop08902b02019-08-20 09:16:51 -04001002 bb.parse.siggen.checkhashes(sq_data, missed, found, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001003
Brad Bishop08902b02019-08-20 09:16:51 -04001004 return found
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001005
1006BB_SETSCENE_DEPVALID = "setscene_depvalid"
1007
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001008def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001009 # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
1010 # task is included in taskdependees too
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001011 # Return - False - We need this dependency
1012 # - True - We can skip this dependency
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001013 import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001014
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001015 def logit(msg, log):
1016 if log is not None:
1017 log.append(msg)
1018 else:
1019 bb.debug(2, msg)
1020
1021 logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001022
1023 def isNativeCross(x):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001024 return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001025
1026 # We only need to trigger populate_lic through direct dependencies
1027 if taskdependees[task][1] == "do_populate_lic":
1028 return True
1029
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001030 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
1031 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
1032 return True
1033
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001034 # We only need to trigger packagedata through direct dependencies
1035 # but need to preserve packagedata on packagedata links
1036 if taskdependees[task][1] == "do_packagedata":
1037 for dep in taskdependees:
1038 if taskdependees[dep][1] == "do_packagedata":
1039 return False
1040 return True
1041
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001042 for dep in taskdependees:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001043 logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001044 if task == dep:
1045 continue
1046 if dep in notneeded:
1047 continue
1048 # do_package_write_* and do_package doesn't need do_package
1049 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']:
1050 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001051 # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
1052 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
1053 return False
1054 # do_package/packagedata/package_qa don't need do_populate_sysroot
1055 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 -05001056 continue
1057 # Native/Cross packages don't exist and are noexec anyway
1058 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']:
1059 continue
1060
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001061 # This is due to the [depends] in useradd.bbclass complicating matters
1062 # The logic *is* reversed here due to the way hard setscene dependencies are injected
1063 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':
1064 continue
1065
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001066 # Consider sysroot depending on sysroot tasks
1067 if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001068 # Allow excluding certain recursive dependencies. If a recipe needs it should add a
1069 # specific dependency itself, rather than relying on one of its dependees to pull
1070 # them in.
1071 # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
1072 not_needed = False
1073 excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
1074 if excludedeps is None:
1075 # Cache the regular expressions for speed
1076 excludedeps = []
1077 for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
1078 excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
1079 d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
1080 for excl in excludedeps:
1081 if excl[0].match(taskdependees[dep][0]):
1082 if excl[1].match(taskdependees[task][0]):
1083 not_needed = True
1084 break
1085 if not_needed:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001086 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001087 # For meta-extsdk-toolchain we want all sysroot dependencies
1088 if taskdependees[dep][0] == 'meta-extsdk-toolchain':
1089 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001090 # Native/Cross populate_sysroot need their dependencies
1091 if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
1092 return False
1093 # Target populate_sysroot depended on by cross tools need to be installed
1094 if isNativeCross(taskdependees[dep][0]):
1095 return False
1096 # Native/cross tools depended upon by target sysroot are not needed
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001097 # Add an exception for shadow-native as required by useradd.bbclass
1098 if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001099 continue
1100 # Target populate_sysroot need their dependencies
1101 return False
1102
1103 if taskdependees[task][1] == 'do_shared_workdir':
1104 continue
1105
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001106 if taskdependees[dep][1] == "do_populate_lic":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001107 continue
1108
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001109
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001110 # Safe fallthrough default
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001111 logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001112 return False
1113 return True
1114
1115addhandler sstate_eventhandler
1116sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
1117python sstate_eventhandler() {
1118 d = e.data
Andrew Geissler82c905d2020-04-13 13:39:40 -05001119 writtensstate = d.getVar('SSTATE_CURRTASK')
1120 if not writtensstate:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001121 taskname = d.getVar("BB_RUNTASK")[3:]
1122 spec = d.getVar('SSTATE_PKGSPEC')
1123 swspec = d.getVar('SSTATE_SWSPEC')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001124 if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
1125 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
1126 d.setVar("SSTATE_EXTRAPATH", "")
Andrew Geissler82c905d2020-04-13 13:39:40 -05001127 d.setVar("SSTATE_CURRTASK", taskname)
1128 siginfo = d.getVar('SSTATE_PKG') + ".siginfo"
1129 if not os.path.exists(siginfo):
1130 bb.siggen.dump_this_task(siginfo, d)
1131 else:
Andrew Geisslerc182c622020-05-15 14:13:32 -05001132 try:
1133 os.utime(siginfo, None)
1134 except PermissionError:
1135 pass
1136
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001137}
1138
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001139SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001140
1141# Event handler which removes manifests and stamps file for
1142# recipes which are no longer reachable in a build where they
1143# once were.
1144# Also optionally removes the workdir of those tasks/recipes
1145#
1146addhandler sstate_eventhandler2
1147sstate_eventhandler2[eventmask] = "bb.event.ReachableStamps"
1148python sstate_eventhandler2() {
1149 import glob
1150 d = e.data
1151 stamps = e.stamps.values()
1152 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001153 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1154 preservestamps = []
1155 if os.path.exists(preservestampfile):
1156 with open(preservestampfile, 'r') as f:
1157 preservestamps = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001158 seen = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001159
1160 # The machine index contains all the stamps this machine has ever seen in this build directory.
1161 # We should only remove things which this machine once accessed but no longer does.
1162 machineindex = set()
1163 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
1164 mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
1165 if os.path.exists(mi):
1166 with open(mi, "r") as f:
1167 machineindex = set(line.strip() for line in f.readlines())
1168
Brad Bishop316dfdd2018-06-25 12:45:53 -04001169 for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001170 toremove = []
1171 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1172 if not os.path.exists(i):
1173 continue
1174 with open(i, "r") as f:
1175 lines = f.readlines()
1176 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001177 try:
1178 (stamp, manifest, workdir) = l.split()
1179 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
1180 toremove.append(l)
1181 if stamp not in seen:
1182 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
1183 seen.append(stamp)
1184 except ValueError:
1185 bb.fatal("Invalid line '%s' in sstate manifest '%s'" % (l, i))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001186
1187 if toremove:
Brad Bishop316dfdd2018-06-25 12:45:53 -04001188 msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
1189 bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001190
Brad Bishop316dfdd2018-06-25 12:45:53 -04001191 removed = 0
1192 for r in toremove:
1193 (stamp, manifest, workdir) = r.split()
1194 for m in glob.glob(manifest + ".*"):
1195 if m.endswith(".postrm"):
1196 continue
1197 sstate_clean_manifest(m, d)
1198 bb.utils.remove(stamp + "*")
1199 if removeworkdir:
1200 bb.utils.remove(workdir, recurse = True)
1201 lines.remove(r)
1202 removed = removed + 1
1203 bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
1204
1205 bb.event.fire(bb.event.ProcessFinished(msg), d)
1206
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001207 with open(i, "w") as f:
1208 for l in lines:
1209 f.write(l)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001210 machineindex |= set(stamps)
1211 with open(mi, "w") as f:
1212 for l in machineindex:
1213 f.write(l + "\n")
1214
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001215 if preservestamps:
1216 os.remove(preservestampfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001217}