From 85ffd927c7834f4111ae1740b8aad5a9c444b7aa Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Wed, 2 Dec 2015 11:44:30 +1300 Subject: classes/kernel-check: add a class to check kernel config options Some user-space software has specific requirements about the kernel configuration options selected. This class allows a recipe to explicitly state the kernel configuration options it needs (through a REQUIRED_KERNEL_OPTIONS variable). This is a space separated list, where each item is one of: (a) an option name (e.g. CONFIG_FHANDLE, in which case CONFIG_FHANDLE must be set to y or m to match) (b) optionname=value (e.g. CONFIG_FHANDLE=y, in which case CONFIG_FHANDLE must be set to y). If the specified value is n, it will also match if the option is not present. (c) optionname1|optionname2|... (e.g. CONFIG_EXT2_FS|CONFIG_EXT4_USE_FOR_EXT23, meaning that either CONFIG_EXT2_FS or CONFIG_EXT4_USE_FOR_EXT23 must be set to y or m to match). Inheriting the class will also add a dependency from do_configure on virtual/kernel:do_shared_workdir so that the kernel config is there to check. If one or more items are not matched, then a warning will be printed at do_configure time. (This is a warning rather than an error in case you are using linux-dummy with an externally built kernel). A separate function is also provided should you wish to check a config option from python code - but note you must only call this in a place where you can guarantee that the kernel config has been written to the sysroot (i.e. from a task that has virtual/kernel:do_shared_workdir in its depends varflag value). Fixes [YOCTO #5574]. Signed-off-by: Paul Eggleton --- meta/classes/kernel-check.bbclass | 97 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 meta/classes/kernel-check.bbclass diff --git a/meta/classes/kernel-check.bbclass b/meta/classes/kernel-check.bbclass new file mode 100644 index 0000000000..d202f4e320 --- /dev/null +++ b/meta/classes/kernel-check.bbclass @@ -0,0 +1,97 @@ +# Provides a means of checking within a recipe if particular kernel +# config options are enabled +# +# Copyright (C) 2016 Intel Corporation +# +# Example usage (within a recipe): +# +# inherit kernel-check +# REQUIRED_KERNEL_OPTIONS = "CONFIG_CGROUPS CONFIG_NAMESPACES" +# +# If one or more of the options aren't in the built kernel configuration +# you will get a warning at do_configure time. +# +# You can also use the check_kernel_config_options() function to do +# explicit checks yourself (and perform a different action). + +def check_kernel_config_options(options, d): + """ + A function you can use to do explicit checks for kernel config + options from python code + """ + + if isinstance(options, basestring): + required = options.split() + else: + required = options[:] + missing = [] + diffvalue = [] + if required: + with open(d.expand('${STAGING_KERNEL_BUILDDIR}/.config'), 'r') as f: + for line in f: + if line.startswith('#'): + continue + linesplit = line.rstrip().split('=', 1) + if len(linesplit) < 2: + continue + linevalue = linesplit[1] + for req in required: + found = False + if '|' in req: + for reqitem in req.split('|'): + if reqitem == linesplit[0]: + if linevalue in ['y', 'm']: + found = True + break + else: + reqsplit = req.split('=', 1) + # Can check for CONFIG_OPTION or CONFIG_OPTION=value + if len(reqsplit) > 1: + reqvalue = reqsplit[1] + else: + reqvalue = None + if reqsplit[0] == linesplit[0]: + if reqvalue is None: + if linevalue not in ['y', 'm']: + diffvalue.append((reqsplit[0], 'y or m', linevalue)) + elif reqvalue.strip("'\"") != linevalue.strip("'\""): + diffvalue.append((reqsplit[0], reqvalue, linevalue)) + found = True + + if found: + required.remove(req) + break + + for req in required: + reqsplit = req.split('=', 1) + if len(reqsplit) > 1: + if reqsplit[1] == 'n': + continue + missing.append('%s=%s' % reqsplit) + else: + missing.append('%s' % req) + + return missing, diffvalue + + +python check_kernel_config() { + pn = d.getVar('PN', True) + required = d.getVar('REQUIRED_KERNEL_OPTIONS', True) or '' + if ' | ' in required: + bb.error('Invalid REQUIRED_KERNEL_OPTIONS value - cannot have spaces around |') + if ' = ' in required: + bb.error('Invalid REQUIRED_KERNEL_OPTIONS value - cannot have spaces around =') + missing, diffvalue = check_kernel_config_options(required, d) + if missing or diffvalue: + reqstr = '\n '.join(missing + ['%s=%s (actual value %s)' % item for item in diffvalue]) + # Just warn here for cases like linux-dummy where we don't actually + # know the final config + bb.warn('The kernel you are building against is missing the following required configuration options:\n %s' % reqstr) +} + +python() { + if d.getVar('REQUIRED_KERNEL_OPTIONS', True): + d.appendVar('DEPENDS', ' virtual/kernel') + d.appendVarFlag('do_configure', 'prefuncs', ' check_kernel_config') + d.appendVarFlag('do_configure', 'depends', ' virtual/kernel:do_shared_workdir') +} -- cgit 1.2.3-korg