¿Cómo funciona en realidad la reconstrucción forzada en mi archivo Makefile?
Como traductor de documentos de IT, tengo los siguientes 4 archivos en un directorio; “ls -F”:
lang-makefile
iterator
Makefile
test*
test.cpp
Donde todos los archivos deberían ser autoexplicativos, pero tengo la sensación de que “iterator” puede sonar un poco extraño, así que para dejar todo claro, quiero almacenar / mostrar la información sobre cuántas veces he recompilado el código fuente “test.cpp”.
Aquí me gustaría preguntar amablemente ¿CÓMO funciona realmente la obligación de reconstruir / recomilar? No soy un experto en Makefiles, así que eso lo resume.
Aquí está mi Makefile real sin cambios en absoluto:
CXX := g++-10
CXXFLAGS := -O2 -std=c++20 -Wall -Wextra -Werror -Wpedantic -pedantic-errors
APP_NAME := test
SRC_FILE := $(APP_NAME).cpp
El siguiente código funciona, pero no sé cómo 🙁
$(APP_NAME): .force_rebuild
.PHONY: .force_rebuild
$(APP_NAME): $(SRC_FILE)
Borrar rápidamente el búfer del terminal
@clear
Aumentar el número de prueba
@expr $$(cat iterator) + 1 > iterator
Imprimir la descripción del número de prueba
@printf ‘%s’ “Prueba nº: ”
Establecer color cian brillante para el número
@tput bold; tput setaf 6
Imprimir el número de prueba
@cat iterator
Restablecer el color normal del terminal
@tput sgr0
Compilar (siempre forzar la reconstrucción)
@$(CXX) $(CXXFLAGS) $(SRC_FILE) -o $(APP_NAME)
Ejecutar mi aplicación de prueba
@./$(APP_NAME)
Para ser completos, trabajo en Linux Mint 20.2 Cinnamon con Bash como shell y VS Code como editor de texto utilizando GNU Make 4.2.1.
Nota secundaria: se ve extraño y menos legible cuando no hay resaltado de sintaxis, por eso adjunto una captura de pantalla también.
davy.ai
El objetivo
force_rebuild
es un requisito previo para el objetivotest
, lo que significa que cada vez que se activaforce_rebuild
,test
se reconstruirá automáticamente, incluso si los archivos de origen no han cambiado.En este caso,
force_rebuild
es un objetivo ficticio, lo que significa que no representa un archivo real, sino una regla que siempre debe ejecutarse. La regla paraforce_rebuild
está vacía, lo que significa que no hace nada, pero como se requiere previamente paratest
, asegura quetest
siempre se reconstruya.La razón por la que funciona es porque
make
verifica las marcas de tiempo de modificación de los archivos involucrados en un objetivo antes de decidir si reconstruirlo o no. Al hacer queforce_rebuild
siempre esté desactualizado (ya que no corresponde a un archivo real),make
se ve obligado a reconstruir siempretest
, incluso si su archivo de origen no ha cambiado.La forma de lograr esto es mediante el uso del comando
touch
para actualizar la marca de tiempo de modificación deforce_rebuild
. Comotouch
crea un archivo si no existe, esto también asegura queforce_rebuild
siempre esté actualizado antes de usarse como requisito previo paratest
.