문제
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가 작성되었습니다 .java
c
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_GRAPH
1로 설정 하면 다음 과 같이 출력됩니다.
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 $@)
make
이 touch $@
부분은 이전 줄의 에코 의 일부일 뿐이라고 생각합니다 .
Building target foobar.txt touch foobar.txt
나는 이전 행에 후행 백 슬래시 떨어져두면 make
불평 *** unterminated call to function
‘전화 :없는 )'. Stop.
사람이하는 방법에 대한 아이디어가 있으면 make
좋은 플레이가, 나는 모든 귀 해요. 🙂
편집 :이 접근법의 다른 문제는 빌드 결과가 아직 존재 make
하지 않는 경우에만 작동한다는 것 입니다. 최신으로 간주되는 대상의 빌드 레시피를 실행하지 않기 때문입니다.
답변
I 사용 –profile 개작 (드롭에 대한 대체 make
), 그것은 callgrind 형식의 종속성 트리를 생성.
그러면 gprof2dot 는 대상 트리의 이미지를 생성 할 수 있습니다.