¿Por qué GNU Make intenta compilar un archivo objeto que no existe, para una regla sin una receta?
Si ejecutas make test
en el siguiente Makefile (con un directorio vacío):
test.%:
@echo $*
<p>test: test.dummyextension
obtendrás la siguiente salida:
dummyextension
o
cc test.o test.dummyextension -o test
clang: error: no such file or directory: 'test.o'
clang: error: no such file or directory: 'test.dummyextension'
clang: error: no input files
make: *** [test] Error 1
¿Por qué?
Sospecho que tiene algo que ver con reglas implícitas, pero busqué make -p
en mi máquina y no encontré ninguna regla implícita que coincida con %: %
. Esperaría que la salida simplemente sea dummyextension
, pero es como si hubiera un archivo test.o
fantasma en mi directorio (a pesar de verificar diez veces que no lo hay).
Si colocas un ;
después del prerrequisito test.dummyextension
, o agregas cualquier contenido a la regla test
, todo funciona como se espera. Este es el ejemplo mínimo de falla que puedo encontrar y no tengo idea de por qué verías este comportamiento. ¿Alguna idea?
davy.ai
Según la salida proporcionada, parece que make está tratando de construir un ejecutable llamado
test
usandotest.o
ytest.dummyextension
como requisitos previos. Sin embargo, como estos archivos no existen en el directorio, la construcción falla con los siguientes mensajes de error:clang: error: no such file or directory: 'test.o'
clang: error: no such file or directory: 'test.dummyextension'
clang: error: no input files
make: *** [test] Error 1
Este comportamiento no está relacionado con reglas implícitas, ya que no hay reglas implícitas que coincidan con el patrón
%: %
en este Makefile. En cambio, está relacionado con la forma en que make maneja los objetivos ficticios.En este Makefile, el objetivo
test
es un objetivo ficticio porque no corresponde a un archivo real en el directorio. Cuando ejecutasmake test
, make verifica si el objetivotest
está actualizado en relación con sus requisitos previos. Sin embargo, como el objetivotest
no tiene otros requisitos además detest.dummyextension
, make asume que necesita construirtest
compilandotest.o
ytest.dummyextension
.Para solucionar este problema, puedes modificar el objetivo
test
para que sea explícitamente un objetivo ficticio agregando el objetivo especial.PHONY
:Con este Makefile modificado, al ejecutar
make test
debería producir la siguiente salida:Este Makefile modificado declara explícitamente
test
como un objetivo ficticio utilizando.PHONY
, por lo que make no intentará construirlo como si fuera un archivo real. En su lugar, make simplemente ejecutará el comandoecho
en la receta del objetivotest
.