¿Cómo se obtiene la lista de objetivos en un archivo MAKE?

202

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:
Brian Burns
fuente
2
Leí rápidamente las respuestas, que son interesantes, pero hasta ahora prefiero mantenerlo simple, simple y portátil usando un alias (en mi .bashrc): la 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 alias
RockyRoad
44
¿Es demasiado trivial solo grep : Makefile:?
cibercitizen1

Respuestas:

130

Este es un intento de mejorar el gran enfoque de @nobar de la siguiente manera:

  • utiliza un comando más robusto para extraer los nombres de destino, lo que con suerte previene cualquier falso positivo (y también elimina los innecesarios sh -c)
  • no se dirige invariablemente al archivo MAKE en el directorio actual ; respeta los makefiles especificados explícitamente con-f <file>
  • excluye objetivos ocultos: por convención, estos son objetivos cuyo nombre no comienza ni con una letra ni con un dígito
  • se conforma con un solo objetivo falso
  • prefija el comando con @para evitar que se repita antes de la ejecución

Curiosamente, GNU makeno tiene una función para enumerar solo los nombres de objetivos definidos en un archivo MAKE. La -popció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 makeimplemente un objetivo llamado listque simplemente enumera todos los nombres de destino en orden alfabético, es decir: invocar comomake list :

.PHONY: list
list:
    @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'

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 objetivos ay zque aparece al lado del otro en la salida, si hay objetivos adicionales.

Explicación de la regla :

  • .PHONY: list
    • declara que la lista de objetivos es un objetivo falso, es decir, uno que no se refiere a un archivo , por lo que debe invocarse su receta incondicionalmente
  • $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null

    • Invoca makenuevamente 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
      • -qsolo 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 includedirectivas; Para abordar esto, defina la variable THIS_FILE := $(lastword $(MAKEFILE_LIST)) antes de cualquier includedirectiva y úsela -f $(THIS_FILE)en su lugar.
      • :es un objetivo deliberadamente inválido destinado a garantizar que no se ejecuten comandos ; 2>/dev/nullsuprime el mensaje de error resultante. Nota: Sin -pembargo, 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 usarlo make -p -f/dev/null, como se recomienda en la manpágina.
  • -v RS=

    • Este es un idioma awk que divide la entrada en bloques de líneas contiguas no vacías.
  • /^# File/,/^# Finished Make data base/
    • Coincide con el rango de líneas en la salida que contiene todos los objetivos (verdadero a partir de GNU make 3.82): al limitar el análisis a este rango, no es necesario tratar con falsos positivos de otras secciones de salida.
  • if ($$1 !~ "^[#.]")
    • Ignora selectivamente los bloques:
      • # ... ignora los no objetivos, cuyos bloques comienzan con # Not a target:
      • . ... ignora objetivos especiales
    • Todos los demás bloques deben comenzar con una línea que contenga solo el nombre de un objetivo definido explícitamente seguido de :
  • 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 el listobjetivo en sí

Correr make listluego imprime todos los objetivos, cada uno en su propia línea; puede canalizar para xargscrear una lista separada por espacios en su lugar.

mklement0
fuente
Esta es una gran respuesta, sin embargo, ¿cómo obtendría la descripción de cada tarea? Actualmente, lo estoy almacenando como un comentario sobre la definición de tarea. ¿No está seguro si es posible incluirlo en la lista de manera similar a como lo rake --taskshace?
Piotr Kuczynski
1
@PiotrKuczynski: Pregunta interesante, pero le sugiero que la publique como una nueva pregunta (señalando esta como referencia).
mklement0
"Lamentablemente, GNU make no ofrece una opción directa para imprimir la base de datos". Hay una -nopción
Bulletmagnet
@Bulletmagnet: El propósito de la -nopció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 -ppor sí mismo hace imprimir la base de datos, pero, invariablemente, también se ejecuta la tarea por defecto ; el manual recomienda el torpe make -p -f/dev/nullpara evitar eso.
mklement0
1
También enumerará cualquier objetivo .PHONY, así que asegúrese de no tenerlo.PHONY: *
tekumara
189

En Bash (al menos), esto se puede hacer automáticamente con la finalización de la pestaña:

make spacetabtab

sin bar
fuente
1
Probado: bash --version = 4.2.45 (1) -release. make --version = 3.81.
nobar
53
+1, pero tenga en cuenta que esta no es una función bash , sino que depende de su plataforma . Las plataformas se dividen en tres categorías: aquellas en las que esta finalización se instala de manera predeterminada (por ejemplo, Debian 7, Fedora 20), aquellas en las que puede instalarla opcionalmente (por ejemplo, Ubuntu 14, con . /etc/bash_completion) y aquellas que no la admiten en absoluto (p. ej., OSX 10.9)
mklement0
8
funciona en OS X 10.10 (no con bash sino con zsh).
Florian Oswald
44
Gran consejo pero también necesita bash-completionpaquete. Encontrado en Fedora, RHEL, Gentoo, ect.
NoelProf
44
Esto no funciona con los objetivos AFAICT creados programáticamente, por ejemplo$(RUN_TARGETS): run-%: ...
Matthias
32

Obviamente, esto no funcionará en muchos casos, pero si Makefilefue creado por CMake, es posible que pueda ejecutarlo make help.

$ make help
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... install
etc
Timmmm
fuente
¿Tiene alguna opción para activar su CMakeList para obtener eso? Recibí un archivo MAKE generado por CMake y no tengo disponible el objetivo de pseudoayuda
Xavier T.
No En OSX, al menos con un CMake reciente (en realidad estoy usando nightlies pero creo que cuando escribí esto estaba usando 3.3), solo corre touch CMakeLists.txt && cmake . && make helpy debería funcionar. ¿Solo puedo adivinar que estás usando un cmake antiguo o no estás usando el generador de Unix Makefiles?
Timmmm
Estoy usando CMake 3.6.2 con el generador de Unix en Windows. Cavaré para buscar una explicación porque parece útil.
Xavier T.
26

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.

.PHONY: no_targets__ list
no_targets__:
list:
    sh -c "$(MAKE) -p no_targets__ | awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {split(\$$1,A,/ /);for(i in A)print A[i]}' | grep -v '__\$$' | sort"

.

$ make -s list
build
clean
default
distclean
doc
fresh
install
list
makefile ## this is kind of extraneous, but whatever...
run
sin bar
fuente
10
También (recientemente) descubrí que completar pestañas en Bash enumerará los objetivos disponibles.
nobar
1
+1 para un enfoque excelente, pero podrían hacerse algunas mejoras: (a) la especificación explícita sh -c "…"es innecesaria, porque eso es lo que makepor 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 -sen la invocación.
mklement0
1
hay un objetivo de creación mucho más simple que podría agregar: lista: cat Makefile | grep "^ [Az]" | awk '{print $$ 1}' | sed "s /: // g | sort"
thamster
2
El enfoque cat / sed falla en varios niveles. No expande las variables y tampoco puede enumerar los objetivos que son el resultado de incluir otros archivos.
Troy Daniels
1
@ mklement0: Prefiero usar 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 los echocomandos (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 .
nobar
14

Si tiene la finalización de bash makeinstalada, 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í:

# Make sure bash completion is enabled
source /etc/bash_completion 

# List targets from Makefile
sed -nrf <(_make_target_extract_script --) Makefile
hek2mgl
fuente
3
Útil, pero tenga en cuenta que no todas las plataformas tienen script /etc/bash_completiony / o función _make_target_extract_script: parece que está en Ubuntu> 12. Si en su /usr/share/bash-completion/completions/makelugar, 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ñas makeen absoluto. Quizás publicar la definición de la función real sería útil.
mklement0
1
Gracias por tu comentario. Esto es muy apreciado. Sí, he probado esto en Ubuntu 14.04
hek2mgl
11

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:

.PHONY: target1 # Target 1 help text
target1: deps
    [... target 1 build commands]

.PHONY: target2 # Target 2 help text
target2:
    [... target 2 build commands]

...                                                                                                         

.PHONY: help # Generate list of targets with descriptions                                                                
help:                                                                                                                    
    @grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20

Lo que rendirá

$ make help
target1             Target 1 help text
target2             Target 2 help text

...
help                Generate list of targets with descriptions

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.

jsp
fuente
Esta es una gran técnica, agradable y simple, ¡pero también ofrece descripciones!
Brian Burns el
Gran técnica Modifiqué esto un poco para usar el echocomando como la descripción del comando ( stackoverflow.com/a/52059487/814145 ).
Penghe Geng
@PengheGeng Gracias por la publicación. Quiero dejar en claro que @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, estos echoserían reemplazados por un comando de construcción o algo así. Editaré la publicación para aclarar esto.
jsp
5

Mi respuesta favorita a esto fue publicada por Chris Down en Unix & Linux Stack Exchange. Citaré

Así es como el módulo de finalización de bash makeobtiene su lista:

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

Imprime una lista de objetivos delimitada por una nueva línea, sin paginación.

El usuario Brainstone sugiere tuberías sort -upara eliminar entradas duplicadas:

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

Fuente: ¿Cómo enumerar todos los objetivos en make? (Unix y Linux SE)

Marc.2377
fuente
4

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 de make
    • Alternativamente, para instalar solo la finalización de pestañas para make:
      • . /usr/share/bash-completion/completions/make
  • Para las plataformas que no ofrecen esta funcionalidad , como OSX , puede obtener los siguientes comandos (adaptados desde aquí ) para implementarla:
_complete_make() { COMPREPLY=($(compgen -W "$(make -pRrq : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' | egrep -v '^[^[:alnum:]]' | sort | xargs)" -- "${COMP_WORDS[$COMP_CWORD]}")); }
complete -F _complete_make make
  • Nota: Esto no es tan sofisticado como la funcionalidad de finalización de tabulación que viene con las distribuciones de Linux: más notablemente, siempre apunta al archivo MAKE en el directorio actual , incluso si la línea de comando apunta a un archivo MAKE diferente -f <file>.
mklement0
fuente
4

Centrándome en una sintaxis fácil para describir un objetivo de creación y con una salida limpia, elegí este enfoque:

help:
    @grep -B1 -E "^[a-zA-Z0-9_-]+\:([^\=]|$$)" Makefile \
     | grep -v -- -- \
     | sed 'N;s/\n/###/' \
     | sed -n 's/^#: \(.*\)###\(.*\):.*/\2###\1/p' \
     | column -t  -s '###'


#: Starts the container stack
up: a b
  command

#: Pulls in new container images
pull: c d 
    another command

make-target-not-shown:

# this does not count as a description, so leaving
# your implementation comments alone, e.g TODOs
also-not-shown:

Así que tratar lo anterior como un Makefile y ejecutarlo te da algo así como

> make help
up          Starts the container stack
pull        Pulls in new container images

Explicación de la cadena de comandos:

Richard Kiefer
fuente
Muy buena solución. Lo he usado durante algunos años: 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.
thoroc
Un archivo MAKE compuesto por los primeros informes de dos líneas grep: parentheses not balanceden mi máquina OSX 10.15.
Malcolm Crum
@Crummy lo siento, mi error. Gracias por mencionarlo. Arreglado. make requiere escapar de los signos de dólar que no deben iniciar nombres de variables.
Richard Kiefer
Cuidado, StackOverflow convierte las pestañas en espacios al mostrar las secciones de código anteriores, pero los Makefiles requieren pestañas. Puede editar la publicación y luego copiar las secciones, de modo que se mantengan las pestañas.
Richard Kiefer
2

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.

.PHONY: list ls
ls list :
    @# search all include files for targets.
    @# ... excluding special targets, and output dynamic rule definitions unresolved.
    @for inc in $(MAKEFILE_LIST); do \
    echo ' =' $$inc '= '; \
    grep -Eo '^[^\.#[:blank:]]+.*:.*' $$inc | grep -v ':=' | \
    cut -f 1 | sort | sed 's/.*/  &/' | sed -n 's/:.*$$//p' | \
    tr $$ \\\ | tr $(open_paren) % | tr $(close_paren) % \
; done

# to get around escaping limitations:
open_paren := \(
close_paren := \)

Lo que me gusta porque:

  • Enumerar objetivos por archivo de inclusión.
  • generar definiciones de destino dinámico sin procesar (reemplaza los delimitadores variables con módulo)
  • dar salida a cada objetivo en una nueva línea
  • parece más claro (opinión subjetiva)

Explicación:

  • cada archivo en la MAKEFILE_LIST
  • dar salida al nombre del archivo
  • líneas grep que contienen dos puntos, que no están sangrados, no son comentarios, y no comienzan con un punto
  • excluir expresiones de asignación inmediata (: =)
  • cortar, ordenar, sangrar y cortar dependencias de reglas (después de dos puntos)
  • Delimitadores variables Munge para evitar la expansión

Salida de muestra:

 = Makefile = 
  includes
  ls list
 = util/kiss/snapshots.mk = 
  rotate-db-snapshots
  rotate-file-snapshots
  snap-db
  snap-files
  snapshot
 = util/kiss/main.mk = 
  dirs
  install
   %MK_DIR_PREFIX%env-config.php
   %MK_DIR_PREFIX%../srdb
ginkgoMZD
fuente
1

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.

cat Makefile | egrep "^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$"
seanlum
fuente
1

Esto está lejos de ser limpio, pero hizo el trabajo, para mí.

make -p 2&>/dev/null | grep -A 100000 "# Files" | grep -v "^$" | grep -v "^\(\s\|#\|\.\)" | grep -v "Makefile:" | cut -d ":" -f 1

Yo uso make -pque vuelca la base de datos interna, zanja stderr, uso rápido y sucio grep -A 100000para mantener la parte inferior de la salida. Luego limpio la salida con un par de grep -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 Makefileque es una regla interna

Lisael
fuente
1

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:

.PHONY: all
all: build
        : "same as 'make build'"

.PHONY: build
build:
        @echo "Build the project"

.PHONY: clean
clean:
        @echo "Clean the project"

.PHONY: help
help:
        @echo -n "Common make targets"
        @echo ":"
        @cat Makefile | sed -n '/^\.PHONY: / h; /\(^\t@*echo\|^\t:\)/ {H; x; /PHONY/ s/.PHONY: \(.*\)\n.*"\(.*\)"/    make \1\t\2/p; d; x}'| sort -k2,2 |expand -t 20

Salida de make help:

$ make help
Common make targets:
    make all        same as 'make build'
    make build      Build the project
    make clean      Clean the project
    make help       Common make targets

Notas:

  • Igual que la respuesta de jsp , solo se pueden enumerar los objetivos de PHONY, que pueden o no funcionar para su caso
  • Además, solo enumera los objetivos PHONY que tienen un comando echoo :como el primer comando de la receta. :significa "no hacer nada". Lo uso aquí para aquellos objetivos que no necesitan eco, como el allobjetivo anterior.
  • Hay un truco adicional para que el helpobjetivo agregue el ":" en la make helpsalida.
Penghe Geng
fuente
0

Otra respuesta adicional a la anterior.

probado en MacOSX usando solo cat y awk en la terminal

cat Makefile | awk '!/SHELL/ && /^[A-z]/ {print $1}' | awk '{print substr($0, 1, length($0)-1)}'

saldrá del archivo make como a continuación:

objetivo1

target2

target3

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.

Jimmy MG Lim
fuente
También puede usar make -qp en lugar de cat. entonces se convertirá en make -qp | awk '/: / &&! /: = / && / ^ [Az] / &&! / PATH / &&! / DISPLAY / &&! / TERM_SESSION / &&! / USER_TEXT_ENCODING / &&! / Makefile / {print substr ($ 0, 1 , longitud ($ 0) -1) | "sort -u"} '
Jimmy MG Lim
0

Yo suelo hacer:

grep install_targets Makefile

Volvería con algo como:

install_targets = install-xxx1 install-xxx2 ... etc

espero que esto ayude

Heider Sati
fuente
0

Para una secuencia de comandos Bash

Aquí hay una manera muy simple de hacer esto bash, según el comentario de @ cibercitizen1 anterior :

grep : Makefile | awk -F: '/^[^.]/ {print $1;}'

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.

jvriesem
fuente
-4

No estoy seguro de por qué la respuesta anterior fue tan complicada:

list:
    cat Makefile | grep "^[A-z]" | awk '{print $$1}' | sed "s/://g" 
thamster
fuente
8
La respuesta anterior es tan complicada, porque cubre todos los escenarios que su respuesta NO cubre: (a) inclusión de objetivos definidos a través de variables (por ejemplo, $(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 si makese 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.
mklement0
66
Como acotación al margen, re complicado: su comando se puede simplificar a la siguiente - pero el punto principal es que no es lo suficientemente robusta como : 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 á.
mklement0
@ mklement0 su primer comando awk funciona bien y es el más simple hasta ahora, aunque usar [: alpha:] parece romperlo por alguna razón: se pierden algunos objetivos en un archivo de prueba.
Brian Burns
@ bburns.km: Mi mal: que debería haber dicho [[: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 [[ / ]].
mklement0
44
¿Por qué es tan complicada esta respuesta? Te las arreglas para recoger varios de los pecados inútiles en este breve fragmento. awk -F: '/^[A-Za-z]/ { print $$1 }' Makefileusa 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).
tripleee