21.2.3.1.1. CONFIG_MODULES_CUSTOM_APP=y 구문이 CMake의 add_subdirectory()를 호출하는 트리거 로직
앞선 21.2.3.1 단원에서 우리는 default.px4board 파일 안의 텍스트 한 줄(CONFIG_MODULES_CUSTOM_APP=y)이 파이썬 스크립트의 손길을 거쳐 CMake 캐시 내의 불리언(Boolean) 변수로 둔갑한다는 것을 알게 되었다.
그렇다면 이 CMake 메모리 안에 둥둥 떠다니는 수백 개의 CONFIG_*=y 변수들은 도대체 언제, 어디서, 어떻게 진정한 C++ 빌드 지시어인 add_subdirectory() 구문으로 변환되어 우리의 소스 폴더를 찌르게 되는 것일까?
이 마법이 벌어지는 은밀한 장소는 다름 아닌 PX4 소스 트리의 각 대분류 디렉터리(src/modules/, src/drivers/ 등) 바로 아래에 숨어있는 중간 브로커(Broker) 역할의 CMakeLists.txt 파일들이다.
1. src/modules/CMakeLists.txt의 조건부 컴파일 로직
여러분이 짠 모듈이 위치한 src/modules 폴더 바로 밑에는 펌웨어 전체 모듈을 통제하는 하나의 거대한 허브(Hub)격인 CMakeLists.txt 파일이 존재한다. 이 파일을 열어보면, 그토록 찾아 헤매던 add_subdirectory() 명령어들이 다음과 같이 즐비하게 늘어서 있는 것을 볼 수 있다.
# src/modules/CMakeLists.txt 내부 예시
px4_add_subdirectory(commander)
px4_add_subdirectory(ekf2)
px4_add_subdirectory(mc_att_control)
px4_add_subdirectory(sensors)
# ... 수십 개의 기본 모듈들 ...
# 그리고 이 파일의 마지막 즈음에 나타나는 기묘한 코드 블록:
foreach(custom_module ${CONFIG_MODULES})
px4_add_subdirectory(${custom_module})
endforeach()
(참고로 PX4는 순정 CMake 함수인 add_subdirectory 대신 각종 예외 처리가 가미된 래퍼(Wrapper) 함수인 px4_add_subdirectory를 쓴다.)
이 파일의 코드를 자세히 들여다보면, 모든 하위 폴더들을 무지성으로 컴파일하는 것이 아니다. 특히 커스텀 모듈이나 선택적 드라이버들의 경우, 오직 CMake 캐시 변수가 켜져 있을 때(=y)만 add_subdirectory를 호출하도록 고도로 스크립팅되어 있다.
1.1 트리거(Trigger)의 정확한 메커니즘
- 변수 룩업(Lookup): 빌드가 시작될 때 최상위 루트의 CMake는 아까 파이썬이 만들어둔 Kconfig 캐시 파일(
px4_board_config.cmake)을 메모리에include한다. 이제 시스템은CONFIG_MODULES_CUSTOM_APP이라는 변수값이TRUE(y)라는 것을 안다. - 허브 디렉터리 진입: 빌드의 흐름이
src/modules/CMakeLists.txt파일로 진입한다. - 동적 폴더 파싱: 파일 내부의 CMake 스크립트가 로직을 돌면서 묻는다. “현재 메모리에 등록된
CONFIG_MODULES_...변수들 중 값이y인 것들이 무엇무엇이 있지?” - 문자열 치환 및 호출 (Trigger): 시스템은
CONFIG_MODULES_CUSTOM_APP=y를 발견하고, 영리하게 접두어를 잘라내어 문자열custom_app을 추출한다. 그리고는 지체 없이 매크로를 발사한다.
\rightarrowpx4_add_subdirectory(custom_app) - 하부 진입 완료: 드디어 C++ 컴파일러가 여러분의
src/modules/custom_app/CMakeLists.txt파일 안으로 틈입하여 컴파일 지시를 받아 적고 번역을 시작한다.
이러한 **단축 평가(Short-circuit evaluation)**와 문자열 치환 매크로의 조합 덕분에, 우리는 CONFIG_MODULES_CUSTOM_APP=y라는 단 한 줄의 스위치만으로 거대한 CMake 컴파일 트리 한가운데에 내 소스 폴더를 정확하게 접붙일 수 있게 되는 것이다.
이제 빌드 시스템의 최후미에 도달했다. 이 모든 빌드의 파편들이 쏟아져 내리는 하수구이자 창고인 build/ 디렉터리의 구조와, 빌드가 꼬였을 때 우리가 무의식적으로 치는 make clean의 숨겨진 의미를 다음 21.2.3.2 단원에서 정리해보자.