variable source make automatic makefile

source - ¿Qué significan los símbolos makefile $ @ y $<?



makefile source variable (5)

Desde Managing Projects with GNU Make, 3rd Edition (está bajo la licencia de documentación libre de GNU ):

Las variables automáticas se establecen por make después de que una regla coincida. Proporcionan acceso a los elementos de las listas de destino y requisitos previos para que no tenga que especificar explícitamente ningún nombre de archivo. Son muy útiles para evitar la duplicación de código, pero son fundamentales al definir reglas de patrón más generales.

Hay siete variables automáticas “básicas”:

  • $@ : El nombre de archivo que representa el objetivo.

  • $% : El elemento de nombre de archivo de una especificación de miembro de archivo.

  • $< : El nombre de archivo del primer requisito previo.

  • $? : Los nombres de todos los requisitos previos que son más nuevos que el objetivo, separados por espacios.

  • $^ : Los nombres de archivo de todos los requisitos previos, separados por espacios. Esta lista tiene nombres de archivos duplicados eliminados ya que para la mayoría de los usos, como compilar, copiar, etc., no se desean duplicados.

  • $+ : Similar a $^ , estos son los nombres de todos los requisitos previos separados por espacios, excepto que $+ incluye duplicados. Esta variable se creó para situaciones específicas, como argumentos a vinculadores donde los valores duplicados tienen un significado.

  • $* : La raíz del nombre de archivo de destino. Una raíz es típicamente un nombre de archivo sin su sufijo. Se desaconseja su uso fuera de las reglas de patrón.

Además, cada una de las variables anteriores tiene dos variantes para la compatibilidad con otras marcas. Una variante devuelve solo la parte del directorio del valor. Esto se indica agregando una “D” al símbolo, $(@D) , $(<D) , etc. La otra variante devuelve solo la parte del archivo del valor. Esto se indica agregando una “F” al símbolo, $(@F) , $(<F) , etc. Tenga en cuenta que estos nombres de variantes tienen más de un carácter y por eso deben ir entre paréntesis. GNU make proporciona una alternativa más legible con las funciones dir y notdir.

CC=g++ CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@

¿Qué hacen exactamente los $@ y $< ?


El Makefile construye el ejecutable hello si alguno de main.cpp , hello.cpp , factorial.cpp cambió. El Makefile más pequeño posible para lograr esa especificación podría haber sido:

hello: main.cpp hello.cpp factorial.cpp g++ -o hello main.cpp hello.cpp factorial.cpp

  • pro: muy fácil de leer
  • con: pesadilla de mantenimiento, duplicación de las dependencias de C ++
  • con: problema de eficiencia, recompilamos todo C ++ incluso si solo se cambió uno

Para mejorar lo anterior, solo compilamos los archivos C ++ que fueron editados. Luego, simplemente vinculamos los archivos de objetos resultantes.

OBJECTS=main.o hello.o factorial.o hello: $(OBJECTS) g++ -o hello $(OBJECTS) main.o: main.cpp g++ -c main.cpp hello.o: hello.cpp g++ -c hello.cpp factorial.o: factorial.cpp g++ -c factorial.cpp

  • Pro: Soluciona el problema de eficiencia
  • con: nueva pesadilla de mantenimiento, posible error tipográfico en las reglas de archivos de objetos

Para mejorar esto, podemos reemplazar todas las reglas de archivos de objetos con una sola regla .cpp.o :

OBJECTS=main.o hello.o factorial.o hello: $(OBJECTS) g++ -o hello $(OBJECTS) .cpp.o: g++ -c $< -o $@

  • pro: volver a tener un makefile corto, algo fácil de leer

Aquí, la regla .cpp.o define cómo construir anyfile.o desde anyfile.cpp .

  • $< coincide con la primera dependencia, en este caso, anyfile.cpp
  • $@ coincide con el objetivo, en este caso, anyfile.o .

Los otros cambios presentes en el Makefile son:

  • Facilitando el cambio de compiladores de g ++ a cualquier compilador de C ++.
  • Haciendo más fácil cambiar las opciones del compilador.
  • Haciendo más fácil cambiar las opciones del enlazador.
  • Haciendo más fácil cambiar los archivos fuente de C ++ y la salida.
  • Se agregó una regla predeterminada ''todos'' que actúa como una comprobación rápida para garantizar que todos los archivos de origen estén presentes antes de que se realice un intento de compilación de su aplicación.

Los $@ y $< se denominan variables automáticas. El $@ es la variable de salida. $< es la primera variable de entrada. Por ejemplo:

hello.o: hello.c hello.h gcc -c $< -o $@

Aquí, hello.o es el archivo de salida. Esto es lo que $@ expande. La primera dependencia es hello.c . Eso es a lo que $< expande.

La bandera -c genera el archivo .o ; Ver man gcc para una explicación más detallada. La -o especifica el archivo al que se va a enviar.

Para más detalles, puedes leer this .

Además, puedes consultar los manuales de GNU. Hay una manera de depurar su makefile para entenderlo mejor.

Esto dará salida a la base de datos makefile:

$make -p


Los $@ y $< son macros especiales.

Dónde:

$@ es el nombre de archivo del objetivo.

$< es el nombre de la primera dependencia.


$@ es el nombre del archivo que se genera, y $< el primer requisito previo (generalmente el archivo de origen). Puede encontrar una lista de todas estas variables especiales en el manual de GNU Make .

Por ejemplo, considere la siguiente declaración:

all: library.cpp main.cpp

En este caso:

  • $@ evalúa a all
  • $< evalúa a library.cpp
  • $^ evalúa a library.cpp main.cpp