<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 9, 2016 at 12:43 AM, Paul Eggleton <span dir="ltr">&lt;<a href="mailto:paul.eggleton@linux.intel.com" target="_blank">paul.eggleton@linux.intel.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Some user-space software has specific requirements about the kernel<br>
configuration options selected. This class allows a recipe to explicitly<br>
state the kernel configuration options it needs (through a<br>
REQUIRED_KERNEL_OPTIONS variable). This is a space separated list, where<br>
each item is one of:<br>
  (a) an option name (e.g. CONFIG_FHANDLE, in which case CONFIG_FHANDLE<br>
      must be set to y or m to match)<br>
  (b) optionname=value (e.g. CONFIG_FHANDLE=y, in which case<br>
      CONFIG_FHANDLE must be set to y). If the specified value is n,<br>
      it will also match if the option is not present.<br>
  (c) optionname1|optionname2|... (e.g.<br>
      CONFIG_EXT2_FS|CONFIG_EXT4_USE_FOR_EXT23, meaning that either<br>
      CONFIG_EXT2_FS or CONFIG_EXT4_USE_FOR_EXT23 must be set to y or<br>
      m to match).<br></blockquote><div><br></div><div><br></div><div>This duplicates code that is already in the kconf_check routines, which I&#39;ve already</div><div>made generic (and added dependency information) for the 2.2 release ... so call</div><div>me confused that I&#39;ve never heard about this until now :(</div><div><br></div><div>Bruce</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Inheriting the class will also add a dependency from do_configure on<br>
virtual/kernel:do_shared_workdir so that the kernel config is there to<br>
check. If one or more items are not matched, then a warning will be<br>
printed at do_configure time. (This is a warning rather than an error<br>
in case you are using linux-dummy with an externally built kernel).<br>
<br>
A separate function is also provided should you wish to check a config<br>
option from python code - but note you must only call this in a place<br>
where you can guarantee that the kernel config has been written to the<br>
sysroot (i.e. from a task that has virtual/kernel:do_shared_workdir in<br>
its depends varflag value).<br>
<br>
Fixes [YOCTO #5574].<br>
<br>
Signed-off-by: Paul Eggleton &lt;<a href="mailto:paul.eggleton@linux.intel.com">paul.eggleton@linux.intel.com</a>&gt;<br>
---<br>
 meta/classes/kernel-check.bbclass | 97 +++++++++++++++++++++++++++++++++++++++<br>
 1 file changed, 97 insertions(+)<br>
 create mode 100644 meta/classes/kernel-check.bbclass<br>
<br>
diff --git a/meta/classes/kernel-check.bbclass b/meta/classes/kernel-check.bbclass<br>
new file mode 100644<br>
index 0000000..d202f4e<br>
--- /dev/null<br>
+++ b/meta/classes/kernel-check.bbclass<br>
@@ -0,0 +1,97 @@<br>
+# Provides a means of checking within a recipe if particular kernel<br>
+# config options are enabled<br>
+#<br>
+# Copyright (C) 2016 Intel Corporation<br>
+#<br>
+# Example usage (within a recipe):<br>
+#<br>
+# inherit kernel-check<br>
+# REQUIRED_KERNEL_OPTIONS = &quot;CONFIG_CGROUPS CONFIG_NAMESPACES&quot;<br>
+#<br>
+# If one or more of the options aren&#39;t in the built kernel configuration<br>
+# you will get a warning at do_configure time.<br>
+#<br>
+# You can also use the check_kernel_config_options() function to do<br>
+# explicit checks yourself (and perform a different action).<br>
+<br>
+def check_kernel_config_options(options, d):<br>
+    &quot;&quot;&quot;<br>
+    A function you can use to do explicit checks for kernel config<br>
+    options from python code<br>
+    &quot;&quot;&quot;<br>
+<br>
+    if isinstance(options, basestring):<br>
+        required = options.split()<br>
+    else:<br>
+        required = options[:]<br>
+    missing = []<br>
+    diffvalue = []<br>
+    if required:<br>
+        with open(d.expand(&#39;${STAGING_KERNEL_BUILDDIR}/.config&#39;), &#39;r&#39;) as f:<br>
+            for line in f:<br>
+                if line.startswith(&#39;#&#39;):<br>
+                    continue<br>
+                linesplit = line.rstrip().split(&#39;=&#39;, 1)<br>
+                if len(linesplit) &lt; 2:<br>
+                    continue<br>
+                linevalue = linesplit[1]<br>
+                for req in required:<br>
+                    found = False<br>
+                    if &#39;|&#39; in req:<br>
+                        for reqitem in req.split(&#39;|&#39;):<br>
+                            if reqitem == linesplit[0]:<br>
+                                if linevalue in [&#39;y&#39;, &#39;m&#39;]:<br>
+                                    found = True<br>
+                                    break<br>
+                    else:<br>
+                        reqsplit = req.split(&#39;=&#39;, 1)<br>
+                        # Can check for CONFIG_OPTION or CONFIG_OPTION=value<br>
+                        if len(reqsplit) &gt; 1:<br>
+                            reqvalue = reqsplit[1]<br>
+                        else:<br>
+                            reqvalue = None<br>
+                        if reqsplit[0] == linesplit[0]:<br>
+                            if reqvalue is None:<br>
+                                if linevalue not in [&#39;y&#39;, &#39;m&#39;]:<br>
+                                    diffvalue.append((reqsplit[0], &#39;y or m&#39;, linevalue))<br>
+                            elif reqvalue.strip(&quot;&#39;\&quot;&quot;) != linevalue.strip(&quot;&#39;\&quot;&quot;):<br>
+                                diffvalue.append((reqsplit[0], reqvalue, linevalue))<br>
+                            found = True<br>
+<br>
+                    if found:<br>
+                        required.remove(req)<br>
+                        break<br>
+<br>
+        for req in required:<br>
+            reqsplit = req.split(&#39;=&#39;, 1)<br>
+            if len(reqsplit) &gt; 1:<br>
+                if reqsplit[1] == &#39;n&#39;:<br>
+                    continue<br>
+                missing.append(&#39;%s=%s&#39; % reqsplit)<br>
+            else:<br>
+                missing.append(&#39;%s&#39; % req)<br>
+<br>
+    return missing, diffvalue<br>
+<br>
+<br>
+python check_kernel_config() {<br>
+    pn = d.getVar(&#39;PN&#39;, True)<br>
+    required = d.getVar(&#39;REQUIRED_KERNEL_OPTIONS&#39;, True) or &#39;&#39;<br>
+    if &#39; | &#39; in required:<br>
+        bb.error(&#39;Invalid REQUIRED_KERNEL_OPTIONS value - cannot have spaces around |&#39;)<br>
+    if &#39; = &#39; in required:<br>
+        bb.error(&#39;Invalid REQUIRED_KERNEL_OPTIONS value - cannot have spaces around =&#39;)<br>
+    missing, diffvalue = check_kernel_config_options(required, d)<br>
+    if missing or diffvalue:<br>
+        reqstr = &#39;\n  &#39;.join(missing + [&#39;%s=%s (actual value %s)&#39; % item for item in diffvalue])<br>
+        # Just warn here for cases like linux-dummy where we don&#39;t actually<br>
+        # know the final config<br>
+        bb.warn(&#39;The kernel you are building against is missing the following required configuration options:\n  %s&#39; % reqstr)<br>
+}<br>
+<br>
+python() {<br>
+    if d.getVar(&#39;REQUIRED_KERNEL_OPTIONS&#39;, True):<br>
+        d.appendVar(&#39;DEPENDS&#39;, &#39; virtual/kernel&#39;)<br>
+        d.appendVarFlag(&#39;do_configure&#39;, &#39;prefuncs&#39;, &#39; check_kernel_config&#39;)<br>
+        d.appendVarFlag(&#39;do_configure&#39;, &#39;depends&#39;, &#39; virtual/kernel:do_shared_workdir&#39;)<br>
+}<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.5<br>
<br>
--<br>
_______________________________________________<br>
Openembedded-core mailing list<br>
<a href="mailto:Openembedded-core@lists.openembedded.org">Openembedded-core@lists.openembedded.org</a><br>
<a href="http://lists.openembedded.org/mailman/listinfo/openembedded-core" rel="noreferrer" target="_blank">http://lists.openembedded.org/mailman/listinfo/openembedded-core</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">&quot;Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end&quot;</div>
</div></div>