I have decided to take the Eudyptula Challenge. After I submitted the first task which is to build a simple "Hello World!" module, I received the following answer.
Please read the requirements for the Makefile and allow the module to be built against any kernel source tree on the filesystem, not just those kernels that happened to be installed in
/lib/
at some point in time.
The requirements are:
The Makefile should be able to build the kernel module against the source of the currently-running kernel as well as being able to accept an arbitrary kernel sources directory from an environment variable.
What I am doing is checking whether the environment variable KERNELRELEASE
is set. If it is I build the module against
$(KERNELRELEASE)/build
and if it isn't against
/lib/modules/$(shell uname -r)/build
I can't understand why this does not satisfy the requirements of this task.
As per Eudyptula challenge rules, it is prohibited to give you direct solution, so I will try to describe elements of answer, so you can come up with solution by yourself. Basically, everything I've written below is described pretty much in Documentation/kbuild/modules.txt file (especially in section 3.1 - Shared Makefile ), so I don't think it would be some sort of rules violation. So below is just explanation for what is described in mentioned documentation.
KERNELRELEASE
variableWhat you are wrong about is thinking that $(KERNELRELEASE)
is intended for keeping the path to the kernel. What $(KERNELRELEASE)
variable actually means -- you can find it in Documentation/kbuild/makefiles.txt:
KERNELRELEASE
$(KERNELRELEASE)
is a single string such as"2.4.0-pre4"
, suitable for constructing installation directory names or showing in version strings. Some archMakefiles
use it for this purpose.
The thing is, your Makefile
is going to be executed 2 times: from your make
command and from kernel Makefile
. And $(KERNELRELEASE)
can be helpful to figure it out:
Makefile
is running from your make
command; at this step you are going to execute kernel's Makefile
(providing kernel directory using -C
param). Once you have run make
for kernel's Makefile (from inside of your Makefile), your Makefile
is going to be executed second time (see next item).Makefile
is executing from kernel's Makefile
(which defined this variable and called your Makefile
back). At this step you can use kernel build system features, like obj-m.-C
paramWhat you really need to do is define some custom variable in your Makefile
which will hold kernel directory path. You can call it KDIR
for example. As you know, your kernel sources are located at this path: /lib/modules/$(shell uname -r)/build
. Next you can provide this variable to -C
param (see man 1 make) when executing kernel's Makefile.
Next you have to make it possible to pass this variable from outside of your Makefile
. To do so, one can use conditional variable assignment operator:
KDIR ?= /lib/modules/$(shell uname -r)/build
This way if you pass KDIR
variable to your Makefile, like this:
$ make KDIR=bla-bla-bla
the KDIR
variable will have the value you passed. Otherwise it will contain default value, which is /lib/modules/$(shell uname -r)/build
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With