0

So as I mentioned in here, I'm doing some changes to the Linux Kernel.

Right now, the changes are very small, but to isolate them, I want my stuff to be in its own file.

My changes basically redefine some functions and as such, they rely on functions in a parent file.

So foo.c contains:

/* headers.h does not contain a prototype my_fun2*/
#include "headers.h"
static void fun1(){
  ...
}

void fun2(){
 ...
 fun1()
}

And my_foo.c contains:

/* headers.h does not contain a prototype my_fun2*/
#include "headers.h"
/* Note: I'm not #include "foo.c" */
extern void fun1();

void my_fun2()
{
  ...
  fun1()
}

You'll note that in my_foo.c I have extern void fun1() and not extern static void fun1() because this apparently causes a conflict due to storage classes. Further explanation on this would be nice.

Now that I have my code the way I want it, I'll edit the corresponding Makefile to have the following

obj-$(CONFIG_MY_FOO) +=foo.o my_foo.o

With all of this put together though, it doesn't seem to work. I've used make files before and normally a recipe would be:

foo: foo.o bar.o
  $(cc) foo.o bar.o -o foo

foo.o: foo.c
  $(cc) -c foo.c

bar.o: bar.c
  $(cc) -c bar.c

However, this doesn't seem to be the format in the Linux Kernel Makefiles. So when I run make I get the following error:

my_foo.c:XX: undefined reference to `fun1()'

What am I missing? Do I just need to copy the functions to my_foo.c because fun1() is static?

Community
  • 1
  • 1
SailorCire
  • 548
  • 1
  • 7
  • 24
  • In C, static functions can only be used from the same compilation unit (that is source file). You cannot write an extern declaration of a static function. – rodrigo Mar 25 '15 at 20:24
  • So...sounds like I got to copy the functions over. Put that in an answer with a little bit of explanation (in what cases can I use extern what different storage classes mean) and I'll accept it. – SailorCire Mar 25 '15 at 20:31

1 Answers1

3

In C, global functions have external linkage by default, that means that they can be used from other compilation units (C source file) just by including a prototype.

However, if the function is declared as static, then it changes to internal linkage, that is it can only be used from the same compilation unit.

Practically speaking, a static function does not emit a symbol for the linker to use while a non-static function does emit such a function.

It is a somewhat standard practice to write small utility functions as static functions in header files, optionally also tagged as inline.

If the function is not very small my advice is just to make it external (non static). Note that in the Linux kernel, to be able to use your function from other module, you need to export the symbol using some specific macros (do not mix "kernel module" and "compilation unit").

rodrigo
  • 94,151
  • 12
  • 143
  • 190