the make howto create makefile gnu-make

makefile - howto - Enumere las metas/objetivos en GNU make que contienen variables en su definición



makefile structure (16)

Claro, pero ¿cuándo quieres que los escupe?

Para informar el nombre del objetivo cuando ejecuta la regla, ponga una línea en la regla:

foo$(VAR): $(PREREQS) @echo now making the foo target: $@ do_other_stuff...

Para escupirlos a todos a la vez, puedes hacer un objetivo PHONY por separado:

.PHONY: show_vars show_vars: @echo foo$(VAR) @echo bar$(PARAM) blah$(FLAG) # and so on

Y esto puede convertirse en un requisito previo de su objetivo predeterminado:

all: show_vars ...

EDITAR:
Desea una forma de mostrar todos los objetivos posibles de un archivo MAKE arbitrario, lo que supongo que significa de forma no intrusiva. Bien...

Para hacerlo exactamente, y ser capaz de lidiar con archivos make sofisticados, por ejemplo, involucrando reglas construidas por declaraciones eval , tendría que escribir algo cerca de un emulador Make. Poco práctico.

Para ver los objetivos de las reglas simples, puede escribir un archivo MAKE que actuaría como un escáner de archivos MAKE, operando en un archivo MAKE arbitrario:

  1. Obtenga todos los nombres de destino del archivo MAKE utilizando sed.
  2. `include` el archivo MAKE para usarlo para expandir variables.
  3. Use `show_%:; echo $$ * `para imprimir todos los objetivos

Este sería un trabajo impresionante. ¿Estás seguro de que el objetivo vale la pena el esfuerzo?

Tengo un archivo bastante grande que crea una serie de objetivos sobre la marcha al computar los nombres de las variables. (por ejemplo, foo $ (VAR): $ (PREREQS)). ¿Hay alguna forma de que gnu make pueda convencerse de escupir una lista de objetivos después de haber expandido estas variables?

Me gustaría poder obtener los objetivos para un archivo make aribitrary. Estoy tratando de escribir una función de finalización para mi caparazón.


Editar: FYI el repositorio Debian Bash Git de finalización en otra respuesta ahora incorpora una versión mejorada de este script adaptado a los casos de uso de finalización de bash.

#!/bin/bash SCRIPT='' /^# Make data base/,/^# Files/d # skip until files section /^# Not a target/,+1 d # following target isnt /^/.PHONY:/ d # special target /^/.SUFFIXES:/ d # special target /^/.DEFAULT:/ d # special target /^/.PRECIOUS:/ d # special target /^/.INTERMEDIATE:/ d # special target /^/.SECONDARY:/ d # special target /^/.SECONDEXPANSION/ d # special target /^/.DELETE_ON_ERROR:/ d # special target /^/.IGNORE:/ d # special target /^/.LOW_RESOLUTION_TIME:/ d # special target /^/.SILENT:/ d # special target /^/.EXPORT_ALL_VARIABLES:/ d # special target /^/.NOTPARALLEL:/ d # special target /^/.ONESHELL:/ d # special target /^/.POSIX:/ d # special target /^/.NOEXPORT:/ d # special target /^/.MAKE:/ d # special target # The stuff above here describes lines that are not # explicit targets or not targets other than special ones # The stuff below here decides whether an explicit target # should be output. /^[^#/t:=%]+:([^=]|$)/ { # found target block h # hold target d # delete line } /^# File is an intermediate prerequisite/ { # nope s/^.*$//;x # unhold target d # delete line } /^([^#]|$)/ { # end of target block s/^.*$//;x # unhold target s/:.*$//p # write current target d # hide any bugs } '' make -npq .DEFAULT 2>/dev/null | sed -n -r "$SCRIPT" / | sort | uniq

Este es un script mucho más completo que el script Debian Bash, ya que proporciona resultados para las reglas generadas, que es lo que pide la pregunta y la respuesta más alta (debian bash completion script en debian git server) no va lo suficientemente lejos.

Este no es el script original al que me he vinculado, pero es mucho más simple y es un poco más rápido.


Encontré esta solución en otro hilo:

sh -c "cat Makefile | egrep /"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$/""

También puede agregarlo a su Makefile :

list: sh -c "cat Makefile | egrep /"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$//""

Y ejecuta make list .


Este es el código de alias basado en la solución de Todd Hodes

alias mtargets=''make -qp | awk -F":" "/^[a-zA-Z0-9][^$#///t=]*:([^=]|$)/ {split(/$1,A,/ /);for(i in A)print A[i]}"''


Esto dará un buen resultado:

make -pn | perl -F: -ane ''print "$F[0]/n" if /^/w+/s*:/'' | sort


Estoy trabajando en Solaris 10 anda y turbo C shell. La solución dada no funciona para mi proyecto makefile. incluso después de alterar la línea de comando anterior a tcsh sintaxis. Sin embargo, descubrí que puede obtener una solución fácil usando

remake --tasks | grep -v "clean some static output or just grep tabs on start of line" | awk ´{print $1}´

versión de remake:

remake --version

es

GNU Make 3.82+dbg0.8 Built for sparc-sun-sparc2-9

y algunos otros datos de versión sin importancia


Fui en busca de la misma pregunta y se me ocurrió este giro:

make -pn | sed -rn ''/^[^# /t/.%].*:/p''

Esto elimina todas las líneas de comentarios, reglas de patrones (líneas que comienzan con pestañas), todos los intrínsecos (por ejemplo, patrones .co y %.o: %.c ).



No estoy seguro de si esto es solo un gnu make, pero esto funciona bien:

make help


Solución Ruby:

`make -qp`.split("/n").select{|l| l =~ /^/w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'''')}


Supongo que llego un poco tarde a esta fiesta, pero si estás buscando un comando específico, podrías intentarlo

make -qp | grep -v ''^# '' | grep -v ''^[[:space:]]'' | grep --only-matching ''^.*:''

Esto funciona principalmente, aunque aún podría incluir algunas cosas que no son de destino, como una directiva vpath . Si no depende de las reglas make -qpR , puede usar make -qpR como el primer comando en la canalización.


Varios respondedores han sugerido usar make -pn , que imprimirá la base de datos de reglas pero no ejecutará nada, más o menos. El problema con este enfoque es que -n todavía invoca todas las marcas recursivas, y todavía hace mucho más trabajo de lo necesario, ya que imprime cada comando que habría invocado en una compilación normal. Una solución más eficiente sería crear un makefile trivial, dummy.mk, con estos contenidos:

__all_targets__: ; #no-op

Ahora invoque make como make -p -f Makefile -f dummy.mk __all_targets__ . En cualquier compilación sustancial, la diferencia en la cantidad de salida generada por make es significativa. Por ejemplo:

$ gmake -pn | wc 138985 2632330 69612711 $ gmake -f Makefile -f /tmp/dummy.mk -pn __all_targets__ | wc 21673 93437 878985

El tiempo de ejecución también fue espectacularmente mejor: 2.063 para la primera versión, 0.059 para la segunda.



¿Se puede analizar el resultado de make -pn (es decir, make --print-data-base --dry-run )? Imprime todas las variables, reglas, reglas implícitas y qué comandos se ejecutarán con gran detalle.


grep ^[a-z].*/:$ Makefile | sed s,:,,g


make -qp | awk -F'':'' ''/^[a-zA-Z0-9][^$#///t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}''

Tomado de la finalización de make arg, que funciona como un amuleto.