Re: SRC_URI Directory Change
On Fri, Oct 15, 2021 at 6:58 AM Richard Purdie <richard.purdie@...> wrote:
I tested the patch you posted on IRC against bitbake 1.50.0. It seems to work quite well, but I think I found two minor bugs in it. I pasted an updated patch below. In a nutshell... If you have a SRC_URI file:// entry that ends in a "/", then you get a "." that is not enclosed in "/./" when running the checksum_dir method, which causes checksum_file to throw warnings that look like this: I think the simplest fix is to add a "pth = pth.rstrip("/")" in the checksum_dir method after the guard statement. But then that exposes a different issue in the patch. For recipes that trigger the above warning, the rstrip() fix fixes the warning, but then you expose a new problem in siggen.py calc_taskhash(). In your patched version, the check for the "/" fails to include the filename in the hash calculation for files at the root of a SRC_URI entry (there is no "/" to be found). This results in a task hash mismatch error on the first build, but not on subsequent builds for fairly obvious reasons. I solved this by adding a third field to the tuple with a True/False value, which is a much more reliable semaphore (IMHO). I tested these fixes and it worked perfectly. Here is an updated version of your patch that takes into account the fixes I described. I can produce a "patch against your patch" if these fixes are considered correct and do not cause even bigger problems that are not obvious to me. diff --git a/bitbake/lib/bb/checksum.py b/bitbake/lib/bb/checksum.py index 1d50a26426..fb8a77f6ab 100644 --- a/bitbake/lib/bb/checksum.py +++ b/bitbake/lib/bb/checksum.py @@ -50,6 +50,7 @@ class FileChecksumCache(MultiProcessCache): MultiProcessCache.__init__(self) def get_checksum(self, f): + f = os.path.normpath(f) entry = self.cachedata[0].get(f) cmtime = self.mtime_cache.cached_mtime(f) if entry: @@ -84,15 +85,24 @@ class FileChecksumCache(MultiProcessCache): return None return checksum + # + # Changing the format of file-checksums is problematic as both OE and Bitbake have + # knowledge of them. We need to encode a new piece of data, the portion of the path + # we care about from a checksum perspective. This means that files that change subdirectory + # are tracked by the task hashes. To do this, we do something horrible and put a "/./" into + # the path. The filesystem handles it but it gives us a marker to know which subsection + # of the path to cache. + # def checksum_dir(pth): # Handle directories recursively if pth == "/": bb.fatal("Refusing to checksum /") + pth = pth.rstrip("/") dirchecksums = [] for root, dirs, files in os.walk(pth, topdown=True): [dirs.remove(d) for d in list(dirs) if d in localdirsexclude] for name in files: - fullpth = os.path.join(root, name) + fullpth = os.path.join(root, name).replace(pth, os.path.join(pth, ".")) checksum = checksum_file(fullpth) if checksum: dirchecksums.append((fullpth, checksum)) diff --git a/bitbake/lib/bb/siggen.py b/bitbake/lib/bb/siggen.py index 0d88c6ec68..f649f39ced 100644 --- a/bitbake/lib/bb/siggen.py +++ b/bitbake/lib/bb/siggen.py @@ -308,13 +308,14 @@ class SignatureGeneratorBasic(SignatureGenerator): return def get_taskhash(self, tid, deps, dataCaches): - data = self.basehash[tid] for dep in self.runtaskdeps[tid]: data = data + self.get_unihash(dep) for (f, cs) in self.file_checksum_values[tid]: if cs: + if "/./" in f: + data = data + f.split("/./")[1] data = data + cs if tid in self.taints: @@ -372,7 +373,12 @@ class SignatureGeneratorBasic(SignatureGenerator): if runtime and tid in self.taskhash: data['runtaskdeps'] = self.runtaskdeps[tid] - data['file_checksum_values'] = [(os.path.basename(f), cs) for f,cs in self.file_checksum_values[tid]] + data['file_checksum_values'] = [] + for f,cs in self.file_checksum_values[tid]: + if "/./" in f: + data['file_checksum_values'].append((f.split("/./")[1], cs, True)) + else: + data['file_checksum_values'].append((os.path.basename(f), cs, False)) data['runtaskhashes'] = {} for dep in data['runtaskdeps']: data['runtaskhashes'][dep] = self.get_unihash(dep) @@ -1017,6 +1023,8 @@ def calc_taskhash(sigdata): for c in sigdata['file_checksum_values']: if c[1]: + if c[2]: + data = data + c[0] data = data + c[1] if 'taint' in sigdata: ..Ch:W.. P.S. The gettext-minimal-native_0.21.bb (from OEC) is a very good example of something that triggers this behavior. But I found plenty of others as well. "Perfection must be reached by degrees; she requires the slow hand of time." - Voltaire
|
|