blob: aa9c30b4e106ecc50e93378345e13dafb3a75227 [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):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500358 signer = get_signer(d, 'local')
359 if not signer.verify(sstatepkg + '.sig'):
Brad Bishop08902b02019-08-20 09:16:51 -0400360 bb.warn("Cannot verify signature on sstate package %s, skipping acceleration..." % sstatepkg)
361 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500362
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500363 # Empty sstateinst directory, ensure its clean
364 if os.path.exists(sstateinst):
365 oe.path.remove(sstateinst)
366 bb.utils.mkdirhier(sstateinst)
367
368 sstateinst = d.getVar("SSTATE_INSTDIR")
369 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
370
371 for f in (d.getVar('SSTATEPREINSTFUNCS') or '').split() + ['sstate_unpack_package']:
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500372 # All hooks should run in the SSTATE_INSTDIR
373 bb.build.exec_func(f, d, (sstateinst,))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500374
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500375 return sstate_installpkgdir(ss, d)
376
377def sstate_installpkgdir(ss, d):
378 import oe.path
379 import subprocess
380
381 sstateinst = d.getVar("SSTATE_INSTDIR")
382 d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
383
384 for f in (d.getVar('SSTATEPOSTUNPACKFUNCS') or '').split():
385 # All hooks should run in the SSTATE_INSTDIR
386 bb.build.exec_func(f, d, (sstateinst,))
387
388 def prepdir(dir):
389 # remove dir if it exists, ensure any parent directories do exist
390 if os.path.exists(dir):
391 oe.path.remove(dir)
392 bb.utils.mkdirhier(dir)
393 oe.path.remove(dir)
394
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500395 for state in ss['dirs']:
396 prepdir(state[1])
397 os.rename(sstateinst + state[0], state[1])
398 sstate_install(ss, d)
399
400 for plain in ss['plaindirs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500401 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500402 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500403 src = sstateinst + "/" + plain.replace(workdir, '')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500404 if sharedworkdir in plain:
405 src = sstateinst + "/" + plain.replace(sharedworkdir, '')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406 dest = plain
407 bb.utils.mkdirhier(src)
408 prepdir(dest)
409 os.rename(src, dest)
410
411 return True
412
413python sstate_hardcode_path_unpack () {
414 # Fixup hardcoded paths
415 #
416 # Note: The logic below must match the reverse logic in
417 # sstate_hardcode_path(d)
418 import subprocess
419
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500420 sstateinst = d.getVar('SSTATE_INSTDIR')
421 sstatefixmedir = d.getVar('SSTATE_FIXMEDIR')
422 fixmefn = sstateinst + "fixmepath"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500423 if os.path.isfile(fixmefn):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500424 staging_target = d.getVar('RECIPE_SYSROOT')
425 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500426
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500427 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500428 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRHOST:%s:g'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500429 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
430 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (staging_target, staging_host)
431 else:
432 sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g'" % (staging_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500433
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500434 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500435 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500436 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500437 sstate_sed_cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
438
439 # Add sstateinst to each filename in fixmepath, use xargs to efficiently call sed
440 sstate_hardcode_cmd = "sed -e 's:^:%s:g' %s | xargs %s" % (sstateinst, fixmefn, sstate_sed_cmd)
441
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500442 # Defer do_populate_sysroot relocation command
443 if sstatefixmedir:
444 bb.utils.mkdirhier(sstatefixmedir)
445 with open(sstatefixmedir + "/fixmepath.cmd", "w") as f:
446 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(fixmefn, sstatefixmedir + "/fixmepath")
447 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(sstateinst, "FIXMEFINALSSTATEINST")
448 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_host, "FIXMEFINALSSTATEHOST")
449 sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_target, "FIXMEFINALSSTATETARGET")
450 f.write(sstate_hardcode_cmd)
451 bb.utils.copyfile(fixmefn, sstatefixmedir + "/fixmepath")
452 return
453
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500454 bb.note("Replacing fixme paths in sstate package: %s" % (sstate_hardcode_cmd))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500455 subprocess.check_call(sstate_hardcode_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500456
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800457 # Need to remove this or we'd copy it into the target directory and may
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500458 # conflict with another writer
459 os.remove(fixmefn)
460}
461
462def sstate_clean_cachefile(ss, d):
463 import oe.path
464
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300465 if d.getVarFlag('do_%s' % ss['task'], 'task'):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500466 d.setVar("SSTATE_PATH_CURRTASK", ss['task'])
467 sstatepkgfile = d.getVar('SSTATE_PATHSPEC')
Brad Bishopa5c52ff2018-11-23 10:55:50 +1300468 bb.note("Removing %s" % sstatepkgfile)
469 oe.path.remove(sstatepkgfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500470
471def sstate_clean_cachefiles(d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500472 for task in (d.getVar('SSTATETASKS') or "").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500473 ld = d.createCopy()
474 ss = sstate_state_fromvars(ld, task)
475 sstate_clean_cachefile(ss, ld)
476
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500477def sstate_clean_manifest(manifest, d, prefix=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500478 import oe.path
479
480 mfile = open(manifest)
481 entries = mfile.readlines()
482 mfile.close()
483
484 for entry in entries:
485 entry = entry.strip()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500486 if prefix and not entry.startswith("/"):
487 entry = prefix + "/" + entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500488 bb.debug(2, "Removing manifest: %s" % entry)
489 # We can race against another package populating directories as we're removing them
490 # so we ignore errors here.
491 try:
492 if entry.endswith("/"):
493 if os.path.islink(entry[:-1]):
494 os.remove(entry[:-1])
495 elif os.path.exists(entry) and len(os.listdir(entry)) == 0:
496 os.rmdir(entry[:-1])
497 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500498 os.remove(entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500499 except OSError:
500 pass
501
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600502 postrm = manifest + ".postrm"
503 if os.path.exists(manifest + ".postrm"):
504 import subprocess
505 os.chmod(postrm, 0o755)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500506 subprocess.check_call(postrm, shell=True)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600507 oe.path.remove(postrm)
508
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500509 oe.path.remove(manifest)
510
511def sstate_clean(ss, d):
512 import oe.path
513 import glob
514
515 d2 = d.createCopy()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500516 stamp_clean = d.getVar("STAMPCLEAN")
517 extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500518 if extrainf:
519 d2.setVar("SSTATE_MANMACH", extrainf)
520 wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
521 else:
522 wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
523
524 manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
525
526 if os.path.exists(manifest):
527 locks = []
528 for lock in ss['lockfiles-shared']:
529 locks.append(bb.utils.lockfile(lock))
530 for lock in ss['lockfiles']:
531 locks.append(bb.utils.lockfile(lock))
532
533 sstate_clean_manifest(manifest, d)
534
535 for lock in locks:
536 bb.utils.unlockfile(lock)
537
538 # Remove the current and previous stamps, but keep the sigdata.
539 #
540 # The glob() matches do_task* which may match multiple tasks, for
541 # example: do_package and do_package_write_ipk, so we need to
542 # exactly match *.do_task.* and *.do_task_setscene.*
543 rm_stamp = '.do_%s.' % ss['task']
544 rm_setscene = '.do_%s_setscene.' % ss['task']
545 # For BB_SIGNATURE_HANDLER = "noop"
546 rm_nohash = ".do_%s" % ss['task']
547 for stfile in glob.glob(wildcard_stfile):
548 # Keep the sigdata
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500549 if ".sigdata." in stfile or ".sigbasedata." in stfile:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550 continue
551 # Preserve taint files in the stamps directory
552 if stfile.endswith('.taint'):
553 continue
554 if rm_stamp in stfile or rm_setscene in stfile or \
555 stfile.endswith(rm_nohash):
556 oe.path.remove(stfile)
557
558sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
559
560CLEANFUNCS += "sstate_cleanall"
561
562python sstate_cleanall() {
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500563 bb.note("Removing shared state for package %s" % d.getVar('PN'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500564
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500565 manifest_dir = d.getVar('SSTATE_MANIFESTS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500566 if not os.path.exists(manifest_dir):
567 return
568
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500569 tasks = d.getVar('SSTATETASKS').split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500570 for name in tasks:
571 ld = d.createCopy()
572 shared_state = sstate_state_fromvars(ld, name)
573 sstate_clean(shared_state, ld)
574}
575
576python sstate_hardcode_path () {
577 import subprocess, platform
578
579 # Need to remove hardcoded paths and fix these when we install the
580 # staging packages.
581 #
582 # Note: the logic in this function needs to match the reverse logic
583 # in sstate_installpkg(ss, d)
584
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500585 staging_target = d.getVar('RECIPE_SYSROOT')
586 staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
587 sstate_builddir = d.getVar('SSTATE_BUILDDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500588
Brad Bishop316dfdd2018-06-25 12:45:53 -0400589 sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500590 if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500591 sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500592 elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
593 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400594 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500595 else:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400596 sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
597 sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500598
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500599 extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500600 for fixmevar in extra_staging_fixmes.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500601 fixme_path = d.getVar(fixmevar)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500602 sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500603 sstate_grep_cmd += " -e '%s'" % (fixme_path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500604
605 fixmefn = sstate_builddir + "fixmepath"
606
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500607 sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500608 sstate_filelist_cmd = "tee %s" % (fixmefn)
609
610 # fixmepath file needs relative paths, drop sstate_builddir prefix
611 sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
612
613 xargs_no_empty_run_cmd = '--no-run-if-empty'
614 if platform.system() == 'Darwin':
615 xargs_no_empty_run_cmd = ''
616
617 # Limit the fixpaths and sed operations based on the initial grep search
618 # This has the side effect of making sure the vfs cache is hot
619 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)
620
621 bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500622 subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623
624 # If the fixmefn is empty, remove it..
625 if os.stat(fixmefn).st_size == 0:
626 os.remove(fixmefn)
627 else:
628 bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500629 subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500630}
631
632def sstate_package(ss, d):
633 import oe.path
634
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500635 tmpdir = d.getVar('TMPDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500636
637 sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
Andrew Geissler82c905d2020-04-13 13:39:40 -0500638 d.setVar("SSTATE_CURRTASK", ss['task'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500639 bb.utils.remove(sstatebuild, recurse=True)
640 bb.utils.mkdirhier(sstatebuild)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641 for state in ss['dirs']:
642 if not os.path.exists(state[1]):
643 continue
644 srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500645 # Find and error for absolute symlinks. We could attempt to relocate but its not
646 # clear where the symlink is relative to in this context. We could add that markup
647 # to sstate tasks but there aren't many of these so better just avoid them entirely.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500648 for walkroot, dirs, files in os.walk(state[1]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500649 for file in files + dirs:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500650 srcpath = os.path.join(walkroot, file)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500651 if not os.path.islink(srcpath):
652 continue
653 link = os.readlink(srcpath)
654 if not os.path.isabs(link):
655 continue
656 if not link.startswith(tmpdir):
657 continue
658 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 -0500659 bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500660 os.rename(state[1], sstatebuild + state[0])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500661
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500662 workdir = d.getVar('WORKDIR')
Brad Bishop977dc1a2019-02-06 16:01:43 -0500663 sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664 for plain in ss['plaindirs']:
665 pdir = plain.replace(workdir, sstatebuild)
Brad Bishop977dc1a2019-02-06 16:01:43 -0500666 if sharedworkdir in plain:
667 pdir = plain.replace(sharedworkdir, sstatebuild)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500668 bb.utils.mkdirhier(plain)
669 bb.utils.mkdirhier(pdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500670 os.rename(plain, pdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500671
672 d.setVar('SSTATE_BUILDDIR', sstatebuild)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500673 d.setVar('SSTATE_INSTDIR', sstatebuild)
674
675 if d.getVar('SSTATE_SKIP_CREATION') == '1':
676 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500677
Brad Bishop08902b02019-08-20 09:16:51 -0400678 sstate_create_package = ['sstate_report_unihash', 'sstate_create_package']
679 if d.getVar('SSTATE_SIG_KEY'):
680 sstate_create_package.append('sstate_sign_package')
681
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500682 for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
Brad Bishop08902b02019-08-20 09:16:51 -0400683 sstate_create_package + \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500684 (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500685 # All hooks should run in SSTATE_BUILDDIR.
686 bb.build.exec_func(f, d, (sstatebuild,))
687
Andrew Geissler82c905d2020-04-13 13:39:40 -0500688 # SSTATE_PKG may have been changed by sstate_report_unihash
689 siginfo = d.getVar('SSTATE_PKG') + ".siginfo"
690 if not os.path.exists(siginfo):
691 bb.siggen.dump_this_task(siginfo, d)
692 else:
Andrew Geisslerc182c622020-05-15 14:13:32 -0500693 try:
694 os.utime(siginfo, None)
695 except PermissionError:
696 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500697
698 return
699
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800700def pstaging_fetch(sstatefetch, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500701 import bb.fetch2
702
703 # Only try and fetch if the user has configured a mirror
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500704 mirrors = d.getVar('SSTATE_MIRRORS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500705 if not mirrors:
706 return
707
708 # Copy the data object and override DL_DIR and SRC_URI
709 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500710
711 dldir = localdata.expand("${SSTATE_DIR}")
712 bb.utils.mkdirhier(dldir)
713
714 localdata.delVar('MIRRORS')
715 localdata.setVar('FILESPATH', dldir)
716 localdata.setVar('DL_DIR', dldir)
717 localdata.setVar('PREMIRRORS', mirrors)
718
719 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
720 # we'll want to allow network access for the current set of fetches.
Brad Bishopd89cb5f2019-04-10 09:02:41 -0400721 if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
722 bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500723 localdata.delVar('BB_NO_NETWORK')
724
725 # Try a fetch from the sstate mirror, if it fails just return and
726 # we will build the package
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600727 uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
728 'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500729 if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600730 uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500731
732 for srcuri in uris:
733 localdata.setVar('SRC_URI', srcuri)
734 try:
735 fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
736 fetcher.download()
737
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500738 except bb.fetch2.BBFetchException:
739 break
740
741def sstate_setscene(d):
742 shared_state = sstate_state_fromvars(d)
743 accelerate = sstate_installpkg(shared_state, d)
744 if not accelerate:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600745 bb.fatal("No suitable staging package found")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500746
747python sstate_task_prefunc () {
748 shared_state = sstate_state_fromvars(d)
749 sstate_clean(shared_state, d)
750}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500751sstate_task_prefunc[dirs] = "${WORKDIR}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500752
753python sstate_task_postfunc () {
754 shared_state = sstate_state_fromvars(d)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500755
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500756 for intercept in shared_state['interceptfuncs']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500757 bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
758
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600759 omask = os.umask(0o002)
760 if omask != 0o002:
761 bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500762 sstate_package(shared_state, d)
763 os.umask(omask)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500764
765 sstateinst = d.getVar("SSTATE_INSTDIR")
766 d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
767
768 sstate_installpkgdir(shared_state, d)
769
770 bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500771}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500772sstate_task_postfunc[dirs] = "${WORKDIR}"
773
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500774
775#
776# Shell function to generate a sstate package from a directory
777# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
778#
779sstate_create_package () {
Andrew Geissler82c905d2020-04-13 13:39:40 -0500780 # Exit early if it already exists
Brad Bishop08902b02019-08-20 09:16:51 -0400781 if [ -e ${SSTATE_PKG} ]; then
Andrew Geisslerc182c622020-05-15 14:13:32 -0500782 [ ! -w ${SSTATE_PKG} ] || touch ${SSTATE_PKG}
Brad Bishop08902b02019-08-20 09:16:51 -0400783 return
784 fi
785
Andrew Geissler82c905d2020-04-13 13:39:40 -0500786 mkdir -p `dirname ${SSTATE_PKG}`
787 TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
788
789 # Use pigz if available
790 OPT="-czS"
791 if [ -x "$(command -v pigz)" ]; then
792 OPT="-I pigz -cS"
793 fi
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800794
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500795 # Need to handle empty directories
796 if [ "$(ls -A)" ]; then
797 set +e
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800798 tar $OPT -f $TFILE *
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500799 ret=$?
800 if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
801 exit 1
802 fi
803 set -e
804 else
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800805 tar $OPT --file=$TFILE --files-from=/dev/null
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500806 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500807 chmod 0664 $TFILE
Brad Bishop08902b02019-08-20 09:16:51 -0400808 # Skip if it was already created by some other process
809 if [ ! -e ${SSTATE_PKG} ]; then
Andrew Geissler82c905d2020-04-13 13:39:40 -0500810 # Move into place using ln to attempt an atomic op.
811 # Abort if it already exists
812 ln $TFILE ${SSTATE_PKG} && rm $TFILE
Brad Bishop08902b02019-08-20 09:16:51 -0400813 else
814 rm $TFILE
815 fi
Andrew Geisslerc182c622020-05-15 14:13:32 -0500816 [ ! -w ${SSTATE_PKG} ] || touch ${SSTATE_PKG}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500817}
818
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500819python sstate_sign_package () {
820 from oe.gpg_sign import get_signer
821
Brad Bishop08902b02019-08-20 09:16:51 -0400822
823 signer = get_signer(d, 'local')
824 sstate_pkg = d.getVar('SSTATE_PKG')
825 if os.path.exists(sstate_pkg + '.sig'):
826 os.unlink(sstate_pkg + '.sig')
827 signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
828 d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500829}
830
Brad Bishop19323692019-04-05 15:28:33 -0400831python sstate_report_unihash() {
832 report_unihash = getattr(bb.parse.siggen, 'report_unihash', None)
833
834 if report_unihash:
835 ss = sstate_state_fromvars(d)
836 report_unihash(os.getcwd(), ss['task'], d)
837}
838
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500839#
840# Shell function to decompress and prepare a package for installation
841# Will be run from within SSTATE_INSTDIR.
842#
843sstate_unpack_package () {
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500844 tar -xvzf ${SSTATE_PKG}
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500845 # update .siginfo atime on local/NFS mirror
846 [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500847 # Use "! -w ||" to return true for read only files
848 [ ! -w ${SSTATE_PKG} ] || touch --no-dereference ${SSTATE_PKG}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500849 [ ! -w ${SSTATE_PKG}.sig ] || [ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig
850 [ ! -w ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500851}
852
853BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
854
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500855def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, summary=True, **kwargs):
Brad Bishop08902b02019-08-20 09:16:51 -0400856 found = set()
857 missed = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500858
Brad Bishop19323692019-04-05 15:28:33 -0400859 def gethash(task):
Brad Bishop08902b02019-08-20 09:16:51 -0400860 return sq_data['unihash'][task]
Brad Bishop19323692019-04-05 15:28:33 -0400861
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500862 def getpathcomponents(task, d):
863 # Magic data from BB_HASHFILENAME
Brad Bishop08902b02019-08-20 09:16:51 -0400864 splithashfn = sq_data['hashfn'][task].split(" ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500865 spec = splithashfn[1]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500866 if splithashfn[0] == "True":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500867 extrapath = d.getVar("NATIVELSBSTRING") + "/"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500868 else:
869 extrapath = ""
Brad Bishop08902b02019-08-20 09:16:51 -0400870
871 tname = bb.runqueue.taskname_from_tid(task)[3:]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500872
873 if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
874 spec = splithashfn[2]
875 extrapath = ""
876
877 return spec, extrapath, tname
878
879
Brad Bishop08902b02019-08-20 09:16:51 -0400880 for tid in sq_data['hash']:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500881
Brad Bishop08902b02019-08-20 09:16:51 -0400882 spec, extrapath, tname = getpathcomponents(tid, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500883
Andrew Geissler82c905d2020-04-13 13:39:40 -0500884 sstatefile = d.expand("${SSTATE_DIR}/" + extrapath + generate_sstatefn(spec, gethash(tid), tname, siginfo, d))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500885
886 if os.path.exists(sstatefile):
887 bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
Brad Bishop08902b02019-08-20 09:16:51 -0400888 found.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500889 continue
890 else:
Brad Bishop08902b02019-08-20 09:16:51 -0400891 missed.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500892 bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
893
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500894 mirrors = d.getVar("SSTATE_MIRRORS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500895 if mirrors:
896 # Copy the data object and override DL_DIR and SRC_URI
897 localdata = bb.data.createCopy(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500898
899 dldir = localdata.expand("${SSTATE_DIR}")
900 localdata.delVar('MIRRORS')
901 localdata.setVar('FILESPATH', dldir)
902 localdata.setVar('DL_DIR', dldir)
903 localdata.setVar('PREMIRRORS', mirrors)
904
905 bb.debug(2, "SState using premirror of: %s" % mirrors)
906
907 # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
908 # we'll want to allow network access for the current set of fetches.
Brad Bishopd89cb5f2019-04-10 09:02:41 -0400909 if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
910 bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500911 localdata.delVar('BB_NO_NETWORK')
912
913 from bb.fetch2 import FetchConnectionCache
914 def checkstatus_init(thread_worker):
915 thread_worker.connection_cache = FetchConnectionCache()
916
917 def checkstatus_end(thread_worker):
918 thread_worker.connection_cache.close_connections()
919
920 def checkstatus(thread_worker, arg):
Brad Bishop08902b02019-08-20 09:16:51 -0400921 (tid, sstatefile) = arg
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500922
923 localdata2 = bb.data.createCopy(localdata)
924 srcuri = "file://" + sstatefile
925 localdata.setVar('SRC_URI', srcuri)
926 bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
927
928 try:
929 fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
930 connection_cache=thread_worker.connection_cache)
931 fetcher.checkstatus()
932 bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
Brad Bishop08902b02019-08-20 09:16:51 -0400933 found.add(tid)
934 if tid in missed:
935 missed.remove(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500936 except:
Brad Bishop08902b02019-08-20 09:16:51 -0400937 missed.add(tid)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500938 bb.debug(2, "SState: Unsuccessful fetch test for %s" % srcuri)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600939 pass
Andrew Geissler82c905d2020-04-13 13:39:40 -0500940 if len(tasklist) >= min_tasks:
941 bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500942
943 tasklist = []
Andrew Geissler82c905d2020-04-13 13:39:40 -0500944 min_tasks = 100
Brad Bishop08902b02019-08-20 09:16:51 -0400945 for tid in sq_data['hash']:
946 if tid in found:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500947 continue
Brad Bishop08902b02019-08-20 09:16:51 -0400948 spec, extrapath, tname = getpathcomponents(tid, d)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500949 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), tname, siginfo, d))
Brad Bishop08902b02019-08-20 09:16:51 -0400950 tasklist.append((tid, sstatefile))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500951
952 if tasklist:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500953 if len(tasklist) >= min_tasks:
954 msg = "Checking sstate mirror object availability"
955 bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600956
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500957 import multiprocessing
958 nproc = min(multiprocessing.cpu_count(), len(tasklist))
959
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600960 bb.event.enable_threadlock()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500961 pool = oe.utils.ThreadedPool(nproc, len(tasklist),
962 worker_init=checkstatus_init, worker_end=checkstatus_end)
963 for t in tasklist:
964 pool.add_task(checkstatus, t)
965 pool.start()
966 pool.wait_completion()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600967 bb.event.disable_threadlock()
968
Andrew Geissler82c905d2020-04-13 13:39:40 -0500969 if len(tasklist) >= min_tasks:
970 bb.event.fire(bb.event.ProcessFinished(msg), d)
Brad Bishop96ff1982019-08-19 13:50:42 -0400971
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500972 inheritlist = d.getVar("INHERIT")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500973 if "toaster" in inheritlist:
974 evdata = {'missed': [], 'found': []};
Brad Bishop08902b02019-08-20 09:16:51 -0400975 for tid in missed:
976 spec, extrapath, tname = getpathcomponents(tid, d)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500977 sstatefile = d.expand(extrapath + generate_sstatefn(spec, gethash(tid), tname, False, d))
Brad Bishop08902b02019-08-20 09:16:51 -0400978 evdata['missed'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
979 for tid in found:
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['found'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500983 bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
984
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500985 if summary:
986 # Print some summary statistics about the current task completion and how much sstate
987 # reuse there was. Avoid divide by zero errors.
988 total = len(sq_data['hash'])
989 complete = 0
990 if currentcount:
991 complete = (len(found) + currentcount) / (total + currentcount) * 100
992 match = 0
993 if total:
994 match = len(found) / total * 100
995 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 -0800996
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500997 if hasattr(bb.parse.siggen, "checkhashes"):
Brad Bishop08902b02019-08-20 09:16:51 -0400998 bb.parse.siggen.checkhashes(sq_data, missed, found, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500999
Brad Bishop08902b02019-08-20 09:16:51 -04001000 return found
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001001
1002BB_SETSCENE_DEPVALID = "setscene_depvalid"
1003
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001004def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001005 # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
1006 # task is included in taskdependees too
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001007 # Return - False - We need this dependency
1008 # - True - We can skip this dependency
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001009 import re
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001010
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001011 def logit(msg, log):
1012 if log is not None:
1013 log.append(msg)
1014 else:
1015 bb.debug(2, msg)
1016
1017 logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001018
1019 def isNativeCross(x):
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001020 return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001021
1022 # We only need to trigger populate_lic through direct dependencies
1023 if taskdependees[task][1] == "do_populate_lic":
1024 return True
1025
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001026 # stash_locale and gcc_stash_builddir are never needed as a dependency for built objects
1027 if taskdependees[task][1] == "do_stash_locale" or taskdependees[task][1] == "do_gcc_stash_builddir":
1028 return True
1029
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001030 # We only need to trigger packagedata through direct dependencies
1031 # but need to preserve packagedata on packagedata links
1032 if taskdependees[task][1] == "do_packagedata":
1033 for dep in taskdependees:
1034 if taskdependees[dep][1] == "do_packagedata":
1035 return False
1036 return True
1037
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001038 for dep in taskdependees:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001039 logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001040 if task == dep:
1041 continue
1042 if dep in notneeded:
1043 continue
1044 # do_package_write_* and do_package doesn't need do_package
1045 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']:
1046 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001047 # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
1048 if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
1049 return False
1050 # do_package/packagedata/package_qa don't need do_populate_sysroot
1051 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 -05001052 continue
1053 # Native/Cross packages don't exist and are noexec anyway
1054 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']:
1055 continue
1056
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001057 # This is due to the [depends] in useradd.bbclass complicating matters
1058 # The logic *is* reversed here due to the way hard setscene dependencies are injected
1059 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':
1060 continue
1061
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001062 # Consider sysroot depending on sysroot tasks
1063 if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001064 # Allow excluding certain recursive dependencies. If a recipe needs it should add a
1065 # specific dependency itself, rather than relying on one of its dependees to pull
1066 # them in.
1067 # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
1068 not_needed = False
1069 excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
1070 if excludedeps is None:
1071 # Cache the regular expressions for speed
1072 excludedeps = []
1073 for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
1074 excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
1075 d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
1076 for excl in excludedeps:
1077 if excl[0].match(taskdependees[dep][0]):
1078 if excl[1].match(taskdependees[task][0]):
1079 not_needed = True
1080 break
1081 if not_needed:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001082 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001083 # For meta-extsdk-toolchain we want all sysroot dependencies
1084 if taskdependees[dep][0] == 'meta-extsdk-toolchain':
1085 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001086 # Native/Cross populate_sysroot need their dependencies
1087 if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
1088 return False
1089 # Target populate_sysroot depended on by cross tools need to be installed
1090 if isNativeCross(taskdependees[dep][0]):
1091 return False
1092 # Native/cross tools depended upon by target sysroot are not needed
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001093 # Add an exception for shadow-native as required by useradd.bbclass
1094 if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001095 continue
1096 # Target populate_sysroot need their dependencies
1097 return False
1098
1099 if taskdependees[task][1] == 'do_shared_workdir':
1100 continue
1101
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001102 if taskdependees[dep][1] == "do_populate_lic":
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001103 continue
1104
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001105
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001106 # Safe fallthrough default
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001107 logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001108 return False
1109 return True
1110
1111addhandler sstate_eventhandler
1112sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
1113python sstate_eventhandler() {
1114 d = e.data
Andrew Geissler82c905d2020-04-13 13:39:40 -05001115 writtensstate = d.getVar('SSTATE_CURRTASK')
1116 if not writtensstate:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001117 taskname = d.getVar("BB_RUNTASK")[3:]
1118 spec = d.getVar('SSTATE_PKGSPEC')
1119 swspec = d.getVar('SSTATE_SWSPEC')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001120 if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
1121 d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
1122 d.setVar("SSTATE_EXTRAPATH", "")
Andrew Geissler82c905d2020-04-13 13:39:40 -05001123 d.setVar("SSTATE_CURRTASK", taskname)
1124 siginfo = d.getVar('SSTATE_PKG') + ".siginfo"
1125 if not os.path.exists(siginfo):
1126 bb.siggen.dump_this_task(siginfo, d)
1127 else:
Andrew Geisslerc182c622020-05-15 14:13:32 -05001128 try:
1129 os.utime(siginfo, None)
1130 except PermissionError:
1131 pass
1132
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001133}
1134
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001135SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001136
1137# Event handler which removes manifests and stamps file for
1138# recipes which are no longer reachable in a build where they
1139# once were.
1140# Also optionally removes the workdir of those tasks/recipes
1141#
1142addhandler sstate_eventhandler2
1143sstate_eventhandler2[eventmask] = "bb.event.ReachableStamps"
1144python sstate_eventhandler2() {
1145 import glob
1146 d = e.data
1147 stamps = e.stamps.values()
1148 removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001149 preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
1150 preservestamps = []
1151 if os.path.exists(preservestampfile):
1152 with open(preservestampfile, 'r') as f:
1153 preservestamps = f.readlines()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001154 seen = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001155
1156 # The machine index contains all the stamps this machine has ever seen in this build directory.
1157 # We should only remove things which this machine once accessed but no longer does.
1158 machineindex = set()
1159 bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
1160 mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
1161 if os.path.exists(mi):
1162 with open(mi, "r") as f:
1163 machineindex = set(line.strip() for line in f.readlines())
1164
Brad Bishop316dfdd2018-06-25 12:45:53 -04001165 for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001166 toremove = []
1167 i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
1168 if not os.path.exists(i):
1169 continue
1170 with open(i, "r") as f:
1171 lines = f.readlines()
1172 for l in lines:
Brad Bishop19323692019-04-05 15:28:33 -04001173 try:
1174 (stamp, manifest, workdir) = l.split()
1175 if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
1176 toremove.append(l)
1177 if stamp not in seen:
1178 bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
1179 seen.append(stamp)
1180 except ValueError:
1181 bb.fatal("Invalid line '%s' in sstate manifest '%s'" % (l, i))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001182
1183 if toremove:
Brad Bishop316dfdd2018-06-25 12:45:53 -04001184 msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
1185 bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001186
Brad Bishop316dfdd2018-06-25 12:45:53 -04001187 removed = 0
1188 for r in toremove:
1189 (stamp, manifest, workdir) = r.split()
1190 for m in glob.glob(manifest + ".*"):
1191 if m.endswith(".postrm"):
1192 continue
1193 sstate_clean_manifest(m, d)
1194 bb.utils.remove(stamp + "*")
1195 if removeworkdir:
1196 bb.utils.remove(workdir, recurse = True)
1197 lines.remove(r)
1198 removed = removed + 1
1199 bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
1200
1201 bb.event.fire(bb.event.ProcessFinished(msg), d)
1202
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001203 with open(i, "w") as f:
1204 for l in lines:
1205 f.write(l)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001206 machineindex |= set(stamps)
1207 with open(mi, "w") as f:
1208 for l in machineindex:
1209 f.write(l + "\n")
1210
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001211 if preservestamps:
1212 os.remove(preservestampfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001213}