【问题标题】:Linux Kernel LinkingLinux 内核链接
【发布时间】:2015-05-29 17:05:21
【问题描述】:

正如我在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 内核 Makefile 中的格式。因此,当我运行 make 时,会出现以下错误:

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

我错过了什么?我只需要将函数复制到my_foo.c,因为fun1() 是静态的吗?

【问题讨论】:

  • 在 C 中,静态函数只能在同一个编译单元(即源文件)中使用。您不能编写静态函数的外部声明。
  • 所以...听起来我必须将函数复制过来。把它放在一个带有一点解释的答案中(在什么情况下我可以使用 extern 不同存储类的含义),我会接受它。

标签: c linux makefile linker kernel


【解决方案1】:

在 C 语言中,全局函数默认具有外部链接,这意味着它们可以通过包含原型从其他编译单元(C 源文件)中使用。

但是,如果函数被声明为static,那么它会变为内部链接,即只能在同一个编译单元中使用。

实际上,静态函数不会发出符号供链接器使用,而非静态函数会发出这样的函数。

在头文件中将小型实用程序函数编写为静态函数是一种标准做法,也可以选择标记为inline

如果函数不是非常小,我的建议就是将其设为外部(非静态)。请注意,在 Linux 内核中,为了能够从其他模块使用您的功能,您需要使用一些特定的宏导出符号(不要混合“内核模块”和“编译单元”)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2015-02-26
    • 2011-10-14
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多