22

I'm trying to compile a linux kernel module using a Makefile:

obj-m += main.o

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

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

Which gives me:

main.c:54: warning: ISO C90 forbids mixed declarations and code

I need to switch to C99. After reading I noticed I need to add a flag -std=c99, not sure where it suppose to be added.

How do I change the Makefile so it will compile as C99?

mtvec
  • 17,846
  • 5
  • 52
  • 83
djTeller
  • 515
  • 2
  • 5
  • 14
  • I thought C99 was a exploit script for PHP hehe – RobertPitt Jan 16 '11 at 02:31
  • [How to compile a Linux kernel module using -std=gnu99?](https://stackoverflow.com/questions/15910064/how-to-compile-a-linux-kernel-module-using-std-gnu99) – Shay Oct 09 '19 at 13:19

3 Answers3

23

The correct way to add compiler flags when compiling modules is by setting the ccflags-y variable. Like this:

ccflags-y := -std=gnu99

See Documentation/kbuild/makefiles.txt in the kernel tree for more information.

Note that I'm using the gnu99 standard instead of c99 since the Linux kernel heavily relies on GNU extensions.

Maus
  • 2,724
  • 5
  • 32
  • 37
mtvec
  • 17,846
  • 5
  • 52
  • 83
20

You could just add

CFLAGS=-std=c99

To the top of your makefile, or you can make the code compliant with C90 (as LukeN suggests.)

ocodo
  • 29,401
  • 18
  • 105
  • 117
-8

It's got nothing to do with the makefile. ISO C90 forbids declaring variables anywhere but in the beginning of a block or the file - like this

int main(int argc, char **argv) {
   int a; /* Ok */
   int b = 3; /* Ok */

   printf("Hello, the magic number is %d!\n", b);
   int c = 42; /* ERROR! Can only declare variables in the beginning of the block */
   printf("I also like %d.. but not as much as %d!\n", c, b);

   return 0;
}

Thus it has to be modified to this...

int main(int argc, char **argv) {
   int a; /* Ok */
   int b = 3; /* Ok */
   int c = 42; /* Ok! */

   printf("Hello, the magic number is %d!\n", b);
   printf("I also like %d.. but not as much as %d!\n", c, b);

   return 0;
}

You can only "fix" that in the source code, not in the makefile.

This rule has been relaxed in C99, but in my opinion it's a good idea to separate variable definitions, declarations and initializations from the code below it :)

So to change your makefile to make it compile with C99, you need to change the Makefile in the "build" directory that your makefile is referencing, and add the "-std=c99" at the "gcc" line compiling the source file.

LukeN
  • 5,590
  • 1
  • 25
  • 33
  • 8
    CFLAGS is much more common, preferred, and less fragile than editing each invocation of the compiler. –  May 29 '10 at 13:00
  • 6
    After living in the OO (Java) world for a long time and recently getting back into using C on a more day to day basis I have to disagree with the point about separating variable information out. Keeping things in as small a scope as possible seems more important. Some variables will only be needed inside of a while or for loop for example. – powerj1984 May 11 '11 at 03:01
  • @powerj1984 You may use brace {} scoping in this case. LukeN is correct as in *what would be accepted by the kernel main line*. Whether that is a good thing all around, I won't say and I guess it is not what the OP asked. – artless noise Mar 03 '14 at 23:08
  • The kernel allows c11 now, then no need to stay with this old pedantic style. – Alexis Feb 09 '22 at 08:10