28.7.1.2. uORB 메시지 생성 스크립트 빌드 과정 및 의존 모듈(Dependency) 갱신 절차

28.7.1.2. uORB 메시지 생성 스크립트 빌드 과정 및 의존 모듈(Dependency) 갱신 절차

PX4-Autopilot의 커스텀 비행 모드 추가 시, VehicleStatus.msg 파일 안에 새로운 NAVIGATION_STATE_CUSTOM_XXX 상수를 정의했다면 그다음으로 반드시 거쳐야 하는 관문이 있다. 바로 uORB 메시지 헤더 파일 자동 생성(Generation) 및 컴파일 의존성(Dependency) 갱신 과정이다.

PX4 빌드 시스템은 .msg 텍스트 파일을 곧바로 C++ 코드로 인식하지 않는다. 중간에 파이썬(Python) 기반의 파싱 스크립트를 거쳐 .msg 파일을 .h.c/.cpp 소스 코드로 변환해 내는 일련의 툴체인(Toolchain) 파이프라인이 존재한다. 본 절에서는 이 빌드 파이프라인의 내부 동작 원리를 파헤친다.


1. msg 디렉토리와 CMake의 만남

PX4 소스 코드 트리의 루트 디렉토리 산하 msg/ 폴더 안에는 수백 개의 *.msg 파일들이 들어있다.
컴파일러(GCC/Clang) 구동 전에 CMake가 가장 먼저 하는 일은, msg/CMakeLists.txt 파일에 명시된 메시지 리스트를 스캔하는 것이다.

CMakeLists.txt 안에는 다음과 같은 블록이 존재하며, 빌드 시스템은 이 블록에 등록된 메시지만을 컴파일 대상으로 삼는다.

# msg/CMakeLists.txt 내부 발췌 예시
set(msg_files
	ActuatorArmed.msg
	ActuatorControls.msg
	# ... (중략) ...
	VehicleStatus.msg
	# ... (후략) ...
)

만약 기존 파일인 VehicleStatus.msg 내부의 줄반올림(Line) 하나를 수정했다면 CMake 리스트를 수정할 필요는 없다. CMake는 파일의 타임스탬프(수정 시간)가 갱신된 것을 확인하고 오직 변경사항이 발생한 메시지만을 타겟으로 재생성(Re-generation) 파이프라인을 가동한다.


2. genmsg 파이썬 스크립트 기반 코드 제너레이션(Generation)

CMake가 메시지의 변경을 감지하면, 백그라운드에서 msg/tools/uorb_generate_messages.py (또는 genmsg 도구 모음) 파이썬 스크립트를 호출한다. 이 스크립트는 매우 정교한 텍스트 파서(Text Parser) 로직을 담고 있다.

2.1 파싱 및 자료형 치환 (Parsing & Type Mapping)

파이썬 스크립트는 VehicleStatus.msg 내부의 텍스트를 한 줄 한 줄 읽어 내려간다.

  • uint8 NAVIGATION_STATE_CUSTOM_FOO = 22 라는 줄을 만나면, uint8 문자열을 C/C++ 표준 자료형인 uint8_t로 치환한다.
  • 변수명과 숫자 22를 추출하여, C++ 매크로 상수 문법으로 포맷팅(Formatting)한다.

2.2 결과물(.h 파일)의 산출

위 과정을 거치고 나면 빌드 결과물 폴더 안에 vehicle_status.h 라는 헤더 파일이 탄생한다.
(보통 build/px4_fmu-vX_default/uORB/topics/vehicle_status.h 경로에 위치)

/* 파이썬 스크립트에 의해 자동 생성된 C++ 헤더 코드 (부분 발췌) */
#pragma once
#include <uORB/uORB.h>

#ifdef __cplusplus
struct __EXPORT vehicle_status_s {
#else
struct vehicle_status_s {
#endif
	// ... (다른 변수 및 상수들) ...
	static constexpr uint8_t NAVIGATION_STATE_CUSTOM_FOO = 22;
	uint8_t nav_state;
	// ... (후략) ...
};

이렇게 생성된 헤더 코드는 객체 지향적으로 완벽하게 래핑(Wrapping)되어, 비로소 PX4 내부의 모든 C++ 소스 파일들이 #include "uORB/topics/vehicle_status.h" 로 불러와 쓸 수 있는 상태가 된다.


3. 의존 모듈(Dependency)의 연쇄 컴파일 (Cascade Recompilation)

프로그래밍에서 헤더(*.h) 파일이 수정되었다는 것은, 이 헤더를 include 하고 있는 모든 *.cpp 파일들을 문법적으로 다시 검사하고 기계어로 번역해야 함(Re-compile)을 의미한다.

vehicle_status.msg는 PX4 시스템 내에서 시스템의 심장 박동과도 같은 데이터이므로 의존성(Dependency)이 어마어마하게 넓게 퍼져있다. 즉, 이 메시지 안의 상수 번호 하나를 추가했을 뿐이지만 시스템은 다음과 같은 핵심 모듈들을 모조리 연쇄적으로 재컴파일한다.

  • src/modules/commander/: 기체의 전체 상태 머신을 통제하므로 제일 먼저 재조립된다.
  • src/modules/flight_mode_manager/: 커스텀 모드를 스위칭해 줄 책임이 있으므로 다시 컴파일된다.
  • src/modules/mavlink/: 기체의 상태를 GCS로 전송하기 위해 직렬화 코드를 다시 짠다.
  • src/modules/logger/: 나중에 비행 로그(*.ulg)를 파싱할 때 이 상수를 남겨야 하므로 영향을 받는다.

이러한 연쇄 갱신 과정(Cascade Re-linking) 덕분에 PX4 시스템은 개발자의 실수로 인한 상수 충돌이나 누락을 빌드 타임 단계에서 완벽하게 걸러내어, 비행 중 발생할 수 있는 메모리 참조(Segfault) 에러를 원천적으로 방지해 내는 철벽같은 안전망을 구성하고 있다.


4. 빌드 후 클린(Clean) 규칙

간혹 메시지를 수정했는데도 파이썬 캐시(Cache)나 CMake의 의존성 추적기 버그로 인해, 코드는 수정되었으나 예전 헤더 파일이 그대로 쓰이는 링커 오류(Linker Error)가 발생할 수 있다.

이를 방지하기 위해 .msg 파일을 수정한 직후에는 반드시 빌드 캐시를 초기화(Clean) 해 주는 것이 강력히 권장된다.

# PX4 명령어 환경에서의 클린 빌드 수행
make clean
make px4_fmu-vX_default

클린(Clean) 명령이 하달되면 이전 빌드 과정에서 생성되었던 uORB/topics/*.h 파일들이 일괄 삭제되며, genmsg 파이썬 스크립트가 완전히 백지상태에서 새로운 상수를 긁어모아 최상위 무결성을 지닌 헤더 파일 세트를 재생성하게 된다.