25.1.2 빌드 시점 및 런타임 관점의 의존성 태그 분할 원리
ROS 2의 소프트웨어 컴포넌트는 소스 코드가 어셈블리와 목적 코드(Object code)로 번역되는 컴파일레이션 타임(Compilation Time, 즉 빌드 시점)과, 최종 생성된 바이너리 이미지나 스크립트가 운영체제 메모리에 적재되어 프로세스로 인스턴스화되는 런타임(Run-time) 공간으로 생명 주기가 명확히 이분화되어 있다. 이 두 가지 시점에서 요구되는 시스템 디펜던시의 성질은 근본적으로 다르다. package.xml의 Format 3 스키마는 이러한 컴퓨팅 자원 요구의 시점(Timing) 차이를 반영하여 의존성 태그를 학술적으로 분할하고 통제한다.
1. 컴파일 파이프라인과 <build_depend> 메커니즘
<build_depend> 태그는 패키지의 빌드 페이즈(Build Phase)에서만 독점적으로 요구되는 종속성을 명시한다. C++ 기반의 ROS 2 노드를 개발할 때, 컴파일러(예: GCC, Clang)는 소스 파일(.cpp)을 전처리(Preprocessing)하고 구문 분석하는 과정에서 외부 패키지의 구조체, 클래스, 매크로 선언을 인지해야 한다.
이때 <build_depend>로 선언된 타겟 패키지는 다음과 같은 필수 빌드 자원을 현재 패키지의 빌드 컨텍스트에 공급한다.
- 헤더 파일 인클루드 경로 (Include Paths): 전처리기가
#include디렉티브를 해소할 수 있도록rclcpp,std_msgs등의 헤더 파일 위치를 노출한다. - 정적 링킹 스텁 (Static Linking Stubs): 공유 라이브러리의 컴파일 타임 링킹을 위한 링커(Linker) 스코프 자원을 제공한다.
중요한 점은, 이 종속성은 소스코드가 바이너리로 변환된 이후의 런타임 단계에서는 더 이상 시스템 메모리에 존재할 필요가 없다는 것이다. (단, 동적 লাই브러리는 예외이다.)
2. 프로세스 메모리 적재와 <exec_depend> 메커니즘
반면 <exec_depend> (Execution Dependency) 태그는 컴파일러의 해석 과정에는 전혀 관여하지 않으나, 생성된 실행 파일(Executable)이나 런치 파이프라인이 런타임에 진입할 때 운영체제의 동적 링커/로더(예: ld.so)가 요구하는 런타임 종속성을 정의한다.
주요 특징은 다음과 같다.
- 동적 공유 라이브러리(Dynamic Shared Libraries): 프로세스가 구동 중에 호출할 비동기 함수들이 담긴
.so(Linux) 바이너리 공간을 확보한다. - 인터프리터 및 스크립트 종속성: Python으로 작성된 노드의 경우, 사전 컴파일 없이 런타임에 소스를 실시간 해석하므로 의존하는 타 파이썬 모듈이 반드시
<exec_depend>로 선언되어야 한다. - 런치 및 리소스 (Launch & Resources): 시뮬레이터 구동을 위한 URDF 모델, 콜라이더 메쉬 다각형 자원, YAML 파라미터 파일, 또는 컴포지트 노드를 로드하기 위한
launch시스템 구성 요소들이 이에 해당한다.
3. 의존성 전이성(Transitivity)과 <build_export_depend>
시스템의 고도화된 모듈화 설계 징후는 의존성의 전이성(Transitivity)에서 나타난다. 특정 패키지 A가 패키지 B를 구현하기 위한 의존성을 가질 뿐만 아니라, 패키지 A 자신이 외부(패키지 C)로 노출(Export)하는 자체 헤더 파일 내부에서 패키지 B의 타입(Type)을 참조하고 있을 경우가 존재한다. 이 경우 패키지 C는 패키지 A를 종속하기만 해도 컴파일러는 패키지 B의 존재를 요구하게 된다.
이러한 전이적 헤더 노출 문제를 해결하기 위해 <build_export_depend> 태그가 사용된다. 이는 본 패키지를 빌드 시점으로 종속하는 다운스트림(Downstream) 패키지들에게 특정 의존성을 강제적으로 전달(Pass-through)하는 역할을 수행한다.
결과적으로 ROS 2 시스템은 이 세분화된 태그(build_depend, exec_depend, build_export_depend)를 통해 의존성 트리를 최소화하여 불필요한 재빌드 오버헤드를 줄인다. 개발자가 이 세 가지 속성이 모두 교집합을 이룰 때에 한해서 포괄적 태그인 <depend>를 제한적으로 사용하여 매니페스트를 간소화(Simplicity)할 수 있는 수학적 메커니즘을 제공한다. (참고 버전: REP-149, ROS 2 Humble/Jazzy)