[cmake] CMake : 전이 의존성이 어디에서 오는지 어떻게 알 수 있습니까?

자동 종속성 전파와 같은 최신 기능을 사용하기 위해 레거시 CMake 설정을 다시 작성하는 중입니다. (즉 , target_include_directories(<target> PUBLIC <dir>)대신에 같은 것을 사용합니다 include_directories(<dir>).) 현재, 우리는 많은 전역 디렉토리 속성을 설정하여 모든 프로젝트 의존성 정보를 수동으로 처리합니다.

필자의 테스트에서 새 빌드의 대상이 이전 빌드와 달리 라이브러리에 연결되는 몇 가지 예를 찾았습니다. 명시 적으로 연결하지 않으므로 대상의 종속성에서 발생한다는 것을 알고 있지만 찾을 CMakeLists.txt때까지 종속성 계층을 따라 프로젝트의 모든 항목을 재귀 적으로 조사 해야하는 것을 찾기 위해 하나는 문제의 라이브러리를 가져옵니다. 우리는 수십 개의 라이브러리를 가지고 있으므로 사소한 프로세스가 아닙니다.

CMake는 각 대상에 대해 어떤 종속 항목이 명시 적으로 추가되었으며 어떤 대상이 전이 종속 항목을 통해 전파되었는지 확인할 수있는 방법을 제공합니까?

--graphviz출력에 이러한 차이 표시되는 것처럼 보이기 때문에 CMake는 컨텍스트를 내부적으로 잘 알고 있습니다. 그러나 tree명령 줄에 종속성 정보를 표시 하는 비슷한 스크립트 를 작성하고 Graphviz 파일을 구문 분석하는 것은 악몽과 해킹처럼 들립니다.

내가 알 수있는 한이 정보는 포함 cmake-file-api하지 않습니다 . 나는 codemodel/target/dependencies필드가 효과가 있다고 생각 했지만 로컬 및 전 이적 종속성이 함께 혼합되어 나열되어 있습니다. 그리고 backtrace각 종속성 의 필드 는 현재 대상에 대한 add_executable/ add_library호출 에만 연결됩니다 .



답변

dot생성 한 파일 을 구문 분석 graphviz하고 원하는 세부 정보를 추출 할 수 있습니다 . 아래는이를위한 샘플 파이썬 스크립트입니다.

import pydot
import sys

graph = pydot.graph_from_dot_file(sys.argv[1])
result = {}

for g in graph:
    # print(g)
    for node in g.get_node_list():
        if node.get("label") != None:
            result[node.get("label")] = []

    for edge in g.get_edges():
        result[g.get_node(edge.get_source())[0].get("label")].append(g.get_node(edge.get_destination())[0].get("label"))

for r in result:
    print(r+":"+",".join(result[r]))

이 스크립트를 추가하여 cmake에서 사용자 정의 대상으로 실행할 수 있으므로 빌드 시스템에서이를 호출 할 수 있습니다. 여기서 cmake 프로젝트 샘플을 찾을 수 있습니다


답변