正如我在here中提到的,我正在对Linux内核进行一些更改。
现在,变化非常小,但为了隔离它们,我希望我的东西存放在自己的文件中。
我的更改基本上重新定义了一些函数,因此,它们依赖于父文件中的函数。
所以foo.c
包含:
/* headers.h does not contain a prototype my_fun2*/
#include "headers.h"
static void fun1(){
...
}
void fun2(){
...
fun1()
}
my_foo.c
包含:
/* 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()
}
您注意到在my_foo.c
我extern void fun1()
而不是extern static void fun1()
,因为这显然会因存储类而导致冲突。对此的进一步解释会很好。
现在我的代码按照我想要的方式进行,我会编辑相应的Makefile
以获得以下内容
obj-$(CONFIG_MY_FOO) +=foo.o my_foo.o
虽然把所有这些放在一起,但它似乎并不起作用。我之前使用过make文件,通常配方是:
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
但是,这似乎不是Linux Kernel Makefiles中的格式。因此,当我运行make
时,我收到以下错误:
my_foo.c:XX: undefined reference to `fun1()'
我错过了什么?我只需要将函数复制到my_foo.c
,因为fun1()
是静态的吗?
答案 0 :(得分:3)
在C语言中,全局函数默认具有外部链接,这意味着只需包含原型就可以从其他编译单元(C源文件)中使用它们。
但是,如果函数声明为static
,则它将更改为内部链接,即它只能在同一编译单元中使用。
实际上,静态函数不会为链接器发出符号,而非静态函数会发出这样的函数。
在头文件中将小实用程序函数编写为静态函数是一种有点标准的做法,也可以标记为inline
。
如果功能不是很小,我的建议就是将其设为外部(非静态)。请注意,在Linux内核中,为了能够使用其他模块中的函数,需要使用某些特定的宏导出符号(不要混用“内核模块”和“编译单元”)。