정의에 변수를 포함하는 GNU make의 목표 / 타겟 나열
변수에서 이름을 계산하여 즉석에서 여러 대상을 만드는 상당히 큰 메이크 파일이 있습니다. (예 : foo $ (VAR) : $ (PREREQS)). gnu make가 이러한 변수를 확장 한 후 대상 목록을 뱉어 낼 수있는 방법이 있습니까?
임의의 메이크 파일에 대한 타겟을 얻고 싶습니다. 셸에 대한 완성 함수를 작성하려고합니다.
make -pn
(예 :)에서 출력을 구문 분석 할 수 있습니까 make --print-data-base --dry-run
? 모든 변수, 규칙, 암시 적 규칙 및 힘든 세부 사항으로 실행될 명령을 인쇄합니다.
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
매력처럼 작동하는 make arg 완성에서 가져 왔습니다.
이것이 gnu make 일인지 확실하지 않지만 잘 작동합니다.
make help
몇몇 응답자들은을 사용하여 make -pn
규칙 데이터베이스를 인쇄하지만 실행하지는 않습니다. 이 접근 방식의 문제 -n
는 여전히 모든 재귀 적 make를 호출하고 일반 빌드에서 호출했을 모든 명령을 인쇄하기 때문에 필요한 것보다 더 많은 작업을 수행한다는 것입니다. 보다 효율적인 솔루션은 다음 내용으로 간단한 makefile 인 dummy.mk를 만드는 것입니다.
__all_targets__: ; #no-op
이제 make를 make -p -f Makefile -f dummy.mk __all_targets__
. 실질적인 빌드에서 make에 의해 생성되는 산출량의 차이는 중요합니다. 예를 들면 :
$ gmake -pn | wc
138985 2632330 69612711
$ gmake -f Makefile -f /tmp/dummy.mk -pn __all_targets__ | wc
21673 93437 878985
실행 시간도 극적으로 향상되었습니다. 첫 번째 버전은 2.063 초, 두 번째 버전은 0.059 초였습니다.
GitHub 에서 make 에 대한 bash 완료를 확인하십시오 .
편집 : 참고로 다른 답변의 debian bash 완료 git 저장소는 이제 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
이것은 질문이 요구하는 생성 된 규칙에 대한 결과를 제공하고 가장 많이 득표 한 답변 (데비안 git 서버의 데비안 bash 완료 스크립트)이 충분하지 않기 때문에 데비안 bash 완료 스크립트보다 훨씬 더 완전한 스크립트입니다.
이것은 내가 링크 한 원래 스크립트는 아니지만 훨씬 더 간단하고 터치가 더 빠릅니다.
이것은 Todd Hodes 솔루션을 기반으로하는 별칭에 대한 코드입니다.
alias mtargets='make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"'
이것은 좋은 출력을 줄 것입니다 :
make -pn | perl -F: -ane 'print "$F[0]\n" if /^\w+\s*:/' | sort
여기에 sed 및 egrep 마법이있는 아주 좋은 솔루션이 있습니다 : https://gist.github.com/pvdb/777954
내가이 파티에 좀 늦었 나봐요.하지만 특정 명령을 찾고 있다면 시도해 볼 수 있습니다
make -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'
This mostly works, although it might still include some non-target stuff like a vpath
directive. If you don't depend on make
's built-in rules, you can use make -qpR
as the first command in the pipeline.
Ruby solution:
`make -qp`.split("\n").select{|l| l =~ /^\w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'')}
Im working on solaris 10 anda turbo C shell. The given solution doesn´t work for my makefile project. even after altering the command line above to tcsh syntax. However, I found out you can get an easy solution using
remake --tasks | grep -v "clean some static output or just grep tabs on start of line" | awk ´{print $1}´
remake version:
remake --version
is
GNU Make 3.82+dbg0.8
Built for sparc-sun-sparc2-9
and some other unimportant version data
I went looking for the same question and came up with this spin:
make -pn | sed -rn '/^[^# \t\.%].*:/p'
This removes all comment lines, pattern rules (lines beginning with tabs), all the intrinsics (example .c.o
and %.o: %.c
patterns).
Found this solution in another thread:
sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\""
You can also add it to your Makefile
:
list:
sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\\""
And execute make list
.
Sure, but when do you want it to spit them out?
To report the name of the target when it runs the rule, put a line in the rule:
foo$(VAR): $(PREREQS)
@echo now making the foo target: $@
do_other_stuff...
To spit them all out at once, you could make a separate PHONY target:
.PHONY: show_vars
show_vars:
@echo foo$(VAR)
@echo bar$(PARAM) blah$(FLAG)
# and so on
And this can be made a prerequisite of your default target:
all: show_vars
...
EDIT:
You want a way to show all possible targets of an arbitrary makefile, which I suppose means non-intrusively. Well...
To do it exactly, and be able to cope with sophisticated makefiles, e.g. involving rules constructed by eval
statements, you'd have to write something close to a Make emulator. Impractical.
To see the targets of the simple rules, you could write a makefile that would act as a makefile scanner, operating on an arbitrary makefile:
- Get all the target names from the makefile using sed.
- `include` the makefile in order to use it to expand variables.
- Use `show_%: ; echo $$*` to print all the targets
This would be an impressive piece of work. Are you sure the goal is worth the effort?
grep ^[a-z].*\:$ Makefile | sed s,:,,g
'program story' 카테고리의 다른 글
presentModalViewController : Animated는 ios6에서 더 이상 사용되지 않습니다. (0) | 2020.08.20 |
---|---|
Laravel에서 이것을 수행하는 방법, 하위 쿼리 (0) | 2020.08.20 |
영업일 계산 (0) | 2020.08.20 |
pycharm은 탭을 공백으로 자동으로 변환합니다. (0) | 2020.08.20 |
Python에서 하위 프로세스, 다중 처리 및 스레드 중에서 결정합니까? (0) | 2020.08.20 |