본문 바로가기
HW SW 개발

💻🔧ARM32 라즈베리파이에서 크로스 컴파일 적용 예시: PC에서 빌드하고 Pi에서 실행하기

by 아이텍 2025. 12. 14.
반응형

이전 글에서 “크로스 컴파일은 Host(빌드 머신)에서 Target(실행 머신)용 바이너리를 만든다”는 개념을 정리했습니다. 이번 글에서는 ARM32(32-bit) 라즈베리파이를 대상으로, 가장 실무적인 흐름인 PC(우분투)에서 빌드 → 라즈베리파이에서 실행까지 한 번에 따라갈 수 있도록 예시를 정리합니다.

가정

  • Host: x86_64 Ubuntu(개발 PC)
  • Target: Raspberry Pi OS 32-bit(ARMv7 / armhf)
  • 목표: hello 같은 간단한 C 프로그램을 ARM32용으로 빌드하여 Pi에서 실행

1) 라즈베리파이(ARM32) 확인부터: armhf가 맞는지 체크

라즈베리파이에서 아래 명령으로 아키텍처를 확인합니다.

 
uname -m dpkg --print-architecture getconf LONG_BIT

예상 결과 예시:

  • uname -m → armv7l (Pi 2/3/4에서 32-bit OS면 자주 이렇게 나옵니다)
  • dpkg --print-architecture → armhf
  • getconf LONG_BIT → 32

여기서 핵심은 dpkg 아키텍처가 armhf인지입니다. 이 글은 ARM32(armhf) 기준입니다.


2) Host(우분투 PC)에 ARM32 크로스 컴파일러 설치

우분투에서는 보통 gcc-arm-linux-gnueabihf 패키지를 많이 씁니다.

 
sudo apt update sudo apt install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

설치 후 확인:

 
arm-linux-gnueabihf-gcc -v

3) (중요) “sysroot” 준비: 타깃(라즈베리파이)의 라이브러리/헤더를 Host에서 쓰기

단순한 hello.c 정도는 sysroot 없이도 빌드가 되지만, 실무에서는 (특히 OpenSSL, zlib, libcurl 등) 타깃 라이브러리 링크가 필요해져서 sysroot가 사실상 필수입니다.

가장 현실적인 방법은 라즈베리파이의 루트 파일시스템 일부를 Host로 복사하는 것입니다.

3-1) Host에서 sysroot 디렉터리 생성

 
mkdir -p $HOME/rpi-sysroot

3-2) Pi에서 Host로 필요한 경로를 rsync로 복사

(Host에서 실행. Pi IP/계정은 환경에 맞게 변경)

 
rsync -avz pi@raspberrypi.local:/lib $HOME/rpi-sysroot/ rsync -avz pi@raspberrypi.local:/usr $HOME/rpi-sysroot/

팁: SSH 접속이 설정돼 있어야 합니다. .local이 안 되면 Pi의 실제 IP를 사용하세요.


4) ARM32용 “Hello World” 크로스 컴파일

4-1) 예제 코드 작성 (Host)

hello.c

 
#include <stdio.h> int main(void) { printf("Hello from ARM32 cross-compiled binary!\n"); return 0; }

4-2) sysroot를 지정해서 컴파일 (Host)

 
arm-linux-gnueabihf-gcc hello.c -o hello_arm32 \ --sysroot=$HOME/rpi-sysroot

빌드된 파일 확인:

 
file hello_arm32 readelf -h hello_arm32 | head

file 결과에 대략 아래처럼 나오면 정상입니다.

  • ELF 32-bit LSB ... ARM, EABI5 ... dynamically linked ...

5) 라즈베리파이로 복사 후 실행

5-1) Host → Pi로 전송

 
scp hello_arm32 pi@raspberrypi.local:/home/pi/

5-2) Pi에서 실행

 
chmod +x ~/hello_arm32 ./hello_arm32

정상 출력:

 
Hello from ARM32 cross-compiled binary!

6) 자주 터지는 문제와 해결 체크리스트

(1) “Exec format error”

  • 원인: 타깃 아키텍처가 다름(예: Pi는 32-bit인데 aarch64로 빌드했거나 반대)
  • 해결: Pi에서 dpkg --print-architecture가 armhf인지 확인하고, 컴파일러가 gnueabihf(hard-float)인지 확인

(2) “No such file or directory”인데 파일은 존재함

  • 원인: 동적 로더/라이브러리 경로 문제(대개 잘못된 ABI 또는 타깃 라이브러리 누락)
  • 해결: Pi에서로 의존성 확인. sysroot를 타깃에서 제대로 가져왔는지 점검.
  •  
    ldd ./hello_arm32

(3) 특정 라이브러리 링크가 깨짐 (-lxxx not found)

  • 원인: Host의 라이브러리를 링크하려고 함(타깃용이 아님)
  • 해결: sysroot 기반으로 include/lib 경로를 잡거나, pkg-config도 타깃용으로 맞춰야 함(다음 글 소재로 좋습니다)

7) 실무 팁: Makefile/CMake로 확장하는 방향

단발성 컴파일은 위 방식으로 충분하지만, 프로젝트가 커지면 보통 아래로 확장합니다.

  • CMake toolchain file로 CMAKE_SYSROOT, CMAKE_C_COMPILER 지정
  • pkg-config도 타깃용 .pc를 보게 환경변수(PKG_CONFIG_SYSROOT_DIR, PKG_CONFIG_LIBDIR) 구성
  • 배포는 scp/rsync로 바이너리 + 필요한 설정/리소스 동반 전송

마무리

ARM32 라즈베리파이에서 크로스 컴파일은 결론적으로 아래 3가지만 잡으면 안정화됩니다.

  1. 타깃 아키텍처 확인(armhf)
  2. Host에 arm-linux-gnueabihf-* 툴체인 설치
  3. 타깃에서 sysroot(/lib, /usr)를 가져와 --sysroot로 빌드

 

반응형