본문 바로 가기

CMake로 간단하게: 어디서나 코딩하고, 어디서나 빌드하기

Read Time

10분

요약

CMake로 임베디드 팀의 개발자·운영체제·CI/CD 환경 워크플로를 표준화하는 방법

  • 어디서나 하나의 빌드 설명: CMake는 제각각 변질되는 IDE, 스크립트, CI 설정을 텍스트 기반으로 버전 관리되는 하나의 빌드로 대체합니다. 이 빌드는 Linux, Windows, 컨테이너, 파이프라인 어디서든 똑같이 동작합니다. 새로운 코어나 변형이 생겨도 프로젝트를 복제할 필요 없이 툴체인 파일이나 프리셋만 추가하면 됩니다.
  • CMake를 기본으로 지원하는 IAR Platform: IAR 크로스 플랫폼 IDE는 CMake 프로젝트와 기존 Zephyr/west 프로젝트를 변환 없이 그대로 엽니다. 편집과 C-SPY 디버깅을 모두 쓸 수 있고, CTest, C-SPY 테스트 실행, C-STAT 정적 분석(MISRA, CERT, CWE)도 개발자 워크스테이션과 CI에서 동일하게 실행됩니다.
  • 팀이 얻는 효과: 설정 변질이 줄고, 온보딩이 빨라지며, 몇 년 뒤에도 다시 만들어 낼 수 있는 재현 가능한 빌드를 확보합니다. 사이버 복원력법(CRA, Cyber Resilience Act) 같은 규제를 고려하면 중요한 부분입니다. 기존 IAR 프로젝트는 단계적으로 마이그레이션할 수 있습니다.

모든 임베디드 개발 팀은 다음과 같은 상황을한 번쯤겪어봤을 것입니다. 공급업체의 프로젝트 파일은 특정 IDE에 묶어두는 반면, CI 파이프라인은 또 다른 환경을요구합니다 . 리눅스 개발자들은 GUI 중심의 개발 방식에서 벗어나 더 스크립트 중심의 워크플로를 도입하기 위해 프로젝트 파일을 수작업으로변환하곤 합니다. 새로운 마이크로컨트롤러 변종은 유지 관리해야 할또 다른 프로젝트 구성을가져오는데 , 이는 대개 공급업체 고유의 형식으로 되어 있습니다.

이러한 마찰은 임베디드 개발이 소프트웨어 빌드 방식을 설명하는 공통언어로 CMake를 채택하는 방향으로 수렴하고 있는 주요 이유 중 하나입니다. IDE, 명령줄 도구, CI 파이프라인이 모두 읽을 수 있는 단일 빌드 설명이, 서서히 서로 어긋나고 있는 수많은 구성 설정을 대체합니다.

IAR은 수십 년 동안 자체 프로젝트 형식을 사용해 왔으며, 팀이 이를 계속 사용할 수 있도록 완전한 지원이 제공되지만, 이제 CMake는 IAR 플랫폼 전반에서 주요 옵션으로 자리 잡았습니다. 이 블로그에서는 워크스테이션에서 파이프라인에 이르기까지 단일 펌웨어 프로젝트를 따라가며, 실제 적용 사례가 어떻게 보이는지 보여드립니다.

임베디드 팀들이 CMake로 전환하는 이유는 무엇일까요?

대부분의 팀은 의도적으로 빌드 과정을 복잡하게 만들지 않습니다. 복잡성은 점차 쌓여갑니다. 새로운 제품 변형에는 별도의 구성이 필요합니다. 두 번째 아키텍처가 추가되면 프로젝트 파일도 늘어납니다. CI 스크립트는 이미 IDE에 존재하는 설정을 중복하여 복사하기 시작합니다. 얼마 지나지 않아, 본질적으로 동일해야 할 빌드의 여러 버전이 서로 독립적으로 진화하게 됩니다.

이러한 증상은 익숙할 것입니다:

    • IDE, 스크립트, CI 전반에 걸쳐 수동으로 동기화해야 하는 프로젝트 설정
    • 개발자 및 팀 간에 발생하는 구성 불일치
    • 특정 컴퓨터나 운영 체제에서만 작동하는 빌드 스크립트
    • 새로운 아키텍처나 변형을 도입하려면 프로젝트 전체를 복제해야 함
    • 빌드 정보가 일부는 파일에, 일부는 누군가의 머릿속에 흩어져 있어 온보딩이 더딘 문제

한편, 환경은 변했습니다. 이제 빌드는 리눅스에서 컨테이너 내부에서 헤드리스 방식으로 실행되며, 데스크톱을 한 번도 본 적 없는 파이프라인에 의해 트리거됩니다. GUI 프로젝트 형식 내부에만 존재하는 빌드는 이러한 환경에서 병목 현상이 됩니다. 텍스트 기반이며 버전 관리가 되는 CMake 설명은 이러한 환경에 자연스럽게 부합합니다.

CMake는 임베디드 타깃에 대한 크로스 컴파일을 어떻게 처리할까요?

크로스 컴파일을 가능하게 하는 부분, 즉 툴체인 파일부터 살펴보겠습니다. 이 파일은 CMake에 어떤 컴파일러, 어셈블러, 링커를 사용할지, 그리고 어떤 플랫폼을 대상으로 하는지 알려줍니다. Arm용 IAR 툴체인을 위한 최소한의 툴체인 파일은 다음과 같습니다:

cmake

# iar-arm.cmake

set(CMAKE_SYSTEM_NAME Generic)

set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER iccarm)

set(CMAKE_CXX_COMPILER iccarm)

set(CMAKE_ASM_COMPILER iasmarm)

이렇게 설정하면, Linux나 Windows의 어떤 터미널에서든 동일한 프로젝트를 구성하고 빌드할 수 있습니다:

cmake -S . -B build -G Ninja --toolchain iar-arm.cmake

cmake --build build

프로젝트가 확장되더라도 CMake의 타깃 중심 설계 덕분에 관리하기 쉽습니다. 포함 경로, 컴파일러 설정 및 링크 옵션은 target_include_directories() 및 target_link_libraries()와 같은 명령을 통해 타깃에 연결되며, 이에 의존하는 모든 요소로 자동으로 전파됩니다. 제너레이터 표현식을 사용하면 단일 CMakeLists.txt 파일로 다양한 아키텍처, 컴파일러 및 빌드 유형에 대응할 수 있습니다. 새로운 코어나 장치 변형을 지원하는 작업은 프로젝트를 복제하는 대신 새로운 툴체인 파일이나 프리셋을 생성하는 방식으로 이루어집니다.

CMake로 임베디드 테스트를 실행할 수 있을까요?

동일한 빌드 설명으로 테스트도 수행할 수 있습니다. CTest는 CMake의 일부입니다. add_test()를 사용하여 테스트를 정의하면, 소프트웨어 빌드에 사용된 것과 동일한 워크플로를 통해 테스트가 실행됩니다.

ctest --test-dir build

IAR 사용자의 경우, 테스트를 한 단계 더 발전시켜 C-SPY 디버거를 통해 시뮬레이터나 대상 하드웨어에서 실행할 수 있습니다. C-SPY를 지원하는 테스트 래퍼가 각 테스트를 실행하고 출력 결과를 통해 성공 또는 실패를 감지하므로, CI 결과는 개발자가 디버깅할 때 사용하는 것과 동일한 실행 환경에서 도출됩니다.

이제 빌드와 테스트가 하나의 공통 기반을 공유하므로, 파이프라인과 개발자의 워크스테이션 모두 동일한 단계를 실행하고 동일한 결과를 얻게 됩니다.

IAR 크로스 플랫폼 IDE는 CMake와 어떻게 연동되나요?

CMake 도입을 고려하는 팀들이 흔히 묻는 질문 중 하나는 CMake 프로젝트를 유지하면서도 IDE에서 생산적으로 작업할 수 있는지 여부입니다. IAR 크로스 플랫폼 IDE를 사용하면 CMake 프로젝트가 여전히 신뢰할 수 있는 기준이 됩니다. IDE는 프로젝트를 다른 형식으로 변환하지 않고 Linux나 Windows에서 직접 열어주므로, 프로젝트는 이식성이 유지되고 스크립트 처리가 가능하며 CMake를 이해하는 모든 도구에서 읽을 수 있습니다.

개발자는 본격적인 IDE가 제공하는 편집, 빌드 및 C-SPY 디버깅 기능을 활용할 수 있습니다. 명령줄, CI 서버 및 Docker 컨테이너는 여전히 정확히 동일한 빌드 정의를 사용합니다. 소스 트리 외부에 숨겨진 프로젝트 상태가 없으므로, 개발자의 컴퓨터에서 빌드된 결과물은 Jenkins, GitLab CI 또는 GitHub Actions에서 실행되는 빌드와 동일합니다.

기존 IAR 프로젝트를 보유한 팀은 모든 것을 한꺼번에 전환할 필요가 없습니다. 새로운 프로젝트는 CMake로 시작할 수 있으며, 기존 제품은 현재 설정 그대로 계속 사용할 수 있습니다.

기존 Zephyr 프로젝트를 IAR IDE에서 사용할 수 있나요?

Zephyr를 사용하는 팀의 경우, 새로운 개발 환경을 도입할 때 가장 큰 장벽은 대개 마이그레이션에 드는 노력입니다. Zephyr 프로젝트는 이미 CMake 기반으로 구축되어 있으며 west 도구를 통해 관리되고 있는데, 더 나은 디버거를 사용하기 위해 정상적으로 작동하는 프로젝트의 구조를 변경하고 싶어 하는 사람은 아무도 없습니다.

IAR 크로스 플랫폼 IDE는 기존에 미리 구성된 Zephyr 프로젝트에 직접 연동됩니다. west 워크플로는 기존 그대로 유지되며, 팀은 여기에 IAR의 디버깅 및 분석 기능을 추가로 활용할 수 있습니다. IDE가 프로젝트에 맞춰 조정되는 것이지, 그 반대가 아닙니다.

그림 1: 기존 CMakeLists.txt 파일 가져오기 기능을 포함하여 CMake 기반 임베디드 프로젝트를 보여주는 IAR Embedded Workbench 크로스 플랫폼 IDE의 스크린샷. 개발자는 기존 CMake 프로젝트를 모든 기능을 갖춘 크로스 플랫폼 환경으로 직접 가져와, 단일 빌드 구성을 유지하면서 편집, 빌드, 디버깅 및 CI/CD 통합을 수행할 수 있습니다.

CMake 빌드에서 정적 분석을 어떻게 실행하나요?

CMake 기반 워크플로우에서는 정적 분석이 누군가가 따로 기억해야 하는 별도의 단계가 아니라 빌드 과정 자체의 일부가 될 수 있습니다.

Zephyr에서는 ZEPHYR_SCA_VARIANT 변수를 통해 CMake 인수로 정적 분석 도구를 선택합니다. IAR C-STAT을 선택하면 개발자가 이미 실행하고 있는 빌드 명령어에 분석 단계가 추가됩니다:

west build -b <board> -- -DZEPHYR_SCA_VARIANT=iar_c_stat

그러면 C-STAT은 코드를 MISRA C, MISRA C++ 및 CERT C/C++ 기준에 따라 검사하고, 발견된 결과를 CWE 취약점 클래스에 매핑합니다. 규칙 세트, 스레드 수 및 분석기 옵션은 CMake 변수를 통해 설정되므로, 분석 구성은 코드와 함께 버전 관리되며 모든 워크스테이션과 모든 파이프라인에서 동일하게 실행됩니다.

CMake 기반 워크플로가 팀에 어떤 의미가 있을까요?

개발자에게는 즉각적인 이점이 있습니다. 하나의 프로젝트로 모든 운영 체제와 도구를 사용할 수 있으며, 설정을 수동으로 동기화할 필요가 없습니다.

엔지니어링 리더의 경우, 그 가치는 시간이 지남에 따라 배가됩니다. 중복된 구성을 일치시키는 데 소요되는 모든 시간과 IDE와 파이프라인 간의 불일치로 인한 모든 CI 실패가 근원적으로 제거됩니다. 신입 사원 온보딩도 더 빨라집니다. CMake는 업계 전반에 널리 알려져 있으므로, 신입 엔지니어들은 도구별 형식을 먼저 배우는 대신, 종종 도착하자마자 빌드를 읽고 확장할 수 있는 능력을 갖추고 있습니다.

단일하고 버전 관리가 되는 빌드 설명은 재현 가능한 빌드의 핵심 토대 중 하나입니다. 버전 고정된 툴체인과 통제된 빌드 환경과 결합되면, 팀은 수년이 지난 후에도 정확히 동일한 바이너리를 재빌드할 수 있게 되며, 이는 ‘사이버 복원력 법(Cyber Resilience Act)’과 같은 규제가 강화됨에 따라 더욱 중요해지는 요구 사항입니다.

종합해 보면, 이것이 바로 임베디드 개발이 나아가고 있는 방향입니다. 즉, 하나의 빌드 설명, 다양한 환경, 그리고 워크플로우를 정의하기보다는 워크플로우에 자연스럽게 녹아드는 IDE입니다.

실제 적용 사례 확인하기

자신의 프로젝트에서 CMake 우선 워크플로를 직접 시도해 보거나, 대화형 IAR 플랫폼 데모를 통해 각 구성 요소가 어떻게 조화를 이루는지 확인해 보세요.

 

    IAR 임베디드 개발 도구

    자세히 보기