diff --git a/pycheribuild/projects/cross/cheribsd.py b/pycheribuild/projects/cross/cheribsd.py index 54efb3c9e..18cf69e54 100644 --- a/pycheribuild/projects/cross/cheribsd.py +++ b/pycheribuild/projects/cross/cheribsd.py @@ -1099,25 +1099,35 @@ def kernel_make_args_for_config(self, kernconfs: "list[str]", extra_make_args) - return kernel_options def clean(self) -> ThreadJoiner: - cleaning_kerneldir = False - builddir = self.build_dir + cleaning_kerneldirs = False + builddirs = None if self.config.skip_world: - kernel_dir = self.kernel_objdir(self.kernel_config) - print(kernel_dir) - if kernel_dir and kernel_dir.parent.exists(): - builddir = kernel_dir - cleaning_kerneldir = True - if kernel_dir.exists() and self.build_dir.exists(): - assert not os.path.relpath(str(kernel_dir.resolve()), str(self.build_dir.resolve())).startswith( - ".." - ), builddir - else: - self.warning("Do not know the full path to the kernel build directory, will clean the whole tree!") + kernel_dirs = [self.kernel_objdir(k) for k in self.kernconf_list()] + for kernel_dir in kernel_dirs: + print(kernel_dir) + if kernel_dir and kernel_dir.parent.exists(): + if builddirs is None: + builddirs = [] + builddirs.append(kernel_dir) + cleaning_kerneldirs = True + if kernel_dir.exists() and self.build_dir.exists(): + assert not os.path.relpath(str(kernel_dir.resolve()), str(self.build_dir.resolve())).startswith( + ".." + ), kernel_dir + if builddirs is None: + self.warning("Do not know the full path to any kernel build directories, will clean the whole tree!") + if builddirs is None: + builddirs = [self.build_dir] + clean_kwargs = {} if self.crossbuild: # avoid rebuilding bmake when crossbuilding: - return self.async_clean_directory(builddir, keep_root=not cleaning_kerneldir, keep_dirs=["bmake-install"]) - else: - return self.async_clean_directory(builddir) + # XXX: Should keep_root be conditional on crossbuild? + clean_kwargs["keep_root"] = not cleaning_kerneldirs + clean_kwargs["keep_dirs"] = ["bmake-install"] + joiner = ThreadJoiner() + for builddir in builddirs: + joiner += self.async_clean_directory(builddir, **clean_kwargs) + return joiner def _list_kernel_configs(self) -> None: """Emit a list of valid kernel configurations that can be given as --kernel-config overrides""" diff --git a/pycheribuild/utils.py b/pycheribuild/utils.py index 2f3108188..5a57f99d7 100644 --- a/pycheribuild/utils.py +++ b/pycheribuild/utils.py @@ -564,18 +564,31 @@ def uses_zypper(cls) -> bool: class ThreadJoiner: - def __init__(self, thread: "Optional[threading.Thread]"): - self.thread = thread + def __init__(self, threads: "Optional[Union[threading.Thread, list[threading.Thread]]]" = None): + if not isinstance(threads, list): + if threads is None: + self.threads = [] + else: + self.threads = [threads] + else: + self.threads = threads def __enter__(self) -> None: - if self.thread is not None: - self.thread.start() + for thread in self.threads: + thread.start() def __exit__(self, *args) -> None: - if self.thread is not None: - if self.thread.is_alive(): - status_update("Waiting for '", self.thread.name, "' to complete", sep="") - self.thread.join() + for thread in self.threads: + if thread.is_alive(): + status_update("Waiting for '", thread.name, "' to complete", sep="") + thread.join() + + def __add__(self, other: "ThreadJoiner") -> "ThreadJoiner": + return ThreadJoiner(self.threads + other.threads) + + def __iadd__(self, other: "ThreadJoiner") -> "ThreadJoiner": + self.threads += other.threads + return self def replace_one(s: str, old, new) -> str: