我正在尝试按照此 guide 编译一个简单的 hello world 模块,但我对
Makefile
实际上在做什么感到困惑。
这是:
obj-m += hello-1.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
我知道,当我输入
make
命令时,它将运行运行 all
的 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
配方。所以现在它运行在 -C
标志后给出的路径中找到的 Makefile,但是 M=$(PWD) modules
是做什么的?
这是一个细分:
obj-m
:指定构建为可加载内核模块的目标文件。
all and clean
:如果默认运行make
,它将运行第一个目标,即all
。但我们也可以使用 make all
和 make clean
:它只会运行那些特定的目标。
例如:
make all
# Will run: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
make clean
# Will run: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
uname -r
:获取当前内核的版本信息。
示例:对我来说,输出是
4.6.0-rc1
。
选项
-C dir
:在读取其中的 makefile 之前更改为目录 dir
。
示例:
make -C /lib/modules/$(shell uname -r)/build
# Will translate to: make -C /lib/modules/4.6.0-rc1/build
# And execute the Makefile at /lib/modules/4.6.0-rc1/build/Makefile
$(PWD)
:获取当前目录的路径。
现在您想使用以下方法创建可加载模块:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
您的源代码需要特定的环境才能编译。这就是为什么我们必须使用
-C
选项来更改构建目录。其中包含所有需要的定义、头文件、宏等。现在,在更改到构建目录后,您可以使用 M=$(PWD)
告诉内核 Makefile 模块所在的位置。
要编译内核模块,通常需要的
make
命令采用以下形式:
make -C /lib/modules/3.16.0-70-generic/build M=/home/test/ldd3/hello modules
其中,
-C
表示切换到另一条路径。
/lib/modules/3.16.0-70-generic/
是所使用的内核的路径,并且
/home/test/ldd3/hello
是模块源所在的位置。
M=$(PWD) 模块有什么作用?
正如我所说,
M=$(PWD)
只是一个 shell 变量,用于存储内核模块的当前路径。 make
需要在切换到内核构建路径时存储它。