[yocto] [poky/classes] [PATCH] new alternatesrc.bbclass

Koehler, Yannick (HPN Aruba) yannick.koehler at hpe.com
Thu May 18 11:11:40 PDT 2017


In our environment, we have package that are store inside git in their own repo.  Using SRC_URI we fetch the code and build it from the git repo itself and all is fine.  When developer wants to change the content of the package, they had to clone, change, commit, push and only then they were able to test because yocto recipe clone/fetch from the git server only.

We investigated externalsrc to use it so to build from a local folder, but then this required that all our packages be located locally on disk.  In turn, that cause other kind of headaches.  

I came up with the following solution "alternatesrc.bbclass" which is based on "externalsrc.bbclass" and do nothing unless a folder exists at the "ALTERNATESRC" location.  If a folder exists there, then the git SRC_URI is ignored and the do_fetch, do_unpack & do_patch are disabled.  The code located at the folder is used as is (no specific branch are checked out so to allow testing local change that have not been committed).

I am hoping to get feedback and comments, and maybe help someone else by sharing this.

Since this is my first contribution, I apologize if I didn't do it properly.

---
 meta/classes/alternatesrc.bbclass | 70 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 meta/classes/alternatesrc.bbclass

diff --git a/meta/classes/alternatesrc.bbclass b/meta/classes/alternatesrc.bbclass
new file mode 100644
index 0000000000..13f85df851
--- /dev/null
+++ b/meta/classes/alternatesrc.bbclass
@@ -0,0 +1,72 @@
+# Copyright (C) 2017 Hewlett Packard Enterprise
+# Author: Yannick Koehler
+# Released under the MIT license (see COPYING.MIT for the terms)
+# Some code and influence taken from externalsrc.bbclass
+#
+# alternatesrc.bbclass enables use of an optionally existing source tree, usually external  
+# to the build system to build a piece of software rather than the usual fetch/unpack
+# process.
+#
+# To use, add alternatesrc to the global inherit and set ALTERNATESRC to point at the
+# directory you want to use containing the sources e.g. from local.conf for a recipe
+# called "myrecipe" you would do:
+#
+# INHERIT += "alternatesrc"
+# ALTERNATESRC_pn-myrecipe = "/path/to/my/source/tree"
+#
+
+ALTERNATESRC_COVEREDTASKS ?= "do_unpack do_fetch"
+
+python () {
+    alternatesrc = d.getVar('ALTERNATESRC', True)
+
+    if alternatesrc and os.path.isdir(alternatesrc):
+        # Make it obvious that this is happening, since forgetting about it could lead to much confusion
+        bb.note('NOTE: using alternate source tree %s' % (d.getVar('ALTERNATESRC', True)))
+
+        d.setVar('S', alternatesrc)
+
+        local_srcuri = []
+        fetch = bb.fetch2.Fetch((d.getVar('SRC_URI', True) or '').split(), d)
+        for url in fetch.urls:
+            url_data = fetch.ud[url]
+            parm = url_data.parm
+            if (url_data.type == 'file' or
+                    'type' in parm and parm['type'] == 'kmeta'):
+                local_srcuri.append(url)
+
+        d.setVar('SRC_URI', ' '.join(local_srcuri))
+
+        if '{SRCPV}' in d.getVar('PV', False):
+            # Dummy value because the default function can't be called with blank SRC_URI
+            d.setVar('SRCPV', '999')
+
+        tasks = filter(lambda k: d.getVarFlag(k, "task", True), d.keys())
+
+        for task in tasks:
+            #if task.endswith("_setscene"):
+            #    # sstate is never going to work for external source trees, disable it
+            #    bb.build.deltask(task, d)
+            #else:
+            # Since configure will likely touch ${S}, ensure only we lock so one task has access at a time
+            d.appendVarFlag(task, "lockfiles", " ${S}/singletask.lock")
+
+            # We do not want our source to be wiped out, ever (kernel.bbclass does this for do_clean)
+            cleandirs = (d.getVarFlag(task, 'cleandirs', False) or '').split()
+            setvalue = False
+            for cleandir in cleandirs[:]:
+                if d.expand(cleandir) == alternatesrc:
+                    cleandirs.remove(cleandir)
+                    setvalue = True
+            if setvalue:
+                d.setVarFlag(task, 'cleandirs', ' '.join(cleandirs))
+
+        fetch_tasks = ['do_fetch', 'do_unpack']
+
+        for task in d.getVar("ALTERNATESRC_COVEREDTASKS", True).split():
+            if local_srcuri and task in fetch_tasks:
+                continue
+            bb.build.deltask(task, d)
+    else:
+            bb.note('NOTE: using git source tree, since local folder %s is inexistent' % (d.getVar('ALTERNATESRC', True)))
+}
-- 
2.12.0




More information about the yocto mailing list