diff mbox series

[v2,5/5] base.bbclass: introduce prune_source_tree function

Message ID 20260521125828.718050-6-joaomarcos.costa@bootlin.com
State Changes Requested
Headers show
Series Split vim and xxd in different recipes | expand

Commit Message

Joao Marcos Costa May 21, 2026, 12:58 p.m. UTC
Add a helper function to be executed after do_unpack, if PRUNE_KEEP_PATHS
is defined.

This variable is a list (space-separated) of paths that should be kept,
while the others will be pruned. They can be directory names and
filenames, but globbing is not supported as of now.

prune_source_tree() is not a task on its own, of course. It belongs in
do_unpack's 'postfuncs' list, and also in do_unpack_and_patch
(archiver.bbclass): this ensures the archived sources (patched or
configured) will also be pruned.

As a concrete example, add PRUNE_KEEP_PATHS to vim-xxd so that vim's
sources are deleted and only xxd sources are kept.

Signed-off-by: João Marcos Costa <joaomarcos.costa@bootlin.com>
---
 meta/classes-global/base.bbclass        | 49 +++++++++++++++++++++++++
 meta/classes/archiver.bbclass           |  1 +
 meta/recipes-support/vim/vim-xxd_9.2.bb |  4 ++
 3 files changed, 54 insertions(+)

Comments

Quentin Schulz May 21, 2026, 1:11 p.m. UTC | #1
Hi João,

On 5/21/26 2:58 PM, Joao Marcos Costa via lists.openembedded.org wrote:
> Add a helper function to be executed after do_unpack, if PRUNE_KEEP_PATHS
> is defined.
> 
> This variable is a list (space-separated) of paths that should be kept,
> while the others will be pruned. They can be directory names and
> filenames, but globbing is not supported as of now.
> 
> prune_source_tree() is not a task on its own, of course. It belongs in
> do_unpack's 'postfuncs' list, and also in do_unpack_and_patch
> (archiver.bbclass): this ensures the archived sources (patched or
> configured) will also be pruned.
> 
> As a concrete example, add PRUNE_KEEP_PATHS to vim-xxd so that vim's
> sources are deleted and only xxd sources are kept.
> 

Have you tried the ;subpath=src/xxd argument in SRC_URI for the git fetcher?

I don't think we care about xxd being removed from vim recipe, but we do 
not want non-xxd in vim-xxd, so only checking out src/xxd should be 
enough hopefully?

Cheers,
Quentin
diff mbox series

Patch

diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass
index 62f2814bb7..edf37a8016 100644
--- a/meta/classes-global/base.bbclass
+++ b/meta/classes-global/base.bbclass
@@ -256,6 +256,55 @@  python create_source_date_epoch_stamp() {
 }
 do_unpack[postfuncs] += "create_source_date_epoch_stamp"
 
+PRUNE_KEEP_PATHS ??= ""
+python prune_source_tree() {
+    import shutil
+
+    # Space-separated list of paths (relative to ${S}) to keep.
+    #
+    # Example:
+    #   PRUNE_KEEP_PATHS = "READMEdir/Contents.info src/xxd SECURITY.md"
+    #
+    keep_paths = (d.getVar("PRUNE_KEEP_PATHS") or "").split()
+
+    if not keep_paths:
+        bb.debug(1, "do_unpack: prune_source_tree is disabled")
+        return
+
+    s = d.getVar("S")
+    keep_abs = {os.path.abspath(os.path.join(s, p)) for p in keep_paths}
+
+    def should_keep(path):
+        path = os.path.abspath(path)
+
+        for keep in keep_abs:
+            if (
+                path == keep or # exact match with PRUNE_KEEP_PATHS
+                path.startswith(keep + os.sep) or # parent directories
+                keep.startswith(path + os.sep) # child directories
+            ):
+                return True
+        return False
+
+    for root, dirs, _ in os.walk(s, topdown=False):
+        for d in dirs:
+            path = os.path.join(root, d)
+
+            if not should_keep(path):
+                bb.debug(1, "Removing directory: %s" % path)
+                shutil.rmtree(path)
+
+    # in case there are leftover files:
+    for root, _, files in os.walk(s):
+        for f in files:
+            path = os.path.join(root, f)
+
+            if not should_keep(path):
+                bb.debug(1, "Removing file: %s" % path)
+                os.remove(path)
+}
+do_unpack[postfuncs] .= "${@" prune_source_tree" if d.getVar("PRUNE_KEEP_PATHS") else ''}"
+
 def get_source_date_epoch_value(d):
     return oe.reproducible.epochfile_read(d.getVar('SDE_FILE'), d)
 
diff --git a/meta/classes/archiver.bbclass b/meta/classes/archiver.bbclass
index 1f1ee45bd7..1a0d6f8eea 100644
--- a/meta/classes/archiver.bbclass
+++ b/meta/classes/archiver.bbclass
@@ -620,6 +620,7 @@  addtask do_deploy_archives
 do_build[recrdeptask] += "do_deploy_archives"
 do_rootfs[recrdeptask] += "do_deploy_archives"
 do_populate_sdk[recrdeptask] += "do_deploy_archives"
+do_unpack_and_patch[postfuncs] .= "${@" prune_source_tree" if d.getVar("PRUNE_KEEP_PATHS") else ''}"
 
 python () {
     # Add tasks in the correct order, specifically for linux-yocto to avoid race condition.
diff --git a/meta/recipes-support/vim/vim-xxd_9.2.bb b/meta/recipes-support/vim/vim-xxd_9.2.bb
index 5cfacbcea6..b1058e18b7 100644
--- a/meta/recipes-support/vim/vim-xxd_9.2.bb
+++ b/meta/recipes-support/vim/vim-xxd_9.2.bb
@@ -16,6 +16,10 @@  inherit update-alternatives
 
 PROVIDES += "xxd"
 
+# After unpacking, the files/dirs. outside of this list are removed
+# see prune_source_tree() in base.bbclass
+PRUNE_KEEP_PATHS = "src/xxd/Makefile src/xxd/xxd.c"
+
 do_compile() {
     cd  ${S}/src/xxd;
     oe_runmake xxd