makefile에서 대상 목록을 어떻게 얻습니까?


202

나는 약간의 갈퀴를 사용했고 (Ruby make 프로그램), 사용 가능한 모든 대상의 목록을 얻는 옵션이 있습니다.

> 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...
...

그러나 GNU make에서 이것을 할 수있는 옵션이없는 것 같습니다.

분명히 코드는 2007 년 http://www.mail-archive.com/help-make@gnu.org/msg06434.html 현재 거의 있습니다 .

어쨌든, makefile에서 대상을 추출하기 위해 약간의 핵을 만들었습니다. makefile에 포함시킬 수 있습니다.

list:
    @grep '^[^#[:space:]].*:' Makefile

정의 된 대상 목록을 제공합니다. 그것은 단지 시작일뿐입니다. 예를 들어 의존성을 걸러 내지 않습니다.

> make list
list:
copy:
run:
plot:
turnin:

2
나는 빨리 흥미로운 답변을 읽을 수 있지만 지금까지 자신을 위해 나는 일반 간단한을 유지하는 것을 선호하고, (내 .bashrc에의) 별칭을 사용하여 휴대용 : alias makefile-targets='grep "^[^#[:space:]].*:" Makefile' 대부분의 자주 난 그냥 현재 메이크 파일을 검사해야하고, bash는 완료가 확장 내 별칭.
RockyRoad


4
너무 사소한 일 grep : Makefile입니까?
cibercitizen1

답변:


130

이것은 다음과 같이 @nobar의 훌륭한 접근 방식 을 개선하려는 시도입니다 .

  • 어떤 희망 가양 방지 (및 불필요한 멀리 않는 대상 이름을 추출하기 위해보다 강력한 명령을 사용하여 sh -c)
  • 현재 디렉토리 의 makefile을 항상 대상으로하지 않습니다 . 명시 적으로 지정된 makefile을 존중-f <file>
  • 숨겨진 대상 제외-관례에 따라 이름은 문자 나 숫자로 시작하지 않는 대상입니다.
  • 차종은 함께 할 하나의 가짜 대상
  • @실행 전에 에코되지 않도록 명령 접두사

흥미롭게도 GNU make에는 makefile에 정의 된 대상 이름 만 나열하는 기능이 없습니다. 이 -p옵션은 모든 대상을 포함하는 출력을 생성하지만 다른 많은 정보로 저장합니다.

GNU의 makefile에 다음 규칙을 배치하십시오. makelist 알파벳순으로 모든 대상 이름을 나열하는 이름 지정된 대상을 구현할 수 있습니다 ( 예 : invoke asmake 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 '^$@$$'

중요 사항 : 붙여 넣기시 때 마지막 줄에 정확히 1 개의 실제 탭 문자 가 들여 쓰기되어 있는지 확인하십시오 . (공백이 작동 하지 않습니다 ) .

참고 정렬 이후 목표의 결과 목록하는 것이 가장 좋은 방법입니다 하지 대상이 메이크 파일에 나타나는 순서가 있는지에 도움이 순서를 생성하지 않습니다 정렬 되지 보존.
또한 여러 대상을 포함하는 규칙의 하위 대상은 항상 개별적으로 출력 되므로 정렬로 인해 일반적으로 나란히 표시 되지 않습니다. 예를 들어, a z:will으로 시작하는 규칙 없는 목표를 가지고 az나와 서로 옆에 추가 대상이있는 경우, 출력에.

규칙 설명 :

  • .PHONY: list
    • 대상 목록에 가짜 대상, 즉 파일을 참조 하지 않는 대상을 선언 하므로 레시피가 무조건 호출되어야합니다.
  • $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null

    • makemakefile에서 파생 된 데이터베이스를 인쇄하고 구문 분석하기 위해 다시 호출 합니다.
      • -p 데이터베이스를 인쇄
      • -Rr 내장 규칙 및 변수의 포함을 억제합니다
      • -q대상의 최신 상태 만 테스트하지만 (아무것도 만들지 않음) 모든 경우에 레시피 명령의 실행을 막지는 않습니다. 그 후:
      • -f $(lastword $(MAKEFILE_LIST))을 (를) 내재적으로 또는 명시 적으로 대상화했는지 여부에 관계없이 원래 호출에서와 동일한 메이크 파일을 대상으로합니다 -f ....
        주의 사항 : makefile에 include지시문이 포함되어 있으면 중단됩니다 . 주소이에, 변수를 정의 THIS_FILE := $(lastword $(MAKEFILE_LIST)) 하기 전에 모든 include지침과 사용 -f $(THIS_FILE)대신.
      • :A는 의도적으로 잘못된 대상 을 의미한다 어떤 명령이 실행되지 않도록은 ; 2>/dev/null결과 오류 메시지를 표시하지 않습니다. 참고 : -p그럼에도 불구하고 이것은 GNU make 3.82의 경우와 같이 데이터베이스 인쇄에 의존합니다 . 슬프게도에 GNU 메이크 제공 직접적인 옵션을 바로 하지 않고, 데이터베이스를 인쇄 기본 (또는 제공) 작업을 실행; 특정 Makefile을 타겟팅 할 필요가없는 경우 페이지 make -p -f/dev/null에서 권장 하는대로을 사용할 수 있습니다 man.
  • -v RS=

    • 이것은 비어 있지 않은 빈 라인의 블록으로 입력을 나누는 어색한 관용구입니다.
  • /^# File/,/^# Finished Make data base/
    • 모든 대상을 포함하는 출력의 행 범위와 일치합니다 (GNU make 3.82에서 참).이 범위로 구문 분석을 제한하면 다른 출력 섹션의 오 탐지를 처리 ​​할 필요가 없습니다.
  • if ($$1 !~ "^[#.]")
    • 블록을 선택적으로 무시합니다 :
      • # ... 블록으로 시작하는 비 타겟을 무시합니다. # Not a target:
      • . ... 특별한 목표를 무시
    • 다른 모든 블록은 각각 명시 적으로 정의 된 대상 이름과 그 뒤에 오는 이름 만 포함하는 줄로 시작해야합니다. :
  • egrep -v -e '^[^[:alnum:]]' -e '^$@$$' 출력에서 원하지 않는 대상을 제거합니다.
    • '^[^[:alnum:]]'... 일반적으로 문자 나 숫자로 시작하지 않는 대상인 숨겨진 대상은 제외합니다 .
    • '^$@$$'... list대상 자체는 제외

실행 make list하면 모든 대상이 각각 고유 한 행에 인쇄됩니다. xargs공백으로 구분 된 목록을 작성 하기 위해 파이프로 연결할 수 있습니다 .


이것은 훌륭한 답변이지만 각 작업에 대한 설명은 어떻게 얻습니까? 현재 작업 정의 위의 주석으로 저장하고 있습니다. 목록과 비슷한 방식으로 목록에 포함시킬 수 있는지 확실 rake --tasks하지 않습니까?
Piotr Kuczynski 2016 년

1
@ PiotKuczynski : 흥미로운 질문이지만, 새로운 질문 으로 게시 할 것을 제안합니다 (이 질문을 참조하십시오).
mklement0

"분명히 GNU make는 데이터베이스를 인쇄하는 직접적인 옵션을 제공하지 않습니다." 있다 -n옵션.
Bulletmagnet

@Bulletmagnet : -n옵션 의 목적은 "실행될 명령을 인쇄합니다 ..."즉 , 드라 이런 기능입니다. 또한 견적은 단어의 italicization 누락하지 않도록하는 것이 단지 : make -p자체에 의해 수행 데이터베이스를 인쇄하지만, 변함없이 또한 기본 작업을 실행 ; 매뉴얼은 make -p -f/dev/null그것을 피하기 위해 어수선한 것을 권장합니다 .
mklement0

1
또한 .PHONY 대상을 모두 나열하므로 가지고 있지 않은지 확인하십시오.PHONY: *
tekumara

189

Bash (적어도)에서 이것은 탭 완성으로 자동으로 수행 할 수 있습니다.

make spacetabtab


1
테스트 : bash --version = 4.2.45 (1)-릴리스. --version = 3.81을 만드십시오.
nobar

53
+1이지만 bash 기능은 아니지만 플랫폼에 따라 다릅니다 . 플랫폼은이 완료가 기본적으로 설치되는 플랫폼 (예 : Debian 7, Fedora 20), 선택적으로 설치할 수있는 플랫폼 (예 : Ubuntu 14, with . /etc/bash_completion) 및 전혀 지원하지 않는 플랫폼의 세 가지 범주로 구분됩니다. (예 : OSX 10.9)
mklement0

8
OS X 10.10 (bash가 아니라 zsh)에서 작동합니다.
Florian Oswald

4
좋은 팁이지만 bash-completion패키지가 필요 합니다. Fedora, RHEL, Gentoo에서 발견되었습니다.
NoelProf

4
프로그래밍 방식으로 만든 make 대상 AFAICT에서는 작동하지 않습니다. 예 :$(RUN_TARGETS): run-%: ...
Matthias

31

이것은 많은 경우에 효과가 없지만 MakefileCMake에 의해 생성 된 경우 실행할 수 있습니다 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

그것을 얻기 위해 CMakeList에서 켤 수있는 옵션이 있습니까? CMake에 의해 생성 된 makefile이 있는데 의사 도움말 타겟이 없습니다
Xavier T.

아니. 적어도 최근 CMake가있는 OSX (실제로 야간을 사용하고 있지만 이것을 쓸 때 3.3을 사용한다고 생각합니다), 그냥 실행 touch CMakeLists.txt && cmake . && make help하면 작동합니다. 고대 cmake를 사용하고 있거나 Unix Makefiles 생성기를 사용하지 않는 것만 추측 할 수 있습니까?
Timmmm

Windows에서 UNIX 생성기와 함께 CMake 3.6.2를 사용하고 있습니다. 설명이 도움이 될 것 같아서 설명을 찾아 보도록하겠습니다.
Xavier T.

26

나는 https://stackoverflow.com/a/9524878/86967https://stackoverflow.com/a/7390874/86967 이라는 두 가지 답변을 결합 하여 makefile 내부에서 사용할 수 있도록 탈출했습니다.

.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

10
또한 (최근에) Bash에서 탭 완성이 사용 가능한 대상을 나열한다는 것을 발견했습니다.
nobar

1
좋은 접근 한,하지만 몇 가지 개선 할 수있다 : (a)에 명시 적으로 지정이 sh -c "…"그게 무슨이기 때문에, 불필요한 make조리법 명령을 호출하는 기본 사용에 의해; (b) 사용하는 명령이 너무 단순하여 오 탐지 (주의 사항)가 발생합니다. (c) 명령에 접두사를 @붙이면 실행 전에 stdout에 에코되지 않으므로 -s호출시 사용할 필요가 없습니다 .
mklement0

1
추가 할 수있는 훨씬 간단한 make 대상이 있습니다 : list : cat Makefile | grep "^ [Az]"| awk '{print $$ 1}'| sed "s / : // g | sort"
thamster

2
cat / sed 접근 방식은 여러 수준에서 실패합니다. 변수를 확장하지 않으며 다른 파일을 포함시킨 결과로 대상을 나열하지 못합니다.
트로이 다니엘스

1
@ mklement0 : make -smakefile에서 명령 앞에 접두어를 사용하지 않고 Bash 별칭 을 사용하는 것을 선호합니다 @. @특히 echo명령 의 접두사 (명령 표시가 중복 되는 경우)로 유용 할 수있는 경우가 있지만 일반적으로 사용하고 싶지 않습니다. 이런 식으로, 나는 (를 사용 하지 않음-s ) 필요할 때 "레시피"를 볼 수 있지만 일반적으로 그렇지는 않습니다. 관련 문서는 다음과 같습니다 : GNU Make Manual, 5.2 Recipe Echoing .
nobar

14

bash 완료를 make설치 한 경우 완료 스크립트가 기능을 정의합니다 _make_target_extract_script. 이 기능은 sed대상을 목록으로 얻는 데 사용할 수 있는 스크립트 를 작성 하기위한 것입니다.

다음과 같이 사용하십시오.

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

# List targets from Makefile
sed -nrf <(_make_target_extract_script --) Makefile

3
도움이 되긴하지만 모든 플랫폼에 스크립트 /etc/bash_completion및 / 또는 기능 이있는 것은 아닙니다 _make_target_extract_script. Ubuntu> 12에있는 것 같습니다. /usr/share/bash-completion/completions/make대신 대상 을 지정 하면 Fedora 20과 같은 추가 플랫폼에서 접근 할 수 있습니다. 이 파일이지만 기능은 아닙니다 (예 : Debian 7 및 Ubuntu 12). OSX와 같은 다른 플랫폼에는 탭 완성 기능이 전혀 제공되지 않습니다 make. 실제 함수 정의를 게시하는 것이 도움이 될 것입니다.
mklement0

1
귀하의 의견에 감사드립니다. 이것은 대단히 감사합니다. 예, 우분투 14.04에서 테스트했습니다
hek2mgl

11

으로 mklement0 점 밖으로 , 모든 메이크 목표를 나열하는 기능은 GNU-메이크업에서 누락되고, 그의 대답하고 다른 사람이 작업을 수행하는 방법을 제공합니다.

그러나, 원래의 게시물도 언급 레이크 누구의 작업 전환 바로 rakefile에서 모든 작업을 나열보다 약간 다른 무언가를합니다. Rake는 관련 설명이있는 작업 목록 만 제공합니다. 설명 이없는 작업 은 표시되지 않습니다 . 이를 통해 저자는 사용자 정의 된 도움말 설명을 제공하고 특정 대상에 대한 도움말을 생략 할 수 있습니다.

각 대상에 대한 설명을 제공하는 레이크의 동작을 에뮬레이션하려면 간단한 방법이 있습니다. 설명하려는 각 대상에 대한 설명에 설명을 포함시킵니다.

다음과 같이 대상 옆에 설명을 넣거나 종종 대상 위의 PHONY 사양 옆에 설명을 넣을 수 있습니다.

.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

어느 것이 생산할 것인가

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

...
help                Generate list of targets with descriptions

이 요지여기 에서도 짧은 코드 예제를 찾을 수 있습니다 .

다시 말하지만, 모든 대상을 Makefile에 나열하는 문제는 해결되지 않습니다. 예를 들어, 생성되었거나 다른 사람이 작성한 큰 Makefile이 있고 대상을 파지 않고 대상을 빠르게 나열하는 방법을 원한다면 도움이되지 않습니다.

그러나 Makefile을 작성 중이고 일관된 자체 문서화 방식으로 도움말 텍스트를 생성하는 방법을 원하는 경우이 기술이 유용 할 수 있습니다.


이것은 훌륭한 기술입니다-훌륭하고 간단하지만 설명도 제공합니다!
Brian Burns

훌륭한 기술. 이 echo명령을 명령 설명 ( stackoverflow.com/a/52059487/814145 ) 으로 사용하도록 약간 수정했습니다 .
Penghe Geng

@PengheGeng 게시물 주셔서 감사합니다. 나는 @echo "Target 1""설명 에코 명령"이 아니라 단지 자리 표시 자임 을 분명히하고 싶습니다 . 생성 된 도움말 텍스트가에서 제공되지 않습니다 @echo. 실제 Makefile에서 이것들 echo은 빌드 명령 또는 그와 같은 것으로 대체됩니다. 글을 더 명확하게하기 위해 글을 편집하겠습니다.
jsp

4

@nobar의 답변탭 완성을 사용하여 makefile의 대상을 나열하는 방법을 보여줍니다 .

  • 기본적 으로이 기능을 제공하는 플랫폼 (예 : Debian, Fedora )에 적합합니다.

  • 다른 플랫폼 (예 : Ubuntu ) 에서는 에서는 @ hek2mgl의 답변에 의해 암시 된 것처럼이 기능을 명시 적으로로드 .

    • . /etc/bash_completion 에 대한 기능을 포함하여 여러 탭 완성 기능을 설치합니다. make
    • 또는 다음에 대한 탭 완성 설치하려면 다음을 수행 하십시오 make.
      • . /usr/share/bash-completion/completions/make
  • 들어 모두에서이 기능을 제공하지 않는 플랫폼 등, OSX , 당신은 할 수 있습니다 다음 명령을 소스 (에서 adapated 여기 )를 구현하는 :
_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
  • 참고 : 이것은 Linux 배포판과 함께 제공되는 탭 완성 기능만큼 정교하지는 않습니다. 특히 명령 줄이로 다른 makefile을 대상으로하는 경우에도 항상 현재 디렉토리 의 makefile을 대상으로합니다 -f <file>.

4

내가 가장 좋아하는 답변은 Chris Down 님 이 Unix & Linux Stack Exchange 에 게시 한 것 입니다. 인용하겠습니다.

이것은 bash 완성 모듈 make이 목록 을 얻는 방법입니다 .

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

페이징없이 줄 바꿈으로 구분 된 대상 목록을 인쇄합니다.

사용자 Brainstone 은 파이핑을 sort -u통해 중복 항목을 제거 할 것을 제안 합니다.

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

출처 : make의 모든 대상을 나열하는 방법은 무엇입니까? (유닉스 및 리눅스 SE)


4

make 대상을 설명하고 깨끗한 결과물을 얻는 쉬운 구문에 중점을 두어이 접근법을 선택했습니다.

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:

위의 내용을 Makefile로 취급하고 실행하면 다음과 같은 결과가 나타납니다.

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

명령 체인에 대한 설명 :


아주 좋은 해결책. 나는 이것을 몇 년 동안 사용했습니다 : 이전 awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort ##목표와 같은 줄에 주석이 있습니다. 그러나 귀하의 솔루션이 가독성 전에 허용한다고 생각합니다.
thoroc

grep: parentheses not balanced내 OSX 10.15 시스템 에서 처음 두 줄로 구성된 makefile이보고 됩니다.
Malcolm Crum

@Crummy 죄송합니다, 제 실수입니다. 지적 해 주셔서 감사합니다. 고쳤다. 변수 이름을 시작하지 않아야하는 달러 기호를 피해야합니다.
Richard Kiefer

위의 코드 섹션을 표시 할 때 StackOverflow가 탭을 공백으로 변환하지만 Makefile에는 탭이 필요합니다. 게시물을 편집 한 다음 섹션을 복사하여 탭이 유지되도록 할 수 있습니다.
Richard Kiefer

2

여기에는 많은 실행 가능한 솔루션이 있지만 "한 번 해 볼만한 가치가 있다면 다시 해 볼 가치가 있습니다"라고 말하고 싶습니다. (tab) (tab)을 사용하도록 sugestion을 상향 조정했지만 일부는 언급했듯이 완료 지원이 없거나 포함 파일이 많은 경우 대상이 정의 된 위치를 더 쉽게 알 수 있습니다.

하위 메이크로 아래를 테스트하지 않았습니다 ... 작동하지 않을 것이라고 생각합니다. 아시다시피 재귀는 유해한 것으로 간주됩니다.

.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 := \)

내가 좋아하는 것 :

  • 포함 파일별로 대상을 나열하십시오.
  • 원시 동적 대상 정의 출력 (변수 구분 기호를 모듈러스로 대체)
  • 각 줄을 새 줄에 출력
  • 더 명확 해 보인다 (주관적인 의견)

설명:

  • MAKEFILE_LIST의 foreach 파일
  • 파일 이름을 출력
  • 들여 쓰기되지 않고 주석이없고 마침표로 시작하지 않는 콜론을 포함하는 grep 행
  • 즉시 할당 표현식 제외 (: =)
  • 규칙 종속 항목 잘라 내기, 정렬, 들여 쓰기 및 잘라 내기 (콜론 이후)
  • 확장을 방지하기 위해 가변 변수 구분 기호

샘플 출력 :

 = 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

1

make 타겟에 필요한 빌드 대상 (및 해당 종속성)을보고 싶었 기 때문에 이것이 도움이되었습니다. 타겟을 '.'으로 시작할 수 없다는 것을 알고 있습니다. 캐릭터. 지원되는 언어가 무엇인지 모르므로 egrep의 대괄호 식을 사용했습니다.

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

1

이것은 깨끗하지는 않지만 일을했습니다.

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

나는 make -p내부 데이터베이스를 버리고, stitch stderr을 사용하고 grep -A 100000, 출력의 바닥을 유지하기 위해 빠르고 더러운 것을 사용합니다 . 그런 다음 두 개의 출력으로 출력을 정리 grep -v하고 마지막으로 cut콜론 이전의 대상, 즉 대상을 얻는 데 사용 합니다.

이것은 대부분의 Makefile에있는 도우미 스크립트에 충분합니다.

편집 : grep -v Makefile내부 규칙 추가


1

이것은 jsp 의 매우 유용한 답변 ( https://stackoverflow.com/a/45843594/814145 )에 대한 수정 입니다. 목표 목록뿐만 아니라 설명도 얻는 아이디어가 마음에 듭니다. jsp 의 Makefile은 설명을 주석으로 표시하며, 종종 대상의 description echo 명령에서 반복되는 것으로 나타났습니다. 대신 각 대상의 echo 명령에서 설명을 추출합니다.

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

출력 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

노트:

  • jsp 와 동일 의 대답 만 가짜 목표는 나열 될 수있는 수도 있고 수도 귀하의 경우에하지 작업
  • 또한 레시피의 첫 번째 명령으로 echo또는 :명령 이있는 PHONY 대상 만 나열합니다 . :"아무것도하지 마십시오"를 의미합니다. 에코가 필요하지 않은 대상을 위해 여기에 사용합니다.all위의 대상 .
  • help대상이 make help출력 에 ":"을 추가 하는 추가 트릭 이 있습니다 .

0

위의 또 다른 추가 답변.

터미널에서 cat 및 awk 만 사용하여 MacOSX에서 테스트

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

아래와 같이 make 파일을 출력합니다 :

대상 1

대상 2

target3

Makefile에서 동일한 명령문이어야하며 $ variable 대신 $$ variable을 사용하여 변수를 이스케이프해야합니다.

설명

고양이 -내용을 뱉어

| -파이프는 다음 awk로 출력을 구문 분석합니다.

awk- "shell"을 제외하고 "Az"행만 허용하는 정규식을 실행 한 다음 첫 번째 $ 1 열을 인쇄합니다.

awk- 목록에서 마지막 문자 ":"를 다시 제거합니다.

이것은 거친 출력이며 AWK로 더 펑키 한 일을 할 수 있습니다. ss가 BSD 변형에서 일관되지 않기 때문에 sed를 피하십시오. 즉 일부는 * nix에서 작동하지만 MacOSX와 같은 BSD에서는 실패합니다.

"make tab tab "을 의미하는 make , 기본 bash-completion 폴더 /usr/local/etc/bash-completion.d/에 파일을 수정하여 추가 할 수 있어야합니다 . 하나의 라이너 스크립트를 기반으로합니다.


cat 대신 make -qp를 사용할 수도 있습니다. 따라서 make -qp | awk '/ : / &&! / : = / && / ^ [Az] / &&! / PATH / &&! / DISPLAY / &&! / TERM_SESSION / &&! / USER_TEXT_ENCODING / &&! / Makefile / {print substr ($ 0, 1 , 길이 ($ 0) -1) | "sort -u"} '
Jimmy MG Lim

0

나는 보통 :

grep install_targets Makefile

다음과 같이 다시 나타납니다.

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

이게 도움이 되길 바란다


0

배쉬 스크립트

위의bash @ cibercitizen1의 의견에 따라이 작업을 수행하는 매우 간단한 방법이 있습니다 .

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

@ Marc.2377 의 더 권위있는 답변 도 참조하십시오 make.


-4

이전 답변이 왜 그렇게 복잡한 지 잘 모르겠습니다.

list:
    cat Makefile | grep "^[A-z]" | awk '{print $$1}' | sed "s/://g" 

8
이전의 대답은 그것이 당신의 대답이 적용되지 않는 모든 시나리오를 다루고 있기 때문에 그렇게 복잡 :를 통해 정의 된 목표의 (a)에 포함 변수 (예를 들어, $(SHELLS): ...), (b)는 숫자로 시작 목표, (C)의 포함 비 변수 정의 포함 , (d) make명시 적 makefile 경로로 지정된 경우 적절한 makefile을 대상 으로합니다. (a)는 중요한 결점입니다. 올바른 makefile 을 안정적으로 대상으로 지정하더라도 변수 확장 부족으로 인해 원시 파일을 구문 분석하는 것은 일반적인 경우에는 작동하지 않습니다.
mklement0

6
제쳐두고, 복잡한 : 당신의 명령은 다음과 같이 단순화 할 수 있습니다-그러나 요점은 충분히 강력하지 않다는 것입니다 : awk -F: '/^[A-z]/ {print $$1}' Makefile. 마지막으로 큰 학문적 요점 : [A-z]보다는 사용 하는 것은 [:alpha:]과 같은 외국 문자로 시작하는 목표를 놓치게된다는 것을 의미합니다 á.
mklement0

@ mklement0 첫 번째 awk 명령은 훌륭하게 작동하며 지금까지 가장 간단하지만 [: alpha :]를 사용하면 어떤 이유로 든 중단되는 것처럼 보입니다. 테스트 파일에서 일부 대상이 누락되었습니다.
Brian Burns

@ bburns.km : 내 나쁜 : 나는 말했다해야 [[:alpha:]]보다는 [:alpha:]( [:alpha:]문자의 로케일 인식 세트 나타내는 내부 문자 클래스 ( [...])에 따라서 효과가 필요 더블 [[ /를 ]].
mklement0

4
답변 왜 그렇게 복잡합니까? 이 짧은 발췌 문장에서 쓸모없는 죄를 몇 가지 모아서 관리 할 수 있습니다. awk -F: '/^[A-Za-z]/ { print $$1 }' Makefile단일 프로세스를 사용하고 더 정확한 정규 표현식을 사용합니다 (물론 이전 주석에서 언급했듯이 밑줄, 숫자 등으로 대상을 가질 수는 있지만).
tripleee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.