¿Cuál es la diferencia entre el requisito previo del archivo MAKE de porcentaje y asterisco (estrella)?

¿Cuál es la diferencia entre el requisito previo del archivo MAKE de porcentaje y asterisco (estrella)?

Estoy tratando de entender por qué algunos Makefiles tienen requisitos previos %.txty otros tienen *.txt.

He creado este diseño de carpeta.

$ tree .
.
├── hi1.txt
├── hi2.txt
├── hi3.txt
└── Makefile

Primero, probé esto.

foo.txt: *.txt
    echo $^

Y hace lo que espero.

$ make
echo hi1.txt hi2.txt hi3.txt
hi1.txt hi2.txt hi3.txt

Pero luego he visto que algunos Makefiles se utilizan %.txtcomo comodín. Entonces lo intenté a continuación.

foo.txt: %.txt
    echo $^

Sin embargo, esto produce un error.

$ make
make: *** No rule to make target '%.txt', needed by 'foo.txt'.  Stop.

¿Alguien puede explicar por qué sucede esto?

GNU hace 4.3

Respuesta1

En make, el signo de porcentaje se utiliza para la coincidencia de patrones y requiere uno en el objetivo y (al menos) uno en los requisitos previos:

%.o: %.c
        $(CC) $(CFLAGS) -c -o $@ $<

Con este archivo MAKE, especificamos que para construir algo cuyo nombre de archivo termine en .o, necesita tener un archivo que tenga el mismo prefijo, pero que luego termine en .cen lugar de.o

Para poder construir esas reglas, obviamente es necesario poder hacer referencia tanto al objetivo como a los requisitos previos; aquí es donde entran en juego las variables $@y . significa "el objetivo de esta regla" y significa "el primer requisito previo enumerado de esta regla". Si necesita construir un comando que use$<$@$<todorequisitos previos (por ejemplo, para vincular un ejecutable), entonces puede usar la variable $^:

%: %.o lib.o
        $(CC) $(LDFLAGS) -o $@ $^

Si combina los dos fragmentos de archivos MAKE de ejemplo anteriores en un archivo MAKE y tiene un archivo 'lib.c' con algún código común que desea usar en varios programas C en ese mismo directorio, entonces puede agregar cualquier .carchivo aleatorio. , digamos foo.c, y compílelo en un programa fooque también enlace el código en lib.c, sin requerir ningún cambio en su archivo MAKE.

Tenga en cuenta que también es posible tener patrones con el mismo objetivo, siempre que los requisitos previos sean diferentes; por ejemplo, lo siguiente funcionará:

%.o: %.c
        $(CC).....
%.o: %.cpp
        $(CXX).....

es decir, funcionará como se espera siempre y cuando no tenga ningún archivo fuente de C++ en este directorio que tenga el mismo nombre (sin extensión) que un archivo fuente de C. Si ese fuera el caso, la versión C++ se ignorará y en su lugar se compilará la fuente C (porque la regla C aparece primero en el archivo MAKE)

Para obtener más información, consulte elsección relevanteen el manual de creación de GNU.

información relacionada