es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo forzar a Make a reiniciar y recargar los makefiles generados?

La tarea a realizar es la siguiente: una herramienta externa llamada en una receta produce un archivo makefile que debe ser incluido inmediatamente por make. Luego, otra regla, utilizando los datos incluidos, genera más archivos de inclusión. Make debe reiniciar nuevamente y solo entonces procesar las reglas adicionales. Considere el siguiente ejemplo:

$(info ------- Reinicio $(MAKE_RESTARTS))

all:

include a
include b

a: p
    touch a

b: a
    touch b

Funciona de la siguiente manera:

        touch p
        make
        ------- Reinicio
        touch a
        touch b
        ------- Reinicio 1
        make: No hay nada por hacer para 'all'.

Mi problema es que la regla b necesita los datos incluidos de a, pero b se ejecuta ANTES de incluir la versión actualizada de a. Make debe reiniciarse antes de ejecutar b. ¿Cómo se puede lograr esto? Me gustaría ver lo siguiente:

        touch p
        make
        ------- Reinicio
        touch a
        ------- Reinicio 1
        touch b
        ------- Reinicio 2
        make: No hay nada por hacer para 'all'.

Es fácil detectar si a fue incluido o no, y la regla para b se puede ocultar cuando a no está incluido. Esto funciona para una compilación limpia, pero no cuando a ya existe en el disco desde una compilación anterior y se activa la regla porque p se actualizó. Solo make sabe si la regla a:p está actualizada, no es posible verificar eso con expresiones condicionales.

¿Hay alguna solución para esto?

Actualización: basado en el consejo de @MadScientist, lo hice funcionar de esta manera:

$(info ------- Reinicio $(MAKE_RESTARTS))

all:

include b
include a

a: p
    @echo regla A
    touch a
    $(eval upd=1)

b: a
    @echo regla B
    $(if $(upd),@echo b omitido,touch b)

Y la salida es la siguiente:

touch p
make   
------- Reinicio 
regla A
touch a
regla B
b omitido
------- Reinicio 1
regla B
touch b
------- Reinicio 2

¡Perfecto! Gracias chicos, Feliz Navidad a todos.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para lograr el comportamiento deseado, las reglas en el archivo makefile deben ser reorganizadas. Las declaraciones include para el makefile generado deben venir después de la regla all, y se debe añadir una nueva regla para regenerar el makefile incluido. De esta manera, el makefile generado será incluido con el contenido actualizado, permitiendo que la regla b use los datos de la regla a. Aquí tienes un ejemplo:

    $(info ------- Reiniciando $(MAKE_RESTARTS))
    
    all : b
    
    include a
    include b
    
    a : p
        touch a
    
    .PHONY : regenerate_makefile
    regenerate_makefile :
        # comando para regenerar el makefile aquí
        touch generated_makefile
    
    b : generated_makefile a
        touch b
    

    En este ejemplo, la regla all depende de b, que a su vez depende de generated_makefile y a. Si a aún no está incluido, será creado por la regla a : p. La regla generated_makefile está marcada como .PHONY, lo que significa que siempre se considerará desactualizada y se ejecutará cada vez que se ejecute b. Esto asegurará que el makefile incluido esté actualizado antes de ejecutar las reglas que dependen de él.

    Para regenerar la herramienta externa que genera el makefile, ejecuta make regenerate_makefile. Esto actualizará el makefile, y la próxima invocación de make utilizará el nuevo makefile con reglas actualizadas.

Comments are closed.