Paso previo a la construcción en makefile
prebuild (5)
¿Cómo puedo ejecutar un script, que debe ejecutarse antes de todos los demás comandos de makefile? Y será bueno (pero no obligatorio) que el script no se ejecute si no hay nada que construir.
He buscado SO y Google, pero no puedo encontrar nada.
Tengo esta solución:
# myscript.bat output is empty
CHEAT_ARGUMENT = (shell myscript.bat)
CFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)
AFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)
Pero es muy feo. ¿Hay otra forma de ejecutar " paso previo a la compilación " en makefile ?
Dependiendo de la versión de su versión, algo como lo siguiente debería al menos evitar ejecutar docenas de veces si se evalúan CFLAGS y AFLAGS docenas de veces:
CHEAT_ARG := $(shell myscript)
Tenga en cuenta los dos puntos.
Esto funciona exactamente una vez. Nunca más de una vez, pero también nunca menos de una vez. Elija sus propias compensaciones.
Gracias por las respuestas. ndim me ayudó mucho, asveikau . El archivo final es un ejecutable binario, así que ahora puedo usar algo como esto:
run-script:
myscript
$(AXF_FILE): run-script $(OBJ_DIRS) $(OBJ_FILES)
$(LINK) #......
Se ejecutará myscript una vez. El valor de {AXF_FILE} depende de myscript y debo ejecutarlo antes . Y en este caso myscript se ejecuta siempre, no solo cuando se necesita reconstruir. Después, La respuesta más simple vino a mi mente:
all: run-script $(AXF_FILE)
Eso es todo ;) (Por supuesto, se puede usar cualquier objetivo en lugar de "todos")
Editar: este método ejecuta el script después de que se calcule $ (AXF_FILE) . Entonces es posible obtener un valor incorrecto de AXF_FILE. Ahora solo la primera respuesta de ndim funciona como necesito.
Lo que usted está proponiendo parece un poco "desarmado". ¿Por qué no solo ejecuta el comando en cualquier destino de makefile al que necesites ir antes?
Ejemplo, si necesita ejecutarlo antes de vincular foo
:
foo: ${OBJS}
my-command-goes-here
${CC} -o $@ ${OBJS} ${LIBS}
Podría agregar un objetivo especial a su Makefile y hacer que todas sus reglas de construcción dependan de eso:
run-script:
myscript
.o.c: run-script
$(CC) $(CFLAGS) -o $@ $<
.o.S: run-script
$(AS) $(AFLAGS) -o $@ $<
Dependiendo de lo que realmente haga su script, ponerlo para que se ejecute una vez en una etapa antes de Makefile (configure stage en términos de autoconf) podría tener aún más sentido (y ser menos trabajo).
Propongo dos soluciones. Lo primero imita lo que genera NetBeans IDE:
CC=gcc
.PHONY: all clean
all: post-build
pre-build:
@echo PRE
post-build: main-build
@echo POST
main-build: pre-build
@$(MAKE) --no-print-directory target
target: $(OBJS)
$(CC) -o $@ $(OBJS)
clean:
rm -f $(OBJS) target
El segundo está inspirado en lo que Eclipse IDE genera:
CC=gcc
.PHONY: all clean
.SECONDARY: main-build
all: pre-build main-build
pre-build:
@echo PRE
post-build:
@echo POST
main-build: target
target: $(OBJS)
$(CC) -o $@ $(OBJS)
@$(MAKE) --no-print-directory post-build
clean:
rm -f $(OBJS) target
Tenga en cuenta que en la primera, las compilaciones previas y posteriores siempre se invocan independientemente de si se determina que la compilación principal está actualizada o no.
En el segundo, el paso posterior a la compilación no se ejecuta si el estado de la compilación principal está actualizado. Mientras que el paso de pre-compilación siempre se ejecuta en ambos.