21.2.3.2. Out-of-tree 빌드 디렉토리(build/px4_fmu-vX_default/) 내 중간 생성물 분석 및 캐시 클리어(make clean)
드디어 C++ 소스 코드가 Kconfig와 CMake의 험난한 파이프라인을 통과하여 번역(컴파일)되기 시작했다. 그렇다면 컴파일러가 만들어내는 그 수많은 기계어 조각파일(.obj, .a)과 자동 생성 헤더 파일들은 도대체 어디로 가는 것일까?
PX4 빌드 시스템은 절대로 지저분하게 여러분의 원본 소스 폴더(src/) 안에 기계어 쓰레기들을 늘어놓지 않는다. PX4는 철저한 ‘아웃오브트리 빌드(Out-of-tree Build)’ 원칙을 고수하며, 소스 코드 원본과 빌드 산출물을 완벽하게 물리적으로 격리시킨다.
1. build/ 디렉터리의 생태계 파헤치기
make px4_fmu-v6x_default 명령어를 실행하는 순간, 소스 트리 제일 바깥쪽 루트에 덩그러니 build/ 라는 폴더가 솟아난다. 그리고 그 안에 타겟 이름(px4_fmu-v6x_default)과 동일한 하위 폴더가 생성되며, 이 거대한 창고 안에 모든 중간 생성물들이 쏟아져 들어간다.
여러분이 작성한 커스텀 모듈(src/modules/custom_app)의 흔적은 이 창고 안에서 크게 세 가지 형태로 발견된다.
- CMake 캐시 (Cache):
build/px4_fmu.../CMakeCache.txt파일 안에는 앞서 파이썬 스크립트가 파싱해 온CONFIG_MODULES_CUSTOM_APP=y라는 스위치 값이 문자열 텍스트로 보관되어 있다. - uORB 파생 헤더 파일:
build/px4_fmu.../uORB/topics/경로를 뒤져보면,my_custom_sensor.h처럼.msg파일에서 변환된 따끈따끈한 C++ 라이브러리 헤더 파일들이 쌓여 있다. 여러분의 모듈은 소스 트리가 아니라 바로 이 빌드 폴더의 헤더를 끌어다(Include) 쓴다. - 정적 라이브러리 아카이브(
.a):
build/px4_fmu.../src/modules/custom_app/라는, 원본과 똑같이 생긴 거울상 경로가 생성되어 있다. 스크롤을 내려보면 그 안에 컴파일의 최종 산물이자 링커에게 바쳐질 제물인libmodules__custom_app.a파일이 고이 모셔져 있다.
빌드 시스템의 마지막 과정인 링커(Linker)는 이 build/ 폴더 안의 모든 .a 파일들을 싹싹 긁어모아 믹서기에 넣고 갈아서 단 하나의 파일, build/px4_fmu.../px4_fmu-v6x_default.px4 라는 최종 펌웨어 바이너리를 뿅 하고 뱉어낸다.
2. make clean의 해부학: 캐시(Cache)가 낳는 저주
아웃오브트리 빌드는 소스 코드를 깨끗하게 유지해 주는 축복이지만, 가끔 개발자를 원인 모를 늪에 빠뜨리는 저주가 되기도 한다.
여러분이 소스 코드의 CMakeLists.txt 구조를 크게 뒤엎었거나 Kconfig 의존성을 갈아엎었는데도 불구하고, 다시 make를 쳤을 때 빌드 시스템이 수정 사항을 반영하지 않고 예전 옵션으로 빌드하여 기괴한 에러를 뿜어댈 때가 있다.
이는 빌드 속도를 높이기 위해 CMake가 이전 빌드 시 만들어두었던 ’캐시(Cache)’를 맹신하고 다시 파싱하지 않기 때문이다.
이때 우리가 마법의 주문처럼 치는 명령어가 바로 make clean이다.
make clean의 진짜 의미: 똑똑하게 코드를 분석해서 꼬인 의존성을 풀어주는 것이 아니다. 그냥 무식하게build/px4_fmu-v6x_default/폴더 자체를 리눅스rm -rf명령어로 통째로 날려버리는 행위이다. (물론 소스 코드 원본 폴더인src/는 아웃오브트리 격리 덕분에 100% 안전하다.)
모든 빌드 창고가 잿더미가 되었으므로, 다음번 make 명령어를 칠 때 시스템은 어쩔 수 없이 Kconfig부터 다시 파싱하고, uORB 헤더를 1번부터 다시 제너레이팅하며, 소스 파일들을 뼈대부터 다시 컴파일하는 완전한 ‘콜드 스타트(Cold Start)’ 클린 빌드를 수행하게 된다.
2.1 모듈 개발자의 꿀팁: 특정 모듈만 핀셋 클린(Clean)하기
만약 펌웨어 전체를 make clean 해버리면 다시 1000개의 파일을 컴파일하느라 5분이 넘는 귀중한 멍때림의 시간을 바쳐야 한다. 내가 짠 custom_app 모듈의 컴파일 꼬임만 풀고 싶다면 핀셋처럼 특정 모듈 창고만 날아버리는 것이 현명하다.
$ rm -rf build/px4_fmu-v6x_default/src/modules/custom_app
이렇게 내 모듈의 거울 폴더만 삭제하고 다시 make를 돌리면, CMake는 기존 코어 라이브러리 캐시는 그대로 살려둔 채 지워진 내 모듈 폴더 하나만 깔끔하게 다시 컴파일하여 펌웨어에 쏙 끼워 넣어준다.
빌드 아키텍처의 거대한 흐름을 모두 파악했다면, 드디어 다음 장(21.3)부터는 진짜 C++ 소스 코드 편집기를 열고, PX4 런루프(Run-loop) 위에서 살아 숨 쉬는 ’최소 단위 모듈(Hello World)’의 심장부를 해부해 볼 시간이다.