How to compile Linux kernel modules within white-space-separated directories under the following makefile

makewhitespace

I was trying to compile a kernel module source code, until I noticed that some whitespaces where causing mismatched path names. The directory under which I found myself was:

axor@vacuum:~/software/CS 8803/Operating System Concepts/Chapter 2/ch2$ ls
Makefile  simple.c

The error into which I incurred:

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

Now, it was clear to me that the white spaces in the directory names were causing the problem. I renamed the interested directory tree into ~/software/CS-8803/Operating-System-Concepts/Chapter-2/ch2 and all of that worked.

Question: how can I get the following makefile to work correctly even under directory names containing whitespaces?

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

Best Answer

You can't. The makefile syntax heavily relies on whitespace to separate words. It's difficult to write makefiles that work correctly when file names contain spaces, and the Linux kernel makefiles, like most makefiles, don't try.

It's also difficult to arrange to quote file names properly when they're used in a command in a makefile, and there too most makefiles don't try. So avoid all characters that are special to the shell: not only whitespace but also !"#$&'()*;<=>?[]\`{|}.

A workaround in your case would be to use a symbolic link whose path doesn't contain any special characters. I think this works with Linux kernel makefiles. It doesn't work in makefiles that use the GNU make realpath function, but the kernel makefiles don't use it on paths to external drivers.

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
…
Related Question