23.3.1 매니페스트 XML 파싱에 의한 위상 정렬 의존성 그래프 추출 프로세스
거대한 워크스페이스 내에 다수의 ROS2 컴포넌트가 혼재하는 상황에서, 어떠한 순서로 패키지들을 컴파일할 것인지 결정하는 메커니즘은 시스템 빌드 생태계의 신뢰성을 담보하는 가장 중요한 과정이다. 패키지 A가 패키지 B의 인터페이스를 참조한다면, 패키지 B가 먼저 컴파일되어 링커에 노출되어야만 문법적 오류(Syntax Error)를 단절할 수 있다. Ament 툴체인(및 이를 활용하는 Colcon)은 각 패키지의 package.xml을 추출하여 다차원적인 의존성 그래프(Dependency Graph)를 메모리 상에 구축함으로써 이 문제를 수학적으로 해결한다.
1. 매니페스트 기반 메타데이터 모델 추상화
빌드 도구는 워크스페이스를 순회(Traversal)하며 최상위 디렉터리 경로에 존재하는 파일 트리에서 package.xml 파일들을 전수 조사한다. 각 파일이 발견될 때마다 내부 XML 구문 분석기(Parser)가 기동하여 DOM(Document Object Model) 트리를 탐색한다.
수많은 XML 태그 중 빌드 체인이 가장 우선순위에 두는 것은 의존성 속성을 나타내는 태그 집합(build_depend, exec_depend, buildtool_depend 등)이다. 파서는 이 태그들의 내부 Text 값을 읽어 패키지 객체(Package Object)의 의존성 리스트(List) 변수에 할당한다. 이 단계가 만료되면, 툴체인은 시스템 내에 존재하는 모든 패키지의 명칭과 그들이 요구하는 종속 관계 정보를 1차원 데이터로서 확보하게 된다.
2. 방향성 비순환 그래프(DAG) 구조 모델링
1차원으로 나열된 의존성 데이터 리스트만으로는 빌드 순서를 계층적으로 산출할 수 없다. 이를 해소하기 위해 툴체인은 추출된 데이터를 기반으로 방향성 비순환 그래프(Directed Acyclic Graph, DAG)를 수학적으로 모델링한다.
그래프 이론(Graph Theory)적 관점에서 접근할 때, 각각의 ROS2 패키지는 하나의 노드(Vertex)로 규정된다. 패키지 A가 package.xml을 통해 패키지 B에 대한 build_depend를 선언했다면, 이는 패키지 B에서 패키지 A로 향하는 유향 간선(Directed Edge)으로 정의된다. 즉, 빌드의 흐름과 시맨틱(Semantic) 의존성의 방향이 그래프 모델의 코어 로직으로 바인딩되는 것이다.
3. 위상 정렬(Topological Sorting)을 통한 빌드 파이프라인 전개
구성된 DAG 모델을 선형적(Linear)인 컴파일 순서, 즉 파이프라인 대기열로 치환하는 연산은 위상 정렬(Topological Sorting) 알고리즘을 통해 수행된다.
내부 엔진은 주로 역방향 깊이 우선 탐색(DFS, Depth First Search) 또는 큐(Queue) 기반의 칸 알고리즘(Kahn’s Algorithm)을 병용한다. 그래프 내에서 자신에게 들어오는 간선(진입 차수, In-degree)이 ’0’인 노드를 먼저 탐색한다. 진입 차수가 ’0’이라는 것은 어떠한 외부 패키지에도 의존하지 않는 독립적인 모듈임을 의미하므로, 이를 최우선 빌드 타겟(Leaf level target)으로 대기열에 삽입한다.
이후 해당 노드에서 출발하는 모든 유향 간선을 그래프에서 소거하고, 새롭게 진입 차수가 ’0’이 된 노드들을 다음 빌드 큐에 배정하는 연산을 노드가 소진될 때까지 재귀적으로 반복한다. 이를 통해 빌드 시스템은 타겟 간의 의존성 계층 수준(Dependency level)을 완벽히 정렬한다.
4. 순환 참조(Circular Dependency) 탐지 및 오류 제어 메커니즘
위상 정렬 프로세스는 오직 그래프가 ‘비순환(Acyclic)’ 구조를 가질 때만 정상 작동한다. 만일 A 노드가 B 노드를 요구하고, B 노드가 다시 A 노드를 요구하는 순환 참조(Circular Dependency)가 package.xml 설계 결함에 의해 발생했다면, 진입 차수가 ’0’이 되는 노드를 더 이상 찾을 수 없는 교착 상태(Deadlock)에 직면하게 된다.
Ament 파서는 이러한 무한 루프 상태를 위상 정렬 알고리즘 단계에서 즉시 탐지한다. 아직 대기열에 배정되지 않은 잔여 노드가 존재함에도 연산이 멈출 경우, 순환 참조 오류(Fatal Exception)를 터미널 표준 에러(stderr) 스트림으로 출력하고 파이프라인 전체를 강제 중지시킴으로써 시스템 메모리 마비 및 비정상 빌드를 선제적으로 회피하는 강력한 무결성 제어를 수행한다.