0

I want to build a basic main.c, that is actually a kernel module written in C. I have include header files that are in include/. I want to use GCC -I to make GCC search for the include headers in -Iinclude. However, GCC doesn't seem to understand that, and I have no clue how to debug it.

Tree:

main.c
include
   file.h

main.c

#include "file.h"
...

Makefile:

EXTRA_CFLAGS += -Iinclude -Werror -Wall \
                -Wno-missing-braces -Wno-error=unused-function

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

The error:

main.c: fatal error: file.h: No such file or directory

1 Answers1

1

That's because make is not actually running in your directory, when it compiles things.

The -C option in this command:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

tells make to change it's current working directory to that path. Thus, include is no longer the include directory in your current directory.

You should write it like this:

EXTRA_CFLAGS += -I'$M/include' -Werror -Wall \
                -Wno-missing-braces -Wno-error=unused-function

all:
        $(MAKE) -C "/lib/modules/$$(uname -r)/build" M='$(CURDIR)' modules

clean:
        $(MAKE) -C "/lib/modules/$$(uname -r)/build" M='$(CURDIR)' clean

You should always use $(MAKE), and never make, when running a sub-make. And using make's shell function is not really needed since a recipe is already running in a shell. And, PWD is just inherited from the calling shell and might be inaccurate.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • This doens't work. `CURDIR` _does_ work and point to the right directory, it should find `include`, however it still won't find the header file. `main.c` is still not able to find `file.h` – nigihen Shoam Jul 06 '22 at 20:40
  • 1
    Please make sure you're using my latest edits. You should be using `$M` in the `EXTRA_CFLAGS`. – MadScientist Jul 06 '22 at 20:42
  • Damn, it worked when I changed `CURDIR` to `M`. Why is that? `CURDIR` _does_ point to my current working directory, that is my tree. – nigihen Shoam Jul 06 '22 at 20:43
  • 2
    When you run the top-level make, `CURDIR` is your directory. But, as I said, you're invoking a sub-make in a different directory and that sub-make is doing all the work. In that sub-make, `CURDIR` is set to the working directory of the sub-make, not your directory. That's why you set `M=$(CURDIR)` on the sub-make command line so that in the sub-make the variable `M` is set to your directory; whenever you want to talk about your directory you use `$M`. – MadScientist Jul 06 '22 at 20:46