que para nada make hace entre directorios diferencia con comando makefile

makefile - para - ¿Por qué no se activan las reglas de patrón implícitas de.PHONY?



makefile linux c (3)

De esta sección del manual de make:

La búsqueda de reglas implícitas (ver Reglas implícitas) se omite para los objetivos .PHONY. Esta es la razón por la que declarar un destino como .PHONY es bueno para el rendimiento, incluso si no está preocupado por el archivo real existente.

Por lo tanto, sus objetivos implícitos nunca se buscan porque son falsos.

Puedes lograr lo que estás tratando de hacer de otra manera. Prueba esto:

SUBDIRS := all clean .PHONY: $(SUBDIRS) $(SUBDIRS): echo $(MAKE) -C src $@ echo $(MAKE) -C dict $@

Tengo el siguiente makefile recursivo:

.PHONY: all clean %.subdir: $(MAKE) -C src $* $(MAKE) -C dict $* all: all.subdir clean: clean.subdir

y funciona bien:

$ make all make -C src all make[1]: Entering directory `/or-1.3.6-fix/src'' make[1]: Nothing to be done for `all''. make[1]: Leaving directory `/or-1.3.6-fix/src'' make -C dict all make[1]: Entering directory `/or-1.3.6-fix/dict'' make[1]: Nothing to be done for `all''. make[1]: Leaving directory `/or-1.3.6-fix/dict''

Pero sería más lógico definir las reglas de %.subdir como falsas:

.PHONY: all clean all.subdir clean.subdir

Y ahora haz que deje de funcionar como yo quiero:

$ make all make: Nothing to be done for `all''. $ make -d all ... Updating goal targets.... Considering target file `all''. File `all'' does not exist. Considering target file `all.subdir''. File `all.subdir'' does not exist. Finished prerequisites of target file `all.subdir''. Must remake target `all.subdir''. Successfully remade target file `all.subdir''. Finished prerequisites of target file `all''. Must remake target `all''. Successfully remade target file `all''. make: Nothing to be done for `all''.

¿Alguien puede explicarme por qué (o, mejor aún, señalarme que haga documentación)?


Que GNU haga que los objetivos requeridos declarados como .PHONY para ser explícitos ya se ha indicado en las otras respuestas, lo que también proporcionó algún remedio a esto.

En esta respuesta adicional, me gustaría agregar un alterativo que, al probar, combina un comportamiento "falso", es decir, que los objetivos se activan cada vez, sin importar si existen archivos con el mismo nombre (se ignoran). La alternativa es la siguiente:

.PHONY: phony_explicit phony_explicit: %.subdir: phony_explicit $(MAKE) -C src $* $(MAKE) -C dict $*

Funciona bajo la premisa de que mientras que solo los objetivos explícitos se pueden establecer como .PHONY, lo que dependa de un objetivo falso explícito es, en sí mismo, heredar muchos atributos falsos (que yo sepa, todos). Un objetivo implícito, es decir, un patrón de coincidencia, como el %.subdir anterior, es como si se agregara a .PHONY (lo cual es imposible porque no es explícito), pero se vuelve falso a través de su prerrequisito phony_explicit .

Se reduce a que cada regla, también implícita a través de la coincidencia de patrones, que tiene en sus requisitos un objetivo falso explícito (es decir, un objetivo que se agrega a la .PHONY ) se ejecuta a través de esta dependencia también en un estilo falso (cada vez, incondicionalmente del sistema de archivos que tiene erróneamente un archivo con un nombre coincidente).

De hecho, la documentación de GNU make menciona el target FORCE , que en algunas versiones de GNU que no ofrecen un objetivo .PHONY emula en parte el comportamiento de .PHONY . La alternativa que se presenta aquí utiliza este enfoque de objetivo de FUERZA, sin embargo, debido a que se utiliza GNU make, también establece el objetivo de FORCE como .PHONY evitando posibles conflictos con archivos realmente existentes del mismo nombre.

Con esta solución incluso un

touch clean.subir; make clean.subdir

dará la invocación deseada de

make -C src clean make -C dist clean

Lo que podría ser un punto pro potencial de esta alternativa es que no necesita una declaración explícita de clean.subdir y all.subdir , pero en realidad está usando la %.subdir patrones implícita %.subdir .


Tienes razón, tendría más sentido definir las reglas de subdirección como PHONY. Pero Make no tiene en cuenta las reglas implícitas para los objetivos de PHONY, por lo que tendrá que volver a escribir esa regla. Sugiero lo siguiente:

SUBDIR_TARGETS = all.subdir clean.subdir .PHONY: all clean $(SUBDIR_TARGETS) $(SUBDIR_TARGETS): %.subdir: $(MAKE) -C src $* $(MAKE) -C dict $* all: all.subdir clean: clean.subdir