Eu estava tentando compilar um código-fonte do módulo do kernel, até que notei que alguns espaços em branco estavam causando nomes de caminho incompatíveis. O diretório em que me encontrei foi:
axor@vacuum:~/software/CS 8803/Operating System Concepts/Chapter 2/ch2$ ls
Makefile simple.c
O erro em que eu cometi:
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
Agora, ficou claro para mim que os espaços em branco nos nomes dos diretórios estavam causando o problema. Renomeei a árvore de diretórios interessada ~/software/CS-8803/Operating-System-Concepts/Chapter-2/ch2
e tudo isso funcionou.
Pergunta: como posso fazer com que o seguinte makefile funcione corretamente mesmo em nomes de diretórios que contenham espaços em branco?
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
Você não pode. A sintaxe do makefile depende muito do espaço em branco para separar as palavras. É difícil escrever makefiles que funcionem corretamente quando os nomes dos arquivos contêm espaços, e os makefiles do kernel Linux, como a maioria dos makefiles, não tentam.
Também é difícil arranjar para citar nomes de arquivos corretamente quando eles são usados em um comando em um makefile, e também a maioria dos makefiles não tenta. Portanto, evite todos os caracteres especiais para o shell: não apenas espaços em branco, mas também
!"#$&'()*;<=>?[]\`{|}
.Uma solução alternativa no seu caso seria usar um link simbólico cujo caminho não contenha nenhum caractere especial. Eu acho que isso funciona com makefiles do kernel Linux. Ele não funciona em makefiles que usam a
realpath
função make GNU, mas os makefiles do kernel não a usam em caminhos para drivers externos.