He usado un poco de rastrillo (un programa de creación Ruby), y tiene una opción para obtener una lista de todos los objetivos disponibles, por ejemplo
> rake --tasks
rake db:charset # retrieve the charset for your data...
rake db:collation # retrieve the collation for your da...
rake db:create # Creates the databases defined in y...
rake db:drop # Drops the database for your curren...
...
pero parece que no hay opción para hacer esto en GNU make.
Aparentemente, el código está casi allí para ello, a partir de 2007: http://www.mail-archive.com/[email protected]/msg06434.html .
De todos modos, hice un pequeño truco para extraer los objetivos de un archivo MAKE, que puedes incluir en un archivo MAKE.
list:
@grep '^[^#[:space:]].*:' Makefile
Le dará una lista de los objetivos definidos. Es solo un comienzo: no filtra las dependencias, por ejemplo.
> make list
list:
copy:
run:
plot:
turnin:
alias makefile-targets='grep "^[^#[:space:]].*:" Makefile'
mayoría de las veces solo necesito examinar el archivo MAKE actual y la finalización de bash se expande mi aliasgrep : Makefile
:?Respuestas:
Este es un intento de mejorar el gran enfoque de @nobar de la siguiente manera:
sh -c
)-f <file>
@
para evitar que se repita antes de la ejecuciónCuriosamente, GNU
make
no tiene una función para enumerar solo los nombres de objetivos definidos en un archivo MAKE. La-p
opción produce resultados que incluyen todos los objetivos, pero los entierra en mucha otra información.Coloque la siguiente regla en un archivo MAKE para que GNU
make
implemente un objetivo llamadolist
que simplemente enumera todos los nombres de destino en orden alfabético, es decir: invocar comomake list
:Importante : Al pegar esto, asegúrese de que la última línea esté sangrada exactamente por 1 carácter de pestaña real. (Los espacios no funcionan) .
Tenga en cuenta que ordenar la lista de objetivos resultante es la mejor opción, ya que no ordenar no produce un orden útil en el sentido de que no se conserva el orden en que aparecen los objetivos en el archivo MAKE .
Además, los objetivos secundarios de una regla que comprende múltiples objetivos se emiten invariablemente por separado y, por lo tanto, debido a la clasificación, generalmente no aparecerán uno al lado del otro; por ejemplo, una regla a partir de
a z:
lo que no tienen objetivosa
yz
que aparece al lado del otro en la salida, si hay objetivos adicionales.Explicación de la regla :
PHONY: list
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
make
nuevamente para imprimir y analizar la base de datos derivada del archivo MAKE:-p
imprime la base de datos-Rr
suprime la inclusión de reglas y variables integradas-q
solo prueba el estado actualizado de un objetivo (sin rehacer nada), pero eso por sí solo no impide la ejecución de comandos de receta en todos los casos; por lo tanto:-f $(lastword $(MAKEFILE_LIST))
garantiza que se dirija el mismo archivo MAKE que en la invocación original, independientemente de si fue dirigido implícita o explícitamente con-f ...
.Advertencia : Esto se romperá si su archivo MAKE contiene
include
directivas; Para abordar esto, defina la variableTHIS_FILE := $(lastword $(MAKEFILE_LIST))
antes de cualquierinclude
directiva y úsela-f $(THIS_FILE)
en su lugar.:
es un objetivo deliberadamente inválido destinado a garantizar que no se ejecuten comandos ;2>/dev/null
suprime el mensaje de error resultante. Nota: Sin-p
embargo, esto se basa en la impresión de la base de datos, que es el caso de GNU make 3.82. Lamentablemente, GNU make no ofrece una opción directa para simplemente imprimir la base de datos, sin ejecutar también la tarea predeterminada (o dada); si no necesita apuntar a un Makefile específico, puede usarlomake -p -f/dev/null
, como se recomienda en laman
página.-v RS=
/^# File/,/^# Finished Make data base/
if ($$1 !~ "^[#.]")
#
... ignora los no objetivos, cuyos bloques comienzan con# Not a target:
.
... ignora objetivos especiales:
egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
elimina los objetivos no deseados de la salida:'^[^[:alnum:]]'
... excluye objetivos ocultos , que, por convención, son objetivos que no comienzan ni con una letra ni con un dígito.'^$@$$'
... excluye ellist
objetivo en síCorrer
make list
luego imprime todos los objetivos, cada uno en su propia línea; puede canalizar paraxargs
crear una lista separada por espacios en su lugar.fuente
rake --tasks
hace?-n
opción-n
opción es "Imprimir los comandos que se ejecutarían ...", en otras palabras: una función de ejecución en seco. Tampoco que su cotización que le falta la cursiva de la palabra simplemente :make -p
por sí mismo hace imprimir la base de datos, pero, invariablemente, también se ejecuta la tarea por defecto ; el manual recomienda el torpemake -p -f/dev/null
para evitar eso..PHONY: *
En Bash (al menos), esto se puede hacer automáticamente con la finalización de la pestaña:
make
spacetabtabfuente
. /etc/bash_completion
) y aquellas que no la admiten en absoluto (p. ej., OSX 10.9)bash-completion
paquete. Encontrado en Fedora, RHEL, Gentoo, ect.$(RUN_TARGETS): run-%: ...
Obviamente, esto no funcionará en muchos casos, pero si
Makefile
fue creado por CMake, es posible que pueda ejecutarlomake help
.fuente
touch CMakeLists.txt && cmake . && make help
y debería funcionar. ¿Solo puedo adivinar que estás usando un cmake antiguo o no estás usando el generador de Unix Makefiles?Combiné estas dos respuestas: https://stackoverflow.com/a/9524878/86967 y https://stackoverflow.com/a/7390874/86967 e hice algunos escapes para poder usarlo desde dentro de un archivo MAKE.
.
fuente
sh -c "…"
es innecesaria, porque eso es lo quemake
por defecto usa para invocar comandos de recetas; (b) el comando que usa es demasiado simplista, lo que da como resultado falsos positivos (como observa); (c) si prefijas el comando con@
, no se repetirá en stdout antes de la ejecución, obviando la necesidad de usarlo-s
en la invocación.make -s
(a través de un alias Bash) en lugar de prefijar comandos en el archivo MAKE con@
. Hay algunos casos en los que@
puede ser útil, especialmente como un prefijo para losecho
comandos (donde la visualización del comando sería redundante), pero en general no me gusta usarlo. De esta manera, puedo ver las "recetas" cuando lo necesito (al no usar-s
), pero no de manera típica. Aquí está la documentación relacionada: GNU Make Manual, 5.2 Recipe Echoing .Si tiene la finalización de bash
make
instalada, el script de finalización definirá una función_make_target_extract_script
. Esta función está destinada a crear unsed
script que se puede utilizar para obtener los objetivos como una lista.Úselo así:
fuente
/etc/bash_completion
y / o función_make_target_extract_script
: parece que está en Ubuntu> 12. Si en su/usr/share/bash-completion/completions/make
lugar, apunta , su enfoque funcionará en plataformas adicionales, como Fedora 20. Hay plataformas (más antiguas) que tienen este archivo, pero no la función (por ejemplo, Debian 7 y Ubuntu 12); otras plataformas, como OSX, no vienen con la finalización de pestañasmake
en absoluto. Quizás publicar la definición de la función real sería útil.Como señala mklement0 , una característica para enumerar todos los objetivos Makefile falta en GNU-make, y su respuesta y otras proporcionan formas de hacerlo.
Sin embargo, la publicación original también menciona rake , cuyo cambio de tareas hace algo ligeramente diferente a solo enumerar todas las tareas en el archivo de rake. Rake solo te dará una lista de tareas que tienen descripciones asociadas. Las tareas sin descripciones no se enumerarán . Esto le da al autor la capacidad de proporcionar descripciones de ayuda personalizadas y también omitir la ayuda para ciertos objetivos.
Si desea emular el comportamiento del rastrillo, donde proporciona descripciones para cada objetivo , existe una técnica simple para hacerlo: incrustar descripciones en los comentarios para cada objetivo que desee enumerar.
Puede colocar la descripción al lado del objetivo o, como hago a menudo, junto a una especificación PHONY sobre el objetivo, de esta manera:
Lo que rendirá
También puede encontrar un ejemplo de código corto en esta esencia y aquí también.
Nuevamente, esto no resuelve el problema de enumerar todos los objetivos en un Makefile. Por ejemplo, si tiene un gran Makefile que tal vez se generó o que alguien más escribió, y desea una forma rápida de enumerar sus objetivos sin excavarlo, esto no ayudará.
Sin embargo, si está escribiendo un Makefile y desea una forma de generar texto de ayuda de manera coherente y autodocumentada, esta técnica puede ser útil.
fuente
echo
comando como la descripción del comando ( stackoverflow.com/a/52059487/814145 ).@echo "Target 1"
es solo un marcador de posición y no un "comando echo de descripción". El texto de ayuda generado no proviene de@echo
's. En un Makefile real, estosecho
serían reemplazados por un comando de construcción o algo así. Editaré la publicación para aclarar esto.Mi respuesta favorita a esto fue publicada por Chris Down en Unix & Linux Stack Exchange. Citaré
El usuario Brainstone sugiere tuberías
sort -u
para eliminar entradas duplicadas:Fuente: ¿Cómo enumerar todos los objetivos en make? (Unix y Linux SE)
fuente
La respuesta de @ nobar muestra útilmente cómo usar la finalización de pestañas para enumerar los objetivos de un archivo MAKE .
Esto funciona muy bien para plataformas que proporcionan esta funcionalidad de manera predeterminada (por ejemplo, Debian, Fedora ).
En otras plataformas (p. Ej., Ubuntu ) debe cargar explícitamente esta funcionalidad, como lo implica la respuesta de @ hek2mgl :
. /etc/bash_completion
instala varias funciones de finalización de pestañas, incluida la demake
make
:. /usr/share/bash-completion/completions/make
-f <file>
.fuente
Centrándome en una sintaxis fácil para describir un objetivo de creación y con una salida limpia, elegí este enfoque:
Así que tratar lo anterior como un Makefile y ejecutarlo te da algo así como
Explicación de la cadena de comandos:
fuente
awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort
con##
el comentario anterior en la misma línea que el objetivo. Pero creo que su solución permite antes de la legibilidad.grep: parentheses not balanced
en mi máquina OSX 10.15.Aquí hay muchas soluciones viables, pero como me gusta decir, "si vale la pena hacerlo una vez, vale la pena hacerlo de nuevo". Elegí la sugestión para usar (tab) (tab), pero como algunos han notado, es posible que no tenga soporte de finalización o, si tiene muchos archivos de inclusión, es posible que desee una forma más fácil de saber dónde se define un objetivo.
No he probado lo siguiente con sub-marcas ... Creo que no funcionaría. Como sabemos, lo recursivo hace que se considere dañino.
Lo que me gusta porque:
Explicación:
Salida de muestra:
fuente
Este fue útil para mí porque quería ver los objetivos de compilación requeridos (y sus dependencias) por el objetivo de creación. Sé que hacer objetivos no puede comenzar con un "." personaje. No sé qué idiomas son compatibles, así que elegí las expresiones de corchetes de egrep.
fuente
Esto está lejos de ser limpio, pero hizo el trabajo, para mí.
Yo uso
make -p
que vuelca la base de datos interna, zanja stderr, uso rápido y suciogrep -A 100000
para mantener la parte inferior de la salida. Luego limpio la salida con un par degrep -v
, y finalmente usocut
para obtener lo que está antes del colon, es decir, los objetivos.Esto es suficiente para mis scripts de ayuda en la mayoría de mis Makefiles.
EDITAR: agregado
grep -v Makefile
que es una regla internafuente
Esta es una modificación a la muy útil respuesta de jsp ( https://stackoverflow.com/a/45843594/814145 ). Me gusta la idea de obtener no solo una lista de objetivos sino también sus descripciones. jspEl Makefile de pone la descripción como el comentario, que encontré a menudo se repetirá en el comando echo de descripción del objetivo. Entonces, en cambio, extraigo la descripción del comando echo para cada objetivo.
Ejemplo de Makefile:
Salida de
make help
:Notas:
echo
o:
como el primer comando de la receta.:
significa "no hacer nada". Lo uso aquí para aquellos objetivos que no necesitan eco, como elall
objetivo anterior.help
objetivo agregue el ":" en lamake help
salida.fuente
Otra respuesta adicional a la anterior.
probado en MacOSX usando solo cat y awk en la terminal
saldrá del archivo make como a continuación:
en el Makefile, debe ser la misma declaración, asegúrese de escapar de las variables usando $$ variable en lugar de $ variable.
Explicación
gato - escupe el contenido
El | - la tubería analiza la salida al siguiente awk
awk : ejecuta expresiones regulares excluyendo "shell" y aceptando solo líneas "Az", luego imprime la primera columna de $ 1
awk : una vez más, elimina el último carácter ":" de la lista
esta es una salida aproximada y puedes hacer cosas más funky con solo AWK. Intente evitar sed ya que no es tan consistente en las variantes de BSD, es decir, algunos funcionan en * nix pero fallan en BSD como MacOSX.
Más
Debería poder agregar esto (con modificaciones) a un archivo para hacer , a la carpeta predeterminada de finalización de bash /usr/local/etc/bash-completion.d/ lo que significa que cuando "hace pestaña de pestañas " ... completará el objetivos basados en el guión de un trazador de líneas.
fuente
Yo suelo hacer:
Volvería con algo como:
espero que esto ayude
fuente
Para una secuencia de comandos Bash
Aquí hay una manera muy simple de hacer esto
bash
, según el comentario de @ cibercitizen1 anterior :Vea también la respuesta más autorizada de @ Marc.2377, que dice cómo lo hace el módulo de finalización de Bash
make
.fuente
No estoy seguro de por qué la respuesta anterior fue tan complicada:
fuente
$(SHELLS): ...
), (b) inclusión de objetivos que comienzan con un dígito, (c) no inclusión de definiciones variables , (d) apuntar al archivo MAKE apropiado simake
se especificó con una ruta de archivo MAKE explícita. (a) es la deficiencia crucial: incluso si apuntó de manera confiable al archivo MAKE correcto , analizar el archivo sin formato no funcionará en el caso general, debido a la falta de expansión variable.awk -F: '/^[A-z]/ {print $$1}' Makefile
. Finalmente, un punto en gran medida académico: usar en[A-z]
lugar de[:alpha:]
significa que perderás objetivos que comienzan con un personaje extranjero comoá
.[[:alpha:]]
en lugar de[:alpha:]
([:alpha:]
representa el conjunto de la configuración regional al tanto de las letras dentro de una clase de caracteres ([...]
), de ahí la necesidad efectiva de doble[[
/]]
.awk -F: '/^[A-Za-z]/ { print $$1 }' Makefile
usa un solo proceso y, con suerte, una expresión regular más correcta (aunque, por supuesto, también podría tener objetivos con guiones bajos, números, etc., como se señaló en comentarios anteriores).