primer make instalar entre ejecutar diferencia create como comando archivos c++ linux makefile

c++ - instalar - makefile linux c



¿Cómo fuerza un archivo MAKE para reconstruir un objetivo (14)

¡Según Recursive Miller Make Considered Harmful , debe evitar llamar $(MAKE) ! En el caso que muestre, es inofensivo, porque esto no es realmente un archivo MAKE, solo un script de contenedor, que bien podría haber sido escrito en Shell. Pero dices que continúas así a niveles de recursión más profundos, por lo que probablemente hayas encontrado los problemas que se muestran en ese ensayo revelador.

Por supuesto, con GNU, es engorroso 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 por nivel de directorio, pero todos se unen para obtener una vista completa de su proyecto.

Pero los archivos make heredados se escriben recursivamente. Así que hay una solución alternativa en la que $(MAKE) no hace más que canalizar las subpeticiones de vuelta al proceso principal de makepp. Solo si haces cosas redundantes o, lo que es peor, contradictorias entre tus submake, debes solicitar --traditional-recursive-make (lo que por supuesto rompe esta ventaja de makepp). No conozco tus otros archivos makefiles, pero si están escritos de manera clara, con makepp las reconstrucciones necesarias deberían suceder automáticamente, sin la necesidad de ningún truco sugerido aquí por otros.

Tengo un archivo MAKE que construye y luego llama a otro archivo MAKE. Como este archivo make llama a más makefiles 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


Alguien más sugirió .PHONY, que definitivamente es correcto. .PHONY se debe usar para cualquier regla para la que una comparación de fecha entre la entrada y la salida no sea válida. Como no tiene ningún objetivo de output: input formulario output: input ¡debe usar .PHONY para TODOS ellos!

Dicho todo esto, probablemente debas definir algunas variables en la parte superior de tu archivo MAKE para los distintos nombres de archivo, y definir reglas de creación real que tengan tanto secciones de entrada como de salida para que puedas usar los beneficios de make, es decir, que solo compilas cosas que son necesarias para copmile!

Editar: ejemplo agregado. No probado, pero así es como lo haces .PHONY

.PHONY: clean clean: $(clean)


De hecho, depende de lo que 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 quiere 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í.


El cambio de -B a hacer, cuya forma larga es - --always-make , le dice a make ignorar las marcas de tiempo y hacer los objetivos especificados. Esto puede frustrar el propósito de usar make, pero puede ser lo que necesita.


En mi sistema Linux (Centos 6.2), hay una diferencia significativa entre declarar el destino .PHONY y crear una dependencia falsa en FORCE, cuando la regla realmente crea un archivo que coincide con el objetivo. Cuando el archivo debe regenerarse cada vez, se requiere tanto la FUERZA de dependencia falsa en el archivo como .PHONY para la dependencia falsa.

incorrecto:

date > $@

derecho:

FORCE date > $@ FORCE: .PHONY: FORCE


Esta técnica simple permitirá que el archivo MAKE funcione normalmente cuando no se desea forzarlo. Crea un nuevo objetivo llamado force al final de tu archivo MAKE . El objetivo de la fuerza tocará un archivo del que depende su objetivo predeterminado. En el siguiente ejemplo, he agregado touch myprogram.cpp . También agregué una llamada recursiva para hacer . Esto hará que el objetivo predeterminado se haga cada vez que se escribe fuerza .

yourProgram: yourProgram.cpp g++ -o yourProgram yourProgram.cpp force: touch yourProgram.cpp make


Intenté esto y funcionó para mí

agregue estas líneas a Makefile

clean: rm *.o output new: clean $(MAKE) #use variable $(MAKE) instead of make to get recursive make calls

guardar y ahora llamar

make new

y volverá a compilar todo

¿Que pasó?

''nuevas'' llamadas limpias ''limpias'' do ''rm'' que elimina todos los archivos de objetos que tienen la extensión de ''.o'' ''nuevas'' llamadas ''make''. ''make'' ve que no hay archivos ''.o'', por lo que sigue y crea todo el ''.o'' de nuevo. entonces el enlazador vincula todo el archivo .o int una ejecución ejecutable

Buena suerte


Podrías declarar que uno o más de tus objetivos son phony .

Un objetivo falso es aquel que no es realmente el nombre de un archivo; más bien es solo un nombre para que se ejecute una receta cuando se realiza una solicitud explícita. Hay dos razones para usar un objetivo falso: evitar un conflicto con un archivo del mismo nombre y mejorar el rendimiento.

...

Un objetivo falso no debe ser un requisito previo de un archivo de destino real; si lo es, su receta se ejecutará cada vez que make vaya a actualizar ese archivo. Siempre que un objetivo falso nunca sea un requisito previo para un objetivo real, la receta del objetivo falso se ejecutará solo cuando el objetivo falso sea un objetivo específico.


Si no necesita conservar ninguno de los resultados que ya compiló satisfactoriamente

nmake /A

reconstruye todo


Si recuerdo correctamente, ''make'' usa marcas de tiempo (tiempo 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, usando el comando ''toque''. Podría intentar invocar ''toque'' en su archivo MAKE para actualizar la marca de tiempo de uno de los objetivos (tal vez uno de esos sub-makefiles), lo que podría obligar a Make a ejecutar ese comando.


Un truco que solía documentarse en un manual de Sun para make es utilizar un objetivo (no existente) ''.FORCE''. Puede hacer esto creando un archivo, force.mk, que contenga:

.FORCE: $(FORCE_DEPS): .FORCE

Luego, suponiendo que su archivo make existente se llama makefile , podría ejecutar:

make FORCE_DEPS=release -f force.mk -f makefile release

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 explicó.

También vale la pena considerar por qué make considera que la versión está actualizada. Esto podría deberse a que tiene un comando de touch release entre los comandos ejecutados; podría ser porque hay un archivo o directorio llamado ''release'' que existe y no tiene dependencias, por lo que está actualizado. Luego está la razón real ...


Ya se mencionó, pero pensé que podría agregar al uso del touch

Si touch todos los archivos fuente que se compilarán, el comando touch cambia las marcas de tiempo de un archivo a la hora del sistema en que se ejecutó el comando touch .

El timstamp del archivo fuente es lo que make usos "sepan" que un archivo ha cambiado, y necesita ser compilado nuevamente

Por ejemplo: si el proyecto era un proyecto de C ++, entonces touch *.cpp , luego ejecute make nuevamente, y make debería recompilar todo el proyecto.



make clean borra todos los archivos de objetos ya compilados.