Message ID | 20231028000738.968009-1-bhstalel@gmail.com |
---|---|
State | New |
Headers | show |
Series | meta: classes-recipe: A class for simple Kernel modules | expand |
On Fri, Oct 27, 2023 at 8:07 PM BELHADJ SALEM Talel <bhstalel@gmail.com> wrote: > > The module class provides what is needed to compile a Linux Kernel module > but since the Makefile is always the same for simple modules that have > their sources in one directory level, I thought of creating new class wrapper > to automatically prepare the Makefile. > Also, using variable flag feature, a recipe can provide multiple modules > and can be handled the same way as PACKAGECONFIG is used to enabled/disable > features. I find this method of preparing a kernel module much harder to follow (and debug). So Richard is ok with the class, I have no objections, it may serve a class of developers, but it isn't something I'd support as a first option. But please, create a separate example for it, not modifying hello-world, we want that simple and explicit example to persist. Bruce > > Signed-off-by: Talel BELHAJSALEM <bhstalel@gmail.com> > --- > .../recipes-kernel/hello-mod/hello-mod_0.1.bb | 11 +- > meta/classes-recipe/simple-module.bbclass | 116 ++++++++++++++++++ > 2 files changed, 120 insertions(+), 7 deletions(-) > create mode 100644 meta/classes-recipe/simple-module.bbclass > > diff --git a/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb b/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > index a2fb212a68..f191b08be5 100644 > --- a/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > +++ b/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > @@ -3,16 +3,13 @@ DESCRIPTION = "${SUMMARY}" > LICENSE = "GPL-2.0-only" > LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" > > -inherit module > +inherit simple-module > > -SRC_URI = "file://Makefile \ > - file://hello.c \ > +SRC_URI = "file://hello.c \ > file://COPYING \ > " > > S = "${WORKDIR}" > > -# The inherit of module.bbclass will automatically name module packages with > -# "kernel-module-" prefix as required by the oe-core build environment. > - > -RPROVIDES:${PN} += "kernel-module-hello" > +MODULE_SRC = "hello" > +MODULE_SRC[hello] = "" > \ No newline at end of file > diff --git a/meta/classes-recipe/simple-module.bbclass b/meta/classes-recipe/simple-module.bbclass > new file mode 100644 > index 0000000000..a837dec848 > --- /dev/null > +++ b/meta/classes-recipe/simple-module.bbclass > @@ -0,0 +1,116 @@ > +# > +# Copyright OpenEmbedded Contributors > +# > +# SPDX-License-Identifier: MIT > +# > + > +# Class to generate Makefile for Linux Kernel modules > +# > +# The aim of this class is to provide a way to gain time > +# when creating recipes for Linux Kernel modules > +# > +# Required variable: > +# MODULE_SRC > +# > +# This variable itself counts on flags to know what files > +# to use for .ko generation and their .o dependencies > +# > +# Usage: > +# If you have the following module structure: > +# |-- module.c > +# |-- dep1.c > +# `-- dep2.c > +# then you set: > +# MODULE_SRC[module] = "dep1 dep2" > +# > +# This will generate: > +# obj-m += module.o > +# module-objs += dep1.o dep2.o > +# > +# This class supports multiple modules as well > +# each module will be added to obj-m and if it has dependencies > +# an -objs variable will be created. > +# > +# A module can be enabled or disabled by adding or removing > +# the module name from MODULE_SRC > +# > +# Limitations: > +# - All modules source files should exist in the same folder level > + > +inherit module > + > +python do_prepare_makefile() { > + > + if not (d.getVar('MODULE_SRC') or "").split(): > + bb.warn("You inherited easy-module but did not set drivers in MODULE_SRC") > + > + kernel_modules = (d.getVar('MODULE_SRC') or "").split() > + > + if kernel_modules: > + kernel_modules_flags = d.getVarFlags('MODULE_SRC') or [] > + > + objs_data = {} > + for k_module in kernel_modules: > + > + # Check if all enabled drivers have corresponding flag > + if not k_module in kernel_modules_flags: > + bb.fatal(f"Driver {k_module} is enabled but does not have a flag entry") > + > + k_module_file = f"{k_module}.c" > + if not os.path.isfile(k_module_file): > + bb.fatal(f"Source file {k_module_file} is not found") > + > + k_module_o = f"{k_module}.o" > + objs_data[k_module] = [] > + > + k_module_deps = (d.getVarFlag('MODULE_SRC', k_module) or "").split() > + for dep in k_module_deps: > + dep_file = f"{dep}.c" > + dep_o = f"{dep}.o" > + > + if not os.path.isfile(dep_file): > + bb.fatal(f"Dependency file {dep_file} for the {k_module_file} is not found") > + > + objs_data[k_module].append(dep_o) > + > + with open('Makefile', 'w') as mf: > + # Main modules > + mf.write( > + f""" > +# This Makefile is generated automatically by easy-module class > +obj-m += {' '.join([objm + '.o' for objm in objs_data.keys()])} > +""") > + > + # Modules dependencies > + for k_module, deps in objs_data.items(): > + if deps: > + mf.write( > + f""" > +{k_module}-objs += {' '.join([dep for dep in deps])} > +""") > + > + # Rest of Makefile > + mf.write( > + """ > +SRC := $(shell pwd) > + > +all: > +\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) > + > +modules_install: > +\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install > + > +clean: > +\trm -f *.o *~ core .depend .*.cmd *.ko *.mod.c > +\trm -f Module.markers Module.symvers modules.order > +\trm -rf .tmp_versions Modules.symvers > +""") > +} > + > +RPROVIDES:${PN} += "kernel-module-${PN}" > + > +export SRC = "${B}" > + > +do_prepare_makefile[docs] = "Automate Makefile preparation for simple Kernel modules" > +do_prepare_makefile[dirs] = "${B}" > +addtask do_prepare_makefile before do_configure after do_patch > \ No newline at end of file > -- > 2.25.1 > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#189756): https://lists.openembedded.org/g/openembedded-core/message/189756 > Mute This Topic: https://lists.openembedded.org/mt/102233042/1050810 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [bruce.ashfield@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=- >
Hello Bruce, Thanks for the feedback, I agree that this is more suitable for developers that want to integrate a quick driver or a driver that has no Makefile, but I think adding the class for now and then improvements or other ideas can come. I will remove the example as I included some examples in the class comment itself. Kind Regards Talel On Sat, Oct 28, 2023 at 1:35 PM Bruce Ashfield <bruce.ashfield@gmail.com> wrote: > On Fri, Oct 27, 2023 at 8:07 PM BELHADJ SALEM Talel <bhstalel@gmail.com> > wrote: > > > > The module class provides what is needed to compile a Linux Kernel module > > but since the Makefile is always the same for simple modules that have > > their sources in one directory level, I thought of creating new class > wrapper > > to automatically prepare the Makefile. > > Also, using variable flag feature, a recipe can provide multiple modules > > and can be handled the same way as PACKAGECONFIG is used to > enabled/disable > > features. > > I find this method of preparing a kernel module much harder to follow > (and debug). > > So Richard is ok with the class, I have no objections, it may serve a > class of > developers, but it isn't something I'd support as a first option. > > But please, create a separate example for it, not modifying hello-world, > we want > that simple and explicit example to persist. > > Bruce > > > > > Signed-off-by: Talel BELHAJSALEM <bhstalel@gmail.com> > > --- > > .../recipes-kernel/hello-mod/hello-mod_0.1.bb | 11 +- > > meta/classes-recipe/simple-module.bbclass | 116 ++++++++++++++++++ > > 2 files changed, 120 insertions(+), 7 deletions(-) > > create mode 100644 meta/classes-recipe/simple-module.bbclass > > > > diff --git a/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > b/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > > index a2fb212a68..f191b08be5 100644 > > --- a/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > > +++ b/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb > > @@ -3,16 +3,13 @@ DESCRIPTION = "${SUMMARY}" > > LICENSE = "GPL-2.0-only" > > LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" > > > > -inherit module > > +inherit simple-module > > > > -SRC_URI = "file://Makefile \ > > - file://hello.c \ > > +SRC_URI = "file://hello.c \ > > file://COPYING \ > > " > > > > S = "${WORKDIR}" > > > > -# The inherit of module.bbclass will automatically name module packages > with > > -# "kernel-module-" prefix as required by the oe-core build environment. > > - > > -RPROVIDES:${PN} += "kernel-module-hello" > > +MODULE_SRC = "hello" > > +MODULE_SRC[hello] = "" > > \ No newline at end of file > > diff --git a/meta/classes-recipe/simple-module.bbclass > b/meta/classes-recipe/simple-module.bbclass > > new file mode 100644 > > index 0000000000..a837dec848 > > --- /dev/null > > +++ b/meta/classes-recipe/simple-module.bbclass > > @@ -0,0 +1,116 @@ > > +# > > +# Copyright OpenEmbedded Contributors > > +# > > +# SPDX-License-Identifier: MIT > > +# > > + > > +# Class to generate Makefile for Linux Kernel modules > > +# > > +# The aim of this class is to provide a way to gain time > > +# when creating recipes for Linux Kernel modules > > +# > > +# Required variable: > > +# MODULE_SRC > > +# > > +# This variable itself counts on flags to know what files > > +# to use for .ko generation and their .o dependencies > > +# > > +# Usage: > > +# If you have the following module structure: > > +# |-- module.c > > +# |-- dep1.c > > +# `-- dep2.c > > +# then you set: > > +# MODULE_SRC[module] = "dep1 dep2" > > +# > > +# This will generate: > > +# obj-m += module.o > > +# module-objs += dep1.o dep2.o > > +# > > +# This class supports multiple modules as well > > +# each module will be added to obj-m and if it has dependencies > > +# an -objs variable will be created. > > +# > > +# A module can be enabled or disabled by adding or removing > > +# the module name from MODULE_SRC > > +# > > +# Limitations: > > +# - All modules source files should exist in the same folder level > > + > > +inherit module > > + > > +python do_prepare_makefile() { > > + > > + if not (d.getVar('MODULE_SRC') or "").split(): > > + bb.warn("You inherited easy-module but did not set drivers in > MODULE_SRC") > > + > > + kernel_modules = (d.getVar('MODULE_SRC') or "").split() > > + > > + if kernel_modules: > > + kernel_modules_flags = d.getVarFlags('MODULE_SRC') or [] > > + > > + objs_data = {} > > + for k_module in kernel_modules: > > + > > + # Check if all enabled drivers have corresponding flag > > + if not k_module in kernel_modules_flags: > > + bb.fatal(f"Driver {k_module} is enabled but does not > have a flag entry") > > + > > + k_module_file = f"{k_module}.c" > > + if not os.path.isfile(k_module_file): > > + bb.fatal(f"Source file {k_module_file} is not found") > > + > > + k_module_o = f"{k_module}.o" > > + objs_data[k_module] = [] > > + > > + k_module_deps = (d.getVarFlag('MODULE_SRC', k_module) or > "").split() > > + for dep in k_module_deps: > > + dep_file = f"{dep}.c" > > + dep_o = f"{dep}.o" > > + > > + if not os.path.isfile(dep_file): > > + bb.fatal(f"Dependency file {dep_file} for the > {k_module_file} is not found") > > + > > + objs_data[k_module].append(dep_o) > > + > > + with open('Makefile', 'w') as mf: > > + # Main modules > > + mf.write( > > + f""" > > +# This Makefile is generated automatically by easy-module class > > +obj-m += {' '.join([objm + '.o' for objm in objs_data.keys()])} > > +""") > > + > > + # Modules dependencies > > + for k_module, deps in objs_data.items(): > > + if deps: > > + mf.write( > > + f""" > > +{k_module}-objs += {' '.join([dep for dep in deps])} > > +""") > > + > > + # Rest of Makefile > > + mf.write( > > + """ > > +SRC := $(shell pwd) > > + > > +all: > > +\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) > > + > > +modules_install: > > +\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install > > + > > +clean: > > +\trm -f *.o *~ core .depend .*.cmd *.ko *.mod.c > > +\trm -f Module.markers Module.symvers modules.order > > +\trm -rf .tmp_versions Modules.symvers > > +""") > > +} > > + > > +RPROVIDES:${PN} += "kernel-module-${PN}" > > + > > +export SRC = "${B}" > > + > > +do_prepare_makefile[docs] = "Automate Makefile preparation for simple > Kernel modules" > > +do_prepare_makefile[dirs] = "${B}" > > +addtask do_prepare_makefile before do_configure after do_patch > > \ No newline at end of file > > -- > > 2.25.1 > > > > > > -=-=-=-=-=-=-=-=-=-=-=- > > Links: You receive all messages sent to this group. > > View/Reply Online (#189756): > https://lists.openembedded.org/g/openembedded-core/message/189756 > > Mute This Topic: https://lists.openembedded.org/mt/102233042/1050810 > > Group Owner: openembedded-core+owner@lists.openembedded.org > > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [ > bruce.ashfield@gmail.com] > > -=-=-=-=-=-=-=-=-=-=-=- > > > > > -- > - Thou shalt not follow the NULL pointer, for chaos and madness await > thee at its end > - "Use the force Harry" - Gandalf, Star Trek II >
On Sat, 2023-10-28 at 08:35 -0400, Bruce Ashfield wrote: > On Fri, Oct 27, 2023 at 8:07 PM BELHADJ SALEM Talel <bhstalel@gmail.com> wrote: > > > > The module class provides what is needed to compile a Linux Kernel module > > but since the Makefile is always the same for simple modules that have > > their sources in one directory level, I thought of creating new class wrapper > > to automatically prepare the Makefile. > > Also, using variable flag feature, a recipe can provide multiple modules > > and can be handled the same way as PACKAGECONFIG is used to enabled/disable > > features. > > I find this method of preparing a kernel module much harder to follow > (and debug). > > So Richard is ok with the class, I have no objections, it may serve a class of > developers, but it isn't something I'd support as a first option. > > But please, create a separate example for it, not modifying hello-world, we want > that simple and explicit example to persist. Richard isn't convinced. In most cases a kernel module from a source repository would have some form of makefile included with it. yes, if you're creating one from scratch, this is helpful but in general you do create a makefile at that point and are unlikely to want to keep auto-generating one. As such I'm not convinced this class matches the siutation most people wanting to build software would be in. Cheers, Richard
On Sat, Oct 28, 2023 at 9:51 AM Richard Purdie <richard.purdie@linuxfoundation.org> wrote: > > On Sat, 2023-10-28 at 08:35 -0400, Bruce Ashfield wrote: > > On Fri, Oct 27, 2023 at 8:07 PM BELHADJ SALEM Talel <bhstalel@gmail.com> wrote: > > > > > > The module class provides what is needed to compile a Linux Kernel module > > > but since the Makefile is always the same for simple modules that have > > > their sources in one directory level, I thought of creating new class wrapper > > > to automatically prepare the Makefile. > > > Also, using variable flag feature, a recipe can provide multiple modules > > > and can be handled the same way as PACKAGECONFIG is used to enabled/disable > > > features. > > > > I find this method of preparing a kernel module much harder to follow > > (and debug). > > > > So Richard is ok with the class, I have no objections, it may serve a class of > > developers, but it isn't something I'd support as a first option. > > > > But please, create a separate example for it, not modifying hello-world, we want > > that simple and explicit example to persist. > > Richard isn't convinced. > > In most cases a kernel module from a source repository would have some > form of makefile included with it. yes, if you're creating one from > scratch, this is helpful but in general you do create a makefile at > that point and are unlikely to want to keep auto-generating one. > > As such I'm not convinced this class matches the siutation most people > wanting to build software would be in. Everyone probably knows that I'm not in favour of generating pretty much anything that can be clearer and more explicit. :) I re-read my first reply, and it wasn't clear. It should have read "if Richard is ok", ... those joining words are important. What I meant to convey is that I wouldn't block something like this, if you were ok with it! Bruce > > Cheers, > > Richard
diff --git a/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb b/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb index a2fb212a68..f191b08be5 100644 --- a/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb +++ b/meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb @@ -3,16 +3,13 @@ DESCRIPTION = "${SUMMARY}" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" -inherit module +inherit simple-module -SRC_URI = "file://Makefile \ - file://hello.c \ +SRC_URI = "file://hello.c \ file://COPYING \ " S = "${WORKDIR}" -# The inherit of module.bbclass will automatically name module packages with -# "kernel-module-" prefix as required by the oe-core build environment. - -RPROVIDES:${PN} += "kernel-module-hello" +MODULE_SRC = "hello" +MODULE_SRC[hello] = "" \ No newline at end of file diff --git a/meta/classes-recipe/simple-module.bbclass b/meta/classes-recipe/simple-module.bbclass new file mode 100644 index 0000000000..a837dec848 --- /dev/null +++ b/meta/classes-recipe/simple-module.bbclass @@ -0,0 +1,116 @@ +# +# Copyright OpenEmbedded Contributors +# +# SPDX-License-Identifier: MIT +# + +# Class to generate Makefile for Linux Kernel modules +# +# The aim of this class is to provide a way to gain time +# when creating recipes for Linux Kernel modules +# +# Required variable: +# MODULE_SRC +# +# This variable itself counts on flags to know what files +# to use for .ko generation and their .o dependencies +# +# Usage: +# If you have the following module structure: +# |-- module.c +# |-- dep1.c +# `-- dep2.c +# then you set: +# MODULE_SRC[module] = "dep1 dep2" +# +# This will generate: +# obj-m += module.o +# module-objs += dep1.o dep2.o +# +# This class supports multiple modules as well +# each module will be added to obj-m and if it has dependencies +# an -objs variable will be created. +# +# A module can be enabled or disabled by adding or removing +# the module name from MODULE_SRC +# +# Limitations: +# - All modules source files should exist in the same folder level + +inherit module + +python do_prepare_makefile() { + + if not (d.getVar('MODULE_SRC') or "").split(): + bb.warn("You inherited easy-module but did not set drivers in MODULE_SRC") + + kernel_modules = (d.getVar('MODULE_SRC') or "").split() + + if kernel_modules: + kernel_modules_flags = d.getVarFlags('MODULE_SRC') or [] + + objs_data = {} + for k_module in kernel_modules: + + # Check if all enabled drivers have corresponding flag + if not k_module in kernel_modules_flags: + bb.fatal(f"Driver {k_module} is enabled but does not have a flag entry") + + k_module_file = f"{k_module}.c" + if not os.path.isfile(k_module_file): + bb.fatal(f"Source file {k_module_file} is not found") + + k_module_o = f"{k_module}.o" + objs_data[k_module] = [] + + k_module_deps = (d.getVarFlag('MODULE_SRC', k_module) or "").split() + for dep in k_module_deps: + dep_file = f"{dep}.c" + dep_o = f"{dep}.o" + + if not os.path.isfile(dep_file): + bb.fatal(f"Dependency file {dep_file} for the {k_module_file} is not found") + + objs_data[k_module].append(dep_o) + + with open('Makefile', 'w') as mf: + # Main modules + mf.write( + f""" +# This Makefile is generated automatically by easy-module class +obj-m += {' '.join([objm + '.o' for objm in objs_data.keys()])} +""") + + # Modules dependencies + for k_module, deps in objs_data.items(): + if deps: + mf.write( + f""" +{k_module}-objs += {' '.join([dep for dep in deps])} +""") + + # Rest of Makefile + mf.write( + """ +SRC := $(shell pwd) + +all: +\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) + +modules_install: +\t$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install + +clean: +\trm -f *.o *~ core .depend .*.cmd *.ko *.mod.c +\trm -f Module.markers Module.symvers modules.order +\trm -rf .tmp_versions Modules.symvers +""") +} + +RPROVIDES:${PN} += "kernel-module-${PN}" + +export SRC = "${B}" + +do_prepare_makefile[docs] = "Automate Makefile preparation for simple Kernel modules" +do_prepare_makefile[dirs] = "${B}" +addtask do_prepare_makefile before do_configure after do_patch \ No newline at end of file
The module class provides what is needed to compile a Linux Kernel module but since the Makefile is always the same for simple modules that have their sources in one directory level, I thought of creating new class wrapper to automatically prepare the Makefile. Also, using variable flag feature, a recipe can provide multiple modules and can be handled the same way as PACKAGECONFIG is used to enabled/disable features. Signed-off-by: Talel BELHAJSALEM <bhstalel@gmail.com> --- .../recipes-kernel/hello-mod/hello-mod_0.1.bb | 11 +- meta/classes-recipe/simple-module.bbclass | 116 ++++++++++++++++++ 2 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 meta/classes-recipe/simple-module.bbclass