uso reglas puntos punto para niños los exposicion enseñar ejercicios ejemplos como coma makefile gnu-make

niños - ¿Para qué son las reglas de dos puntos en un Makefile?



uso de los dos puntos (4)

Cada :: regla se procesa de forma independiente, por lo que puede ser más simple. Por ejemplo, la regla única:

libxxx.a : sub1.o sub2.o ar rv libxxx.a sub1.o ar rv libxxx.a sub2.o

Puede ser reemplazado por dos reglas más simples:

libxxx.a :: sub1.o ar rv libxxx.a sub1.o libxxx.a :: sub2.o ar rv libxxx.a sub2.o

Las utilidades como AutoMake tienen un tiempo más fácil para escupir muchas reglas simples que algunas complejas.

Se publicó una gran respuesta con más ejemplos, luego se eliminó y luego se encontró aquí:

https://web.archive.org/web/20180122002430/http://owen.sj.ca.us/~rk/howto/slides/make/slides/makecolon.html

Gracias a RK Owen por escribirlo, y a Edward Minnix por encontrarlo nuevamente.

La sección 4.13 del manual GNU Make describe las llamadas reglas de dos puntos:

Las reglas de dos puntos son reglas escritas con ''::'' en lugar de '':'' después de los nombres de destino. Se manejan de manera diferente a las reglas ordinarias cuando el mismo objetivo aparece en más de una regla.

Cuando aparece un objetivo en varias reglas, todas las reglas deben ser del mismo tipo: todas ordinarias o todas de dos puntos dobles. Si son de dos puntos, cada uno de ellos es independiente de los otros. Los comandos de cada regla de dos puntos dobles se ejecutan si el objetivo es anterior a los requisitos previos de esa regla. Si no hay requisitos previos para esa regla, sus comandos siempre se ejecutan (incluso si el objetivo ya existe). Esto puede resultar en ejecutar ninguna, ninguna o todas las reglas de dos puntos dobles.

Las reglas de dos puntos con el mismo objetivo son, de hecho, completamente separadas unas de otras. Cada regla de dos puntos dobles se procesa individualmente, al igual que las reglas con diferentes objetivos se procesan.

Las reglas de dos puntos para un objetivo se ejecutan en el orden en que aparecen en el archivo make. Sin embargo, los casos en que las reglas de dos puntos realmente tienen sentido son aquellos en los que el orden de ejecución de los comandos no importaría.

Las reglas de dos puntos son un tanto oscuras y no son muy útiles a menudo; proporcionan un mecanismo para los casos en que el método utilizado para actualizar un objetivo difiere según los archivos de requisitos previos que causaron la actualización, y estos casos son raros.

Cada regla de dos puntos dobles debe especificar comandos; si no lo hace, se utilizará una regla implícita si se aplica. Consulte la sección Uso de reglas implícitas.

Creo un poco el significado de cada oración de esta sección individualmente, pero todavía no me queda claro para qué sirven las reglas de los dos puntos. En cuanto a que es raro, todavía no he visto ningún proyecto de código abierto cuyo Makefile no haya comenzado

all::

Por lo tanto: ¿Cuál es el propósito de las reglas de dos puntos en Makefiles?


Hay 3 situaciones donde el doble colon es útil:

  1. Alternar entre las reglas de compilación basadas en qué requisito previo es más nuevo que el destino. El siguiente ejemplo está basado en el "Ejemplo 19-3. Reglas de dos puntos dobles" de http://books.gigatux.nl/mirror/cinanutshell/0596006977/cinanut-CHP-19-SECT-3.html

Ejemplo de archivo .c:

c@desk:~/test/circle$ cat circle.c #include <stdio.h> int main (void) { printf("Example./n"); return 0; }

Makefile utilizado:

c@desk:~/test/circle$ cat Makefile # A makefile for "circle" to demonstrate double-colon rules. CC = gcc RM = rm -f CFLAGS = -Wall -std=c99 DBGFLAGS = -ggdb -pg DEBUGFILE = ./debug SRC = circle.c circle :: $(SRC) $(CC) $(CFLAGS) -o $@ -lm $^ circle :: $(DEBUGFILE) $(CC) $(CFLAGS) $(DBGFLAGS) -o $@ -lm $(SRC) .PHONY : clean clean : $(RM) circle

Salir:

c@desk:~/test/circle$ make circle gcc -Wall -std=c99 -o circle -lm circle.c make: *** No rule to make target ''debug'', needed by ''circle''. Stop. c@desk:~/test/circle$ make circle gcc -Wall -std=c99 -o circle -lm circle.c gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c c@desk:~/test/circle$ vim circle.c c@desk:~/test/circle$ make circle gcc -Wall -std=c99 -o circle -lm circle.c c@desk:~/test/circle$ vim debug c@desk:~/test/circle$ make circle gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c

  1. Haz una regla de patrón terminal.

El siguiente ejemplo explica esta situación: el archivo a.config se obtiene de a.cfg, que a su vez se obtiene de a.cfg1 (a.cfg es el archivo intermedio).

c@desk:~/test/circle1$ ls a.cfg1 log.txt Makefile c@desk:~/test/circle1$ cat Makefile CP=/bin/cp %.config:: %.cfg @echo "$@ from $<" @$(CP) $< $@ %.cfg: %.cfg1 @echo "$@ from $<" @$(CP) $< $@ clean: -$(RM) *.config

Resultado (como la regla% .config es terminal, make inhibe la creación del archivo intermedio a.cfg de a.cfg1):

c@desk:~/test/circle1$ make a.conf make: *** No rule to make target ''a.conf''. Stop.

Sin los dos puntos dobles para el% .config, el resultado es:

c@desk:~/test/circle1$ make a.config a.cfg from a.cfg1 a.config from a.cfg rm a.cfg

  1. Haga una regla que se ejecute siempre (útil para reglas limpias). La regla no debe tener prerrequisitos!

c @ desk: ~ / test / circle3 $ cat Makefile

CP=/bin/cp a.config:: @echo "Always" >> $@ a.config:: @echo "Always!" >> $@ clean: -$(RM) *.config

Salir:

c@desk:~/test/circle3$ make a.config c@desk:~/test/circle3$ cat a.config Always Always! c@desk:~/test/circle3$ make a.config c@desk:~/test/circle3$ cat a.config Always Always! Always Always!


Son útiles para makefiles no recursivos y objetivos como clean . Es decir, un archivo .mk individual puede agregar sus propios comandos al objetivo clean ya definido en otro lugar.

Documentation da una respuesta:

Las reglas de dos puntos son un tanto oscuras y no son muy útiles a menudo; proporcionan un mecanismo para los casos en que el método utilizado para actualizar un objetivo difiere según los archivos de requisitos previos que causaron la actualización, y estos casos son raros.


Tal como dice la documentación, las reglas de dos puntos raramente son muy útiles. Son una forma agradable y pequeña de no nombrar los objetivos individuales de un objetivo falso compuesto (como todos: :), pero no es realmente necesario en este rol. Solo puedo dar un ejemplo artificial cuando sea necesario:

Supongamos que tiene un archivo de registro L que está concatenado a partir de varios otros archivos de registro L1, L2, ... Usted formula una serie de reglas de dos puntos dobles como:

L :: L1 cat $< >> $@ && rm $< L :: L2 cat $< >> $@ && rm $<

Hoy en día en GNU make, por supuesto, usaría $^ para este tipo de magia, pero aparece como una característica inspirada en la pestaña de características de GNU make.