makefile에 주어진 의존성을 트리로 표시하는 방법은 무엇입니까? 구문 분석 할 수있는 프로그램을 찾고 트리와

문제

makefile의 하나 이상의 대상에 대한 종속성을보고 싶습니다. 그래서 makefile을 구문 분석 할 수있는 프로그램을 찾고 트리와 같은 형식 (들여 쓰기, 아트 아트, …) 또는 그래프 (점, …)로 종속성을 나타냅니다.

비슷한

다른 상황에서이를 수행하는 프로그램이 있습니다.

  • pactree 또는 빚은 ascii 형식 또는 dot그래프 와 같은 트리의 각 형식으로 소프트웨어 패키지에 대한 종속성을 표시 할 수 있습니다 .
  • gcc -M source_file.c C 소스 파일의 종속성을 작성 규칙으로 표시합니다.
  • pstree 는 프로세스 트리의 ASCII 표현을 표시합니다.

진행

웹을 검색하면 도움이 거의 없습니다 . 그게 나를 시도하게

make --always-make --silent --dry-run some_target | \
  grep --extended-regexp 'Considering target file|Trying rule prerequisite'

그러나 이것을 멋진 트리 / 그래프로 표현하기 위해 펄이나 파이썬에서 더 많은 파싱 코드를 해킹 해야하는 것처럼 보입니다. 그리고 나는이 방법으로 완전하고 정확한 그래프를 얻을 수 있는지 아직 모른다.

요구 사항

그래프를 어떤 방식 으로든 제한하는 것이 좋을 것입니다 (내장 규칙, 주어진 대상, 깊이 만). 대부분의 경우, 나는 “합리적”인 인간의 의존성을 줄 도구를 찾고 있습니다. -시청 가능한 형식 (예 : “유사한”의 프로그램).

질문

  • 이를 수행 할 수있는 프로그램이 있습니까?
  • 전체 정보와 정확한 정보를 얻을 수 make -dnq ...있습니까?
  • 이 정보를 얻는 더 좋은 방법이 있습니까?
  • 이 정보를 파싱하려는 스크립트 / 시도가 이미 존재합니까?


답변

같은 저자의 makefile2graph 를 사용해보십시오 . 대신 비슷한 도구 MakeGraphDependencies가 작성되었습니다 .javac

make -Bnd | make2graph | dot -Tsvg -o out.svg

그런 다음 벡터 그래픽 편집기를 사용하여 필요한 연결을 강조 표시하십시오.


답변

나는 어떤 전제 조건에 따라 어떤 대상이 어떤 목표에 따라 명확하게 구조화 된 정보를 출력하는 일종의 해킹을 발견했습니다. 단점은 상당히 방해가된다는 것입니다. 즉, 모든 대상의 빌드 레시피를 작은 조건부 함수로 랩핑하도록 makefile을 변경해야합니다. 간단한 예를 게시하겠습니다.

getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))


VARIABLE_TARGET_NAME = foobar.txt

all : TopLevelTarget

TopLevelTarget : Target_A Target_D
    $(call getRecipe,\
        @echo Building target $@)

Target_A : Target_B
    $(call getRecipe,\
        @echo Building target $@)

Target_D : Target_C
    $(call getRecipe,\
        @echo Building target $@)

Target_B : $(VARIABLE_TARGET_NAME)
    $(call getRecipe,\
        @echo Building target $@)

Target_C :
    $(call getRecipe,\
        @echo Building target $@)

$(VARIABLE_TARGET_NAME) :
    $(call getRecipe,\
        @echo Building target $@)

이 예제에서는 수동 롤백 getRecipe 함수를 사용하여 각 개별 대상의 레시피를 래핑 한 다음 해당 레시피를 실제로 실행할지 또는 어떤 대상이 구축되고 있는지, 어떤 전제 조건에 의존하는지 간단히 출력할지 결정합니다. 후자는 변수 DEPENDENCY_GRAPH가 설정된 경우에만 발생합니다 (예 : 환경 변수). 이 예제에서 빌드 레시피는 대상이 빌드되고 있다는 에코에 지나지 않지만, 선택한 명령으로이를 대체 할 수 있습니다.

DEPENDENCY_GRAPH1로 설정 하면 다음 과 같이 출력됩니다.

Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"

구문 분석하고 도트 그래프로 변환하기에 충분히 쉬워야합니다.

으로 DEPENDENCY_GRAPH모든 설정 또는 0으로 설정하지, 출력은 :

Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget

즉, 일반 빌드 레시피가 대신 사용됩니다. 복잡한 레시피에서 안정적으로 작동하는지 아직 테스트하지 않았습니다. 내가 이미 겪은 한 가지 문제는 멀티 라인 레시피에서 전혀 작동하지 않는다는 것입니다.

예를 들어, 마지막 대상의 빌드 레시피에서 대상이 빌드되고 있다고 말하는 것 외에도 실제로 touch파일을 원했습니다 .

$(VARIABLE_TARGET_NAME) :
    $(call getRecipe,\
        @echo Building target $@\
        touch $@)

maketouch $@부분은 이전 줄의 에코 의 일부일 뿐이라고 생각합니다 .

Building target foobar.txt touch foobar.txt

나는 이전 행에 후행 백 슬래시 떨어져두면 make불평 *** unterminated call to function‘전화 :없는 )'. Stop.사람이하는 방법에 대한 아이디어가 있으면 make좋은 플레이가, 나는 모든 귀 해요. 🙂

편집 :이 접근법의 다른 문제는 빌드 결과가 아직 존재 make하지 않는 경우에만 작동한다는 것 입니다. 최신으로 간주되는 대상의 빌드 레시피를 실행하지 않기 때문입니다.


답변

I 사용 –profile 개작 (드롭에 대한 대체 make), 그것은 callgrind 형식의 종속성 트리를 생성.

그러면 gprof2dot 는 대상 트리의 이미지를 생성 할 수 있습니다.