I have a main kernel module with which other kernel modules communicate. I have structured the modules like this (conceptually):
main module/
|
\drivers/
|
|\driver1
|\driver2
\driver3
Since these are kernel modules, I need to compile them like this:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
However, since the Makefile of drivers can be called from previous directories, I need to do the $(shell pwd)
before calling the other make (linux's make). So the Makefile now looks like this:
CURRENT_DIR := $(shell pwd)
.PHONY: all
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(CURRENT_DIR) modules
So far it is fine and it works perfectly. The problem is this: I have a file that the drivers need to include, so I have to give the include path to make. I first tried
EXTRA_CFLAGS += -I../..
and immediately understood why it doesn't work (relative path would be to /lib/module/... not to current directory). So I changed it to:
MAIN_MODULE_HOME := $(CURRENT_DIR)/../..
EXTRA_CFLAGS += -I$(MAIN_MODULE_HOME)
Oddly enough, this doesn't work! If I write
EXTRA_CFLAGS += -Ipath/I/get/from/pwd/../..
manually, it compiles! Can someone explain what I am doing wrong? Before calling make, I echo
ed $(CURRENT_DIR)
and $(MAIN_MODULE_HOME)
and the variables are meaningful.
I know that EXTRA_CFLAGS
is not immediately evaluated, but since CURRENT_DIR
and MAIN_MODULE_HOME
are declared with :=
I don't understand how things are getting messed up.
(If anyone can phrase the question title better, please do!)
You should pass EXTRA_CFLAGS to make like this:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(CURRENT_DIR) \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" modules
Update:
The content of driver1/Makefile is read twice: first - when you run make
inside driver1 directory, second - by Kbuild system.
First, CURRENT_DIR := $(shell pwd)
is evaluated to something like /home/users/.../main module/drivers/driver1
. Second, Kbuild evaluates CURRENT_DIR := $(shell pwd)
to something like /usr/src/linux-headers-2.6.32-33-generic/
That situation described in LDD3, ch2, p24
The trick is to write your makefile as follows:
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
#endif
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