如何在以下 makefile 下以空格分隔的目录中编译 Linux 内核模块?

Acs*_*sor 6 make whitespace

我试图编译内核模块源代码,直到我注意到一些空格导致路径名不匹配。我发现自己所在的目录是:

axor@vacuum:~/software/CS 8803/Operating System Concepts/Chapter 2/ch2$ ls
Makefile  simple.c
Run Code Online (Sandbox Code Playgroud)

我招致的错误:

axor@vacuum:~/software/CS 8803/Operating System Concepts/Chapter 2/ch2$ make
make -C /lib/modules/4.9.0-3-amd64/build M="/home/none/software/CS 8803/Operating System Concepts/Chapter 2/ch2" modules
make[1]: Entering directory '/usr/src/linux-headers-4.9.0-3-amd64'
/usr/src/linux-headers-4.9.0-3-common/scripts/Makefile.build:44: /home/none/software/CS/Makefile: No such file or directory
make[4]: *** No rule to make target '/home/none/software/CS/Makefile'.  Stop.
make[3]: *** [/usr/src/linux-headers-4.9.0-3-common/Makefile:1507: _module_/home/none/software/CS] Error 2
make[2]: *** [Makefile:150: sub-make] Error 2
make[1]: *** [Makefile:8: all] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.9.0-3-amd64'
make: *** [Makefile:4: all] Error 2
Run Code Online (Sandbox Code Playgroud)

现在,我很清楚目录名称中的空格是导致问题的原因。我将感兴趣的目录树重命名为~/software/CS-8803/Operating-System-Concepts/Chapter-2/ch2,所有这些都有效。

问题:即使在包含空格的目录名下,我怎样才能使以下 makefile 正常工作?

obj-m += simple.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
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 9

你不能。makefile 语法严重依赖空格来分隔单词。当文件名包含空格时,很难编写正确工作的 makefile,Linux 内核 makefile 与大多数 makefile 一样,不要尝试。

在 makefile 中的命令中使用文件名时,也很难安排正确地引用文件名,而且大多数 makefile 都不会尝试。因此,请避免使用 shell 特有的所有字符:不仅是空格,还有!"#$&'()*;<=>?[]\`{|}.

您的情况的解决方法是使用其路径不包含任何特殊字符的符号链接。我认为这适用于 Linux 内核 makefile。它在使用 GNU makerealpath函数的 makefile 中不起作用,但内核 makefile 不在外部驱动程序的路径上使用它。

axor@vacuum:~/software/CS 8803/Operating System Concepts/Chapter 2/ch2$ ln -s "$PWD" /tmp/ch2
axor@vacuum:~/software/CS 8803/Operating System Concepts/Chapter 2/ch2$ cd !$
axor@vacuum:/tmp/ch2$ make
make -C /lib/modules/4.9.0-3-amd64/build M="/tmp/ch2" modules
…
Run Code Online (Sandbox Code Playgroud)