Chapter 25. CMakeLists.txt 및 package.xml 의존성 선언의 학제적 이해
ROS 2의 분산 컴포넌트 아키텍처는 개별 소프트웨어 모듈을 독립적인 패키지로 캡슐화(Encapsulation)하여 개발, 배포, 그리고 통합의 효율성을 극대화한다. 이러한 패키지 기반 아키텍처가 논리적으로 결합되고 물리적으로 컴파일되기 위해서는 패키지 간의 의존 관계가 시스템적으로 명확하게 파악되어야 한다. 이를 위해 ROS 2 패키징의 표준 규격인 ament 빌드 시스템은 선언적 메타데이터 명세 기법과 동적 링킹 파이프라인 지시자를 통해 의존성을 통제한다. 그 중심 요소가 바로 매니페스트 파일인 package.xml과 빌드 구성 스크립트인 CMakeLists.txt이다. 본 장에서는 시스템 레벨에서의 두 파일 간 상호 운영 메커니즘을 학제적으로 규명한다.
1. package.xml 기반 패키지 매니페스트 및 정적 의존성 선언
package.xml은 시스템 차원의 패키지 관리자(예: Ubuntu 환경의 apt 및 rosdep)와 ROS 2 메타 빌드 시스템(colcon)에게 패키지의 정체성과 요구 환경을 고지하는 Extensible Markup Language 기반의 정적 매니페스트이다. 패키지의 물리적 구조가 어떻게 설계되어 있든 간에, 시스템은 우선적으로 package.xml을 파싱(Parsing)하여 다음과 같은 필수 정보와 제약 조건을 수집한다.
Colcon과 rosdep은 이 파일에 명시된 태그를 해독하여 시스템 레벨의 종속성 그래프(Dependency Graph)를 메모리 상에 구축한다.
<buildtool_depend>: 호스트 환경에서 대상 패키지를 컴파일하기 위해 기초적으로 구동되어야 하는 빌드 프레임워크(예:ament_cmake)를 지정한다.<build_depend>: 목적 코드(Object Code) 생성 이전에 헤더(Header) 파일이나 라이브러리의 링킹 심볼 스텁(Stub) 등을 참조하기 위해 요구되는 C++ 및 System 컴파일 타임 의존성을 규정한다.<exec_depend>: 실행 파일(Executable Binary) 코드가 런타임(Runtime) 시점에 동적 로딩 또는 파이썬 인터프리터를 통한 스크립트 실행 과정에서 필요로 하는 공유 라이브러리(.so 파일) 패키지를 명시한다.<depend>: 빌드, 런타임, 익스포트 파이프라인 전반에 걸쳐 공통적으로 종속되는 핵심 패키지 요소(예:rclcpp,std_msgs)를 선언하여 간결성을 도모하는 포괄적 태그이다.
특히 이 선언적 언어 구조는 빌드 스케줄러가 패키지들의 방향성 비순환 그래프(DAG, Directed Acyclic Graph)를 도출하는 1차적 수단이 되며, 이를 바탕으로 병렬 컴파일의 안전한 위상 정렬(Topological Sorting) 순서가 보장된다.
2. CMakeLists.txt 기반 동적 컴파일 및 바인딩 파이프라인 지시
package.xml이 시스템 레벨의 거시적 종속성을 정의한다면, CMakeLists.txt는 해당 종속성들이 실제 컴파일러 파이프라인에서 어떻게 소비(Consume)되고 바인딩(Binding)되는지를 지시하는 미시적 절차서이다. Ament 메타 빌드 시스템 설계 하에서 CMake는 C++ 코드를 빌드 타겟으로 삼아 시스템에 통합하는 동력원이다.
CMakeLists.txt 내부적으로는 find_package() 함수 호출을 통하여 package.xml에 명시된 소프트웨어 패키지들을 CMake 환경 내의 타겟 모듈로 로드(Load)한다. 이후, 패키지 빌드의 구체적 행위 양식은 다음과 같이 기술된다.
- 타겟 선언 (Target Declaration):
add_executable()이나add_library()를 통해 소스 파일들을 컴파일 대상의 결과물인 실행 파일이나 라이브러리 타겟(Target) 객체로 정의한다. - 의존성 연결 (Dependency Linkage):
ament_target_dependencies()매크로를 주입하여 선언된 타겟 객체가find_package()를 통해 로드한 외부 ROS 패키지의 헤더 파일의 인클루드 경로 자원과 라이브러리 바이너리 자원을 타겟 스코프(Scope)에 주입한다. - 가시성 익스포트 (Visibility Exporting): 빌드 산출물이 다시 다른 상위 계층의 패키지에게 소비될 수 있도록
ament_export_dependencies()및ament_package()매크로를 사용하여 자신의 메타 정보와 라이브러리를 ament 인덱스 체계 내에 노출(Export)시킨다.
이와 같이 package.xml의 추상적인 자원 요구 사항과 CMakeLists.txt의 구체적인 자원 사용 및 노출 명세가 긴밀히 맞물림으로써, ROS 2 빌드 과정은 외부 환경 파편화에 관계없이 고도의 모듈화 전략을 일관성 있게 집행할 수 있다. (참고 버전: ROS 2 Humble/Jazzy, CMake 3.16 이상)