PWD 在 Linux 内核模块的 Makefile 中不起作用

问题描述 投票:0回答:2

我正在尝试编写一个简单的 hello world 内核模块。我正在 Virtual Box 上使用 Ubuntu 18.04.2 LTS。在目录 /usr/src 中,我创建了一个名为 hello 的目录,并在该 hello 目录中创建了 hello.c 和一个 makefile。这是我的 makefile:

obj-m += hello.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

当我执行命令“sudo make”时,我得到以下输出:

make -C /lib/modules/5.3.0-28-generic/build M= modules
make[1]: Entering directory '/usr/src/linux-headers-5.3.0-28-generic'
make[2]: *** No rule to make target 'arch/x89/tools/relocs_32.c', needed by 'arch/x86/tools/relocs_32.o'. Stop.
arch/x86/Makefile:232: recipe for target 'archscripts' failed
make[1]: *** [archscripts] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.3.0-28-generic'
makefile:4: recipe for target 'all' failed
make: *** [all] Error 2

我尝试了 makefile 的一些变体,包括将“PWD”更改为“shell pwd”。据我所知,我已经安装了所有必需的工具和库。这里可能有什么问题?

linux makefile linux-kernel kernel-module
2个回答
3
投票

变量

PWD
shell 设置,因此您的 Makefile 依赖于从 shell 执行的
make
调用,就像我们通常在终端中键入
make
时所做的那样。

但是

sudo make
从普通用户环境执行
make
。此环境缺少
PWD
变量,因此您的 Makefile 行为不正确。这可以从您的输出中找到:

make -C /lib/modules/5.3.0-28-generic/build M= modules

$(shell pwd)
表达代替,更可靠:

obj-m += hello.o

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

或者,您可以使用以下方式以 root 权限调用

make

sudo /bin/sh -c make

这样

make
不是从普通的根环境中执行,而是在中间shell下执行。该 shell 设置
PWD
变量。

更新

正如@Ian Abbott 在评论中指出的,

$(PWD)
的另一种选择是
$(CURDIR)
。变量
CURDIR
make
本身设置(准确地说,由 GNU Make)。另请参阅该问题:bash:PWD 和 CURDIR 之间有什么区别?.


0
投票

你的Makefile应该看起来像这样

obj-m += hello.o

然后你的构建命令将如下所示

make -C $KDIR M=$PWD

其中 $KDIR 是内核构建的源代码树。

就是这样。其余的由 kbuild 系统处理。

请参考官方文档构建off-tree模块

© www.soinside.com 2019 - 2024. All rights reserved.