Linux 内核链接
Linux Kernel Linking
因此,正如我在 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
虽然所有这些放在一起,但它似乎不起作用。我以前使用过制作文件,通常食谱是:
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 内核 Makefile 中的格式。所以当我 运行 make
我得到以下错误:
my_foo.c:XX: undefined reference to `fun1()'
我错过了什么?我是否只需要将函数复制到 my_foo.c
因为 fun1()
是静态的?
在 C 中,全局函数默认具有外部链接,这意味着它们可以通过包含原型从其他编译单元(C 源文件)使用。
但是,如果函数被声明为static
,则它变为内部链接,即只能在同一个编译单元中使用。
实际上,静态函数不会发出供链接器使用的符号,而非静态函数会发出这样的函数。
在头文件中将小型实用函数编写为静态函数是一种标准做法,还可以选择标记为 inline
。
如果函数不是很小,我的建议是将其设为外部(非静态)。请注意,在 Linux 内核中,为了能够从其他模块使用您的函数,您需要使用一些特定的宏来导出符号(不要混合使用 "kernel module" 和 "compilation unit")。
因此,正如我在 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
虽然所有这些放在一起,但它似乎不起作用。我以前使用过制作文件,通常食谱是:
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 内核 Makefile 中的格式。所以当我 运行 make
我得到以下错误:
my_foo.c:XX: undefined reference to `fun1()'
我错过了什么?我是否只需要将函数复制到 my_foo.c
因为 fun1()
是静态的?
在 C 中,全局函数默认具有外部链接,这意味着它们可以通过包含原型从其他编译单元(C 源文件)使用。
但是,如果函数被声明为static
,则它变为内部链接,即只能在同一个编译单元中使用。
实际上,静态函数不会发出供链接器使用的符号,而非静态函数会发出这样的函数。
在头文件中将小型实用函数编写为静态函数是一种标准做法,还可以选择标记为 inline
。
如果函数不是很小,我的建议是将其设为外部(非静态)。请注意,在 Linux 内核中,为了能够从其他模块使用您的函数,您需要使用一些特定的宏来导出符号(不要混合使用 "kernel module" 和 "compilation unit")。