4

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 echoed $(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!)

Eldar Abusalimov
  • 24,387
  • 4
  • 67
  • 71
Shahbaz
  • 46,337
  • 19
  • 116
  • 182

2 Answers2

8

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
alexander
  • 2,703
  • 18
  • 16
  • About the line you added: _Kbuild system doesn't use EXTRA_CFLAGS and some others variables from environment._ I doubt that would be true. I **did** use `EXTRA_CFLAGS` with -I/path/to/whatever and it was working. The problem was when /path/to/whatever got inside a variable. Otherwise, `EXTRA_CFLAGS` seemed to be used – Shahbaz Jan 05 '12 at 22:19
  • 1
    You are right about that line, so I removed it and added new comment. – alexander Jan 05 '12 at 23:01
0

It most likely because of recursive flavor of EXTRA_CFLAGS, which gets actually expanded in a sub-make, which doesn't have an access to MAIN_MODULE_HOME referred from it.

First, try to export MAIN_MODULE_HOME:

export MAIN_MODULE_HOME

I would also tried to flatten EXTRA_CFLAGS before using it (however, I'm not sure whether this is a good practice for Kbuild):

EXTRA_CFLAGS := $(EXTRA_CFLAGS)
Eldar Abusalimov
  • 24,387
  • 4
  • 67
  • 71
  • I tried export, it didn't work (although what you said made perfect sense) and oddly enough, your second suggestion (flattening `EXTRA_CFLAGS` didn't work either. – Shahbaz Jan 05 '12 at 16:08
  • @Shahbaz, well, just as a guess, may be Kbuild checks the origin of `EXTRA_CFLAGS` variable and if it comes not from command line it might be ignored. – Eldar Abusalimov Jan 05 '12 at 16:24