21.2. 커스텀 모듈의 빌드 시스템(CMake/Kconfig) 통합 로직 상세

21.2. 커스텀 모듈의 빌드 시스템(CMake/Kconfig) 통합 로직 상세

아무리 기가 막힌 C++ 알고리즘을 짜서 src/modules/custom_app 디렉터리에 던져놓았다고 한들, PX4 펌웨어 빌드 시스템(Build System)이 여러분의 코드를 인지하지 못하면 그것은 그냥 하드디스크 공간을 축내는 무의미한 텍스트 쪼가리에 불과하다.

거대한 PX4 소스 트리를 .px4 확장자를 가진 단 하나의 단단한 바이너리(Firmware)로 구워내는 과정은, 수천 개의 파일과 수백 개의 컴파일 옵션이 뒤엉킨 거대한 컨베이어 벨트와 같다. 이 컨베이어 벨트의 엔진은 CMake이며, 조종간은 Kconfig가 쥐고 있다.

초보 개발자들은 인터넷에 떠도는 CMakeLists.txt 예제를 맹목적으로 복사해 붙여 넣고는, 빌드가 깨지거나 모듈이 NSH 콘솔에서 보이지 않을 때 무엇을 고쳐야 할지 몰라 밤을 새우곤 한다. 이 단원(21.2)은 빌드 에러의 원인을 마법이 아닌 논리로 짚어내기 위한 **‘PX4 빌드 매트릭스 해킹 가이드’**이다.

1. 빌드의 두 축: Kconfig와 CMake

사용자 정의 앱(Custom App)을 펌웨어에 성공적으로 융합시키기 위해서는 다음 두 개의 산을 넘어야 한다.

  1. 의존성 판단과 선택의 영역 (Kconfig):
    수많은 드론 부품 중 여러분의 모듈이 ‘어떤 하드웨어 보드(예: Pixhawk 4, 6C)에만 탑재될 것인가?’, ’이 모듈을 켜기 위해서는 어떤 하부 기능이 먼저 켜져 있어야 하는가?’를 리눅스 커널 스타일의 시스템인 Kconfig를 통해 선언해주어야 한다. make px4_fmu-vX_default boardconfig 명령어를 쳤을 때 뜨는 다채로운 파란색 GCS 터미널 창(Menuconfig)에 여러분의 모듈 이름을 띄우는 작업이다.

  2. 컴파일과 링킹의 영역 (CMake):
    의존성 검사를 통과하여 “이 모듈을 빌드하겠다“는 허락이 떨어지면, CMake가 투입된다. 어떤 C++ 소스 파일들을 읽어 들일 것인지, 어떤 외부 라이브러리(예: Math 라이브러리)를 링크할 것인지, 그리고 uORB 메시지 헤더 파일이 먼저 생성되도록 순서를 보장(DEPENDS uORB_msgs)할 것인지를 CMakeLists.txtpx4_add_module() 매크로를 통해 지시해야 한다.

2. 통합 파이프라인(Integration Pipeline)의 핵심 경로

우리가 이 단원에서 다루게 될 핵심 파이프라인은 다음과 같은 순서로 진행된다.

  1. 가시성 확보 (21.2.1): Kconfig 파일을 생성하여, PX4 소스 트리의 거대한 구성 트리에 내 모듈의 존재를 알린다. 이곳에서 아키텍처 의존성(depends on) 로직을 체계적으로 짠다.
  2. 컴파일 지시 (21.2.2): CMakeLists.txt 파일 내에서 px4_add_module() 매크로를 호출하고, 스택 크기, 멀티스레드 우선순위, 링커 속성 등을 정의한다.
  3. 타겟 보드 활성화 (21.2.3): 특정 비행 제어기 하드웨어보드(default.px4board 등) 설정 파일 안에 내 모듈을 강제로 포함(CONFIG_MODULES_CUSTOM_APP=y)시켜, 최종 컴파일 대상에 올린다.

모듈을 작성하는 일은 코딩 실력의 영역이지만, 그것을 시스템에 얹는 일은 ’규칙과 약속’의 영역이다. 이 빌드 시스템의 톱니바퀴가 어떻게 돌아가는지 정확히 이해해야만, 수백 MB에 달하는 불필요한 코드를 걷어내고 내 모듈이 쾌적하게 숨 쉴 수 있는 ’경량화된 커스텀 펌웨어’를 매끈하게 뽑아낼 수 있다. 이제 가장 첫 번째 단계인 Kconfig 트리 구조 해부부터 시작하자.