[makefile] 정의에 변수를 포함하는 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]}"'