Tengo un archivo MAKE que se construye y luego llama a otro archivo MAKE. Dado que este archivo MAKE llama a más archivos MAKE que hacen el trabajo, realmente no cambia. Por lo tanto, sigue pensando que el proyecto está construido y actualizado.
dnetdev11 ~ # make
make: `release' is up to date.
¿Cómo fuerzo el archivo MAKE para reconstruir el objetivo?
clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean
build = svn up ~/xxx \
$(clean) \
~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace \
$(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1) \
release:
$(build )
debug:
$(build DEBUG=1)
clean:
$(clean)
install:
cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib
Nota: nombres eliminados para proteger a los inocentes
Edición: versión fija final:
clean = $(MAKE) -f xxx_compile.workspace.mak clean;
build = svn up; \
$(clean) \
./cbp2mak/cbp2mak -C . xxx_compile.workspace; \
$(MAKE) -f xxx_compile.workspace.mak $(1); \
.PHONY: release debug clean install
release:
$(call build,)
debug:
$(call build,DEBUG=1)
clean:
$(clean)
install:
cp ./source/xxx_utillity/release/xxx_util /usr/bin
cp ./dlls/Release/xxxcore.so /usr/lib
.PHONY
no fue su único problema, y realmente no se supone que edite la solución en la pregunta, o al menos ya no.)Respuestas:
Podría declarar que uno o más de sus objetivos son falsos .
fuente
:
, no solo al resultado final que desea crear (por ejemplo, su archivo binario). En la pregunta,release
,debug
,clean
, yinstall
son los blancos no tomamos,xxx_util
oxxxcore.so
o cualquier otra cosa.El
-B
cambio para hacer, cuya forma larga es--always-make
, le dicemake
que no tenga en cuenta las marcas de tiempo y haga los objetivos especificados. Esto puede anular el propósito de usar make, pero puede ser lo que necesita.fuente
Un truco que solía estar documentado en un manual de Sun
make
es utilizar un objetivo (inexistente) '.FORCE'. Puede hacer esto creando un archivo, force.mk, que contenga:Luego, suponiendo que se llame a su archivo MAKE existente
makefile
, puede ejecutar:Como
.FORCE
no existe, todo lo que dependa de él estará desactualizado y reconstruido.Todo esto funcionará con cualquier versión de
make
; en Linux, tiene GNU Make y, por lo tanto, puede usar el objetivo .PHONY como se discutió.También vale la pena considerar por qué
make
considera que el lanzamiento está actualizado. Esto podría deberse a que tiene untouch release
comando entre los comandos ejecutados; podría deberse a que existe un archivo o directorio llamado 'versión' que existe y no tiene dependencias, por lo que está actualizado. Luego está la razón real ...fuente
Alguien más sugirió .PHONY, que es definitivamente correcto. .PHONY debe usarse para cualquier regla para la cual una comparación de fecha entre la entrada y la salida no sea válida. ¡Ya que no tienes ningún objetivo de la forma
output: input
, debes usar .PHONY para TODOS!Dicho todo esto, probablemente debería definir algunas variables en la parte superior de su archivo MAKE para los diversos nombres de archivo, y definir reglas de creación reales que tengan secciones de entrada y salida para que pueda usar los beneficios de la creación, es decir, que solo compilará ¡Cosas que son necesarias para copilar!
Editar: ejemplo agregado. Sin probar, pero así es como lo haces .PHONY
fuente
.PHONY
objetivo no importa. Puede estar en cualquier parte delMakefile
.Si recuerdo correctamente, 'make' usa marcas de tiempo (hora de modificación del archivo) para determinar si un objetivo está actualizado o no. Una forma común de forzar una reconstrucción es actualizar esa marca de tiempo, utilizando el comando 'táctil'. Puede intentar invocar 'toque' en su archivo MAKE para actualizar la marca de tiempo de uno de los objetivos (tal vez uno de esos sub-archivos MAKE), lo que podría obligar a Make a ejecutar ese comando.
fuente
Esta técnica simple permitirá que el archivo MAKE funcione normalmente cuando no se desee forzar. Crea un nuevo objetivo llamado fuerza al final de tu archivo MAKE . El objetivo forzado tocará un archivo del que depende su objetivo predeterminado. En el ejemplo a continuación, he agregado touch myprogram.cpp . También agregué una llamada recursiva para hacer . Esto hará que el objetivo predeterminado se haga cada vez que escriba forzar .
fuente
make
dentro de un Makefile. Usar en su$(MAKE)
lugar.Intenté esto y funcionó para mí
agregue estas líneas a Makefile
guardar y ahora llamar
y recompilará todo de nuevo
¿Que pasó?
1) 'nuevas' llamadas limpias. 'clean' do 'rm' que elimina todos los archivos de objetos que tienen la extensión de '.o'.
2) 'nuevas' llamadas 'make'. 'make' ve que no hay archivos '.o', por lo que crea todos los '.o' nuevamente. entonces el enlazador enlaza todo el archivo .o en una salida ejecutable
Buena suerte
fuente
new
mejor uso$(MAKE)
quemake
De acuerdo con el Recursivo de Miller que se considera perjudicial, ¡debes evitar llamar
$(MAKE)
! En el caso que muestres, es inofensivo, porque este no es realmente un archivo MAKE, solo un script de envoltura, que bien podría haber sido escrito en Shell. Pero usted dice que continúa así en niveles de recursión más profundos, por lo que probablemente haya encontrado los problemas que se muestran en ese ensayo revelador.Por supuesto, con GNU es difícil evitarlo. Y a pesar de que son conscientes de este problema, es su forma documentada de hacer las cosas.
OTOH, makepp fue creado como una solución para este problema. Puede escribir sus archivos MAKE en un nivel por directorio, pero todos se unen en una vista completa de su proyecto.
Pero los makefiles heredados se escriben de forma recursiva. Entonces, hay una solución alternativa en la
$(MAKE)
que no hace nada más que canalizar las subrequests al proceso principal de makepp. Solo si hace cosas redundantes o, lo que es peor, contradictorias entre sus submakes, debe solicitar--traditional-recursive-make
(lo que, por supuesto, rompe esta ventaja de makepp). No conozco tus otros archivos MAKE, pero si están escritos de manera limpia, con makepp, las reconstrucciones necesarias deberían ocurrir automáticamente, sin la necesidad de ningún truco sugerido aquí por otros.fuente
:
), siempre se reconstruirá cuando sea necesario.Si no necesita conservar ninguna de las salidas que ya compiló con éxito
reconstruye todo
fuente
De hecho, depende de cuál sea el objetivo. Si es un objetivo falso (es decir, el objetivo NO está relacionado con un archivo), debe declararlo como .PHONY.
Sin embargo, si el objetivo no es un objetivo falso pero solo desea reconstruirlo por alguna razón (un ejemplo es cuando usa la macro de preprocesamiento __TIME__), debe usar el esquema FORCE descrito en las respuestas aquí.
fuente
http://www.gnu.org/software/make/manual/html_node/Force-Targets.html#Force-Targets
fuente
Ya se mencionó, pero pensé que podría agregar a usar
touch
Si
touch
compila todos los archivos de origen, eltouch
comando cambia las marcas de tiempo de un archivo a la hora del sistematouch
se ejecutó comando.La marca de tiempo del archivo fuente es lo que se
make
utiliza para "saber" que un archivo ha cambiado y necesita ser compilado nuevamentePor ejemplo: si el proyecto era un proyecto de C ++, entonces hazlo
touch *.cpp
, luegomake
vuelve a ejecutarlo y make debería recompilar todo el proyecto.fuente
Como señaló abernier, hay una solución recomendada en el manual de creación de GNU, que utiliza un objetivo 'falso' para forzar la reconstrucción de un objetivo:
Esto se ejecutará limpio, independientemente de cualquier otra dependencia.
Agregué el punto y coma a la solución del manual, de lo contrario se requiere una línea vacía.
fuente
En mi sistema Linux (Centos 6.2), hay una diferencia significativa entre declarar el objetivo .PHONY y crear una dependencia falsa en FORCE, cuando la regla realmente crea un archivo que coincide con el objetivo. Cuando el archivo se debe volver a generar cada vez, se requiere tanto la FUERZA de dependencia falsa en el archivo como .PHONY para la dependencia falsa.
incorrecto:
Derecha:
fuente
make clean
elimina todos los archivos de objetos ya compilados.fuente