도구와 산출물의 역할을 나눈다
AI/로봇 프로젝트는 Python 패키지뿐 아니라 native 확장, 메시지 생성물, 설정·모델 자산을 함께 사용한다. 빌드가 성공했다는 한 줄보다 어떤 소스와 의존성을 어떤 도구가 선택해 어떤 산출물을 만들었는지 알아야 한다. 일반 코드 작성 경험은 있어도 CMake와 colcon의 경계를 놓치면 환경 오류를 코드 오류로 오인하기 쉽다.
그림 M01.04-1. 각 칸은 서로 다른 역할/근거다. 아래 방향은 자료/처리의 연결이며 실제 성공을 자동으로 보장하지 않는다. 직접 제작한 개념도이며 본문의 조건과 함께 읽는다.
CMake는 타깃과 의존성·옵션을 기술한 프로젝트에서 선택한 생성기의 빌드 구성을 만든다. 타깃은 실행 파일이나 라이브러리 같은 논리적 빌드 단위다. 컴파일러는 소스를 번역하고, 링커는 필요한 정의를 연결한다. CMake가 그 도구들을 직접 대체하는 새 C++ 실행기는 아니다. CMake 빌드 시스템 설명은 타깃의 소스·사용 요구·링크 관계를 구분한다.
colcon은 workspace의 여러 패키지를 발견하고 의존 관계에 따라 빌드·시험을 조율하는 도구다. ROS의 CMake 기반 패키지는 ament_cmake가 등록·설치·의존성 내보내기 기능 등을 더한다. package.xml은 패키지 의존성·메타데이터를, CMakeLists.txt는 해당 빌드 요구를 담는다. 같은 ROS 패키지라도 여러 타깃을 가질 수 있다. 패키지 하나의 성공과 모든 타깃의 실행 검증은 같지 않다. Python 패키지 빌드도 있을 수 있으므로 모든 colcon 작업을 C++ 컴파일로 동일시하지 않는다.
Configure·build·install·실행을 잇는다
configure는 소스·빌드 디렉터리, 생성기·컴파일러·의존성·옵션을 선택하고 빌드 구성을 만든다. 예를 들어 cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug는 단일 구성 생성기를 가정한 설정 예다. 다중 구성 생성기는 빌드 때 구성을 선택하는 등 차이가 있으므로 프로젝트 규약을 확인한다. 성공했다는 것은 이 단계의 설정이 만들어졌다는 뜻이며 소스의 모든 번역·링크 성공을 뜻하지 않는다.
cmake --build build --target sensor_reader는 그 빌드 공간의 지정 타깃을 빌드하는 명령 형태다. 실제 실행을 하려면 성공한 산출물과 실행 경로를 이어야 한다. install은 실행 파일·라이브러리·헤더·설정 등의 배포 위치를 준비하는 단계이며, 빌드 폴더의 결과와 실행 환경이 찾는 설치본은 다를 수 있다. 여기의 명령은 절차를 읽기 위한 예이며 실행할 소스 프로젝트나 ROS 실행 결과를 제공했다는 뜻은 아니다.
colcon workspace 설명의 기본 build·install·log는 각각 중간 빌드 자료, 설치 자료, 빌드 기록을 구분한다. 소스가 src에 있어도 실행이 install의 이전 결과를 선택할 수 있다. 파일 수정→대상 빌드 성공→필요한 설치 반영→실행 환경 선택→실제 실행·입출력 확인을 한 줄로 연결해 기록한다. configure만 반복하거나 실패 뒤 남은 실행 파일을 실행하면 수정 전 결과를 새 결과로 오인할 수 있다.
첫 실패의 층위를 찾는다
설정에서 SensorMathConfig.cmake를 찾지 못하면 우선 의도한 의존 패키지의 설치와 CMake 검색 경로·버전을 조사한다. 소스 함수의 계산식을 고칠 단계라는 근거는 없다. 설정 통과 뒤 sensor.hpp: file not found가 나오면 해당 번역 작업의 include 경로와 실제 헤더 위치, 타깃에 전달된 요구를 확인한다. 의존성이 기록돼 있다고 모든 소비 타깃에 필요한 헤더 경로가 전달됐다고 가정하지 않는다.
컴파일이 통과했는데 링크에서 undefined reference to convert_mm가 나오면 선언을 봤지만 필요한 정의와 맞게 연결하지 못했을 가능성을 조사한다. 타깃의 소스 목록과 링크 대상, 실제 라이브러리의 심벌·ABI·옵션을 확인한다. include 경로만 추가해서 실제 정의 누락까지 해결되는 것은 아니다. 의존 타깃의 요구를 소비 타깃에 연결하는 방식과 무관한 전역 경로 추가를 혼동하지 않는다.
링크 뒤 실행 시작에서 필요한 공유 라이브러리나 심벌을 못 찾으면 로더가 선택한 경로를 대조한다. 빌드 때 새 라이브러리를 썼어도 실행 때 오래된 설치본이 먼저 선택될 수 있다. 이때도 원문 오류와 실제 선택 경로가 단서이며 모든 로더 오류의 원인을 하나로 고정하지 않는다. 반대로 정상 시작 뒤 250 mm를 250 m로 표시했다면 빌드·로더 통과가 단위 계약까지 검증하지 않았다는 뜻이다. 입력 250 mm를 1000으로 나눈 0.250 m와 비교해 변환/소비 경계를 조사한다.
Underlay·overlay와 빌드 캐시를 증거로 본다
CMakeCache.txt에는 선택한 도구·의존 경로·옵션 등이 남을 수 있다. 환경을 바꿔도 기존 빌드 공간이 이전 선택을 유지하는지 확인한다. 실패 기록을 보존하고 의도한 설정으로 분리된 빌드 공간을 만드는 것은 비교 방법이다. 모든 build/install 폴더를 먼저 삭제하면 어떤 조합에서 실패했는지 증거도 사라질 수 있다. 재구성을 할 때는 필요한 범위와 변경된 조건을 적는다.
ROS의 overlay가 같은 패키지를 대체한다면 헤더와 실행 라이브러리가 같은 계약을 사용해야 한다. colcon overriding 안내는 include 검색 순서와 ABI 변경의 문제를 설명한다. 기반 라이브러리 ABI를 바꿨는데 그것을 사용해 이미 빌드한 패키지를 그대로 두는 문제는 실행 경로만 새 것으로 바꾸면 끝나지 않을 수 있다. 직접·간접 소비자와 필요한 재빌드 범위를 검토한다. 이번 활동은 실제 패키지를 교체하지 않는다.
예를 들어 소스 revision B를 편집했고 B의 configure가 성공했지만 build는 링크 오류로 끝났다고 하자. 이후 /old/install/sensor_reader의 build ID A가 출력됐다면 B의 계산이 검증됐다는 주장은 성립하지 않는다. B 빌드 실패와 A 실행을 서로 다른 사건으로 적는다. 다음 시도에서 B의 빌드·설치·선택 경로가 맞아도 합성 입력의 단위·출력, 실패 입력 거부, 실제 프로젝트의 실행 조건은 별도 검증이다. 빌드 성공은 물리 장비의 기한·정확도·안전을 증명하지 않는다.