Lista celów / targets w GNU make, które zawierają zmienne w swojej definicji
Mam dość duży plik makefile, który tworzy wiele celów w locie, obliczając nazwy ze zmiennych. (np. foo$(VAR): $(PREREQS)). Czy jest jakiś sposób, aby gnu make mógł być przekonany do wyplucia listy celów po rozszerzeniu tych zmiennych?
Chciałbym być w stanie zdobyć cele dla aribitrary makefile. Próbuję napisać funkcję dopełnienia dla mojej powłoki.
16 answers
Czy możesz przeanalizować wyjście z make -pn
(tj. make --print-data-base --dry-run
)? Wypisuje wszystkie zmienne, reguły, reguły ukryte i które polecenia będą uruchamiane w żmudnych szczegółach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-03 02:02:12
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
Wzięte z make arg, który działa jak urok.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-02 18:55:54
Nie jestem pewien czy to jest tylko gnu make, ale to działa dobrze:
make help
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-11 21:23:28
Kilku respondentów zasugerowało użycie make -pn
, które wydrukuje bazę reguł, ale niczego nie wykona-mniej więcej. Problem z tym podejściem polega na tym, że -n
nadal wywołuje wszystkie rekurencyjne Make, i nadal wykonuje o wiele więcej pracy niż to konieczne, ponieważ wypisuje wszystkie polecenia, które wywołałby w zwykłej kompilacji. Bardziej efektywnym rozwiązaniem byłoby stworzenie banalnego makefile, dummy.mk, o treści:
__all_targets__: ; #no-op
Teraz wywołaj make jako make -p -f Makefile -f dummy.mk __all_targets__
. W przypadku każdej istotnej budowy różnica w ilości produkcji generowanej przez make jest znacząca. Na przykład:
$ gmake -pn | wc
138985 2632330 69612711
$ gmake -f Makefile -f /tmp/dummy.mk -pn __all_targets__ | wc
21673 93437 878985
Czas wykonania był znacznie lepszy, jak również -- 2.063 s dla pierwszej wersji, 0.059 s dla drugiej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-12 16:14:51
Sprawdź Ukończenie bash dla make na Githubie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-01 08:25:11
Edit: dla twojej wiadomości repozytorium Debian bash completion git w innej odpowiedzi zawiera teraz ulepszoną wersję tego skryptu dostosowaną do przypadków użycia bash completion.
#!/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
Jest to o wiele bardziej kompletny skrypt niż skrypt zakończenia bash Debiana, ponieważ zapewnia wyniki dla wygenerowanych reguł, o co prosi pytanie, a najczęściej głosowana odpowiedź (skrypt zakończenia bash Debiana na debian Git server) nie idzie wystarczająco daleko.
To nie jest oryginalny skrypt, który Połączyłem się, ale to jest znacznie prostsze i jest to dotyk szybciej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-18 21:37:45
To jest kod aliasu oparty na rozwiązaniu Todda Hodesa
alias mtargets='make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-20 06:40:23
To da ładny wynik:
make -pn | perl -F: -ane 'print "$F[0]\n" if /^\w+\s*:/' | sort
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-08 13:22:19
Jest tu bardzo ładne rozwiązanie z jakąś magią sed i egrep: https://gist.github.com/pvdb/777954
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-06 08:42:19
Chyba trochę się spóźniłem na tę imprezę, ale jeśli szukasz konkretnego polecenia, możesz spróbować
make -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'
To w większości działa, chociaż nadal może zawierać pewne rzeczy niecelowe, takie jak dyrektywa vpath
. Jeśli nie zależy ci na wbudowanych regułach make
, możesz użyć make -qpR
jako pierwszego polecenia w potoku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-06 17:31:04
Ruby rozwiązanie:
`make -qp`.split("\n").select{|l| l =~ /^\w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'')}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 08:39:55
Pracuję na Solaris 10 i turbo C shell. Podane rozwiązanie nie działa dla mojego projektu makefile. nawet po zmianie powyższej linii poleceń na składnię tcsh. Jednak okazało się, że można uzyskać łatwe rozwiązanie za pomocą
remake --tasks | grep -v "clean some static output or just grep tabs on start of line" | awk ´{print $1}´
Wersja Remake:
remake --version
Jest
GNU Make 3.82+dbg0.8
Built for sparc-sun-sparc2-9
I inne nieistotne dane wersji
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-20 05:14:41
Szukałem tego samego pytania i wpadłem na ten spin:
make -pn | sed -rn '/^[^# \t\.%].*:/p'
Usuwa wszystkie linie komentarza, reguły wzorca (linie rozpoczynające się tabulatorami), wszystkie wewnętrzne (przykładowe wzorce .c.o
i %.o: %.c
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-03 21:41:12
Znalazłem to rozwiązanie w innym wątku:
sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\""
Możesz też dodać go do swojego Makefile
:
list:
sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\\""
I wykonać make list
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-03 16:26:45
Jasne, ale kiedy chcesz je wypluć?
Aby zgłosić nazwę celu podczas uruchamiania reguły, umieść wiersz w regule:
foo$(VAR): $(PREREQS)
@echo now making the foo target: $@
do_other_stuff...
Aby wypluć je wszystkie na raz, można zrobić osobny fałszywy Cel:
.PHONY: show_vars
show_vars:
@echo foo$(VAR)
@echo bar$(PARAM) blah$(FLAG)
# and so on
I to może być warunkiem wstępnym domyślnego celu:
all: show_vars
...
EDIT:
Chcesz pokazać wszystkie możliwe cele dowolnego pliku makefile, co chyba oznacza nieinwazyjnie. Cóż...
To do it dokładnie, i być w stanie poradzić sobie z wyrafinowanymi plikami Makefile, np. zawierającymi reguły skonstruowane przez eval
, musiałbyś napisać coś podobnego do emulatora Make. Niepraktyczne.
Aby zobaczyć cele prostych zasad, możesz napisać plik makefile, który będzie działał jak skaner makefile, działający na dowolnym pliku makefile:
- pobranie wszystkich nazw docelowych z pliku makefile przy użyciu sed.
- `include ' plik makefile, aby użyć go do rozszerzenia zmienne.
- użyj ' show_%:; echo$$*', aby wydrukować wszystkie cele
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 19:08:48
grep ^[a-z].*\:$ Makefile | sed s,:,,g
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-20 19:22:54