
우선 clang과 크로스 컴파일에 필요한 툴체인을 설치한다.
애초에 크로스 컴파일 환경을 만들었으면 이 과정도 필요없다.
sudo apt install clang libc6-dev-armhf-cross g++-arm-linux-gnueabihf
CMake에서 크로스 컴파일을 하려면 툴체인 파일을 작성해야 한다.
# clang-arm.cmake
set(CMAKE_SYSTEM_NAME Linux) # 타겟 시스템 이름 (예: Linux)
set(CMAKE_SYSTEM_PROCESSOR arm) # 타겟 아키텍처 (예: arm)
# 크로스 컴파일러 설정
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER clang)
# 크로스 컴파일러에 타겟 지정
set(CMAKE_C_FLAGS "--target=arm-linux-gnueabihf")
set(CMAKE_CXX_FLAGS "--target=arm-linux-gnueabihf")
크로스 컴파일 환경을 갖추고 개발했어야 했는데 그러지 않아서 어쩔 수 없이 정적 컴파일을 하려면 아래의 라인을 CMakeLists.txt에 추가한다.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
빌드 디렉터리를 만들고 자신의 디렉터리 구조에 맞게 아래의 명령어를 고쳐 쓰면 된다.
cmake -DCMAKE_TOOLCHAIN_FILE=../clang-arm.cmake -DBUILD_TESTS=OFF ..
ssh를 이용해서 파일을 보내려면 scp 명령어를 사용한다.
scp <로컬_파일_경로> <user_name>@<라즈베리파이_주소>:<라즈베리파이 디렉터리 목적지>
안녕.
크로스 컴파일을 위해서 이번 글을 쓴다.
먼저, 뭘 해야 할지 정리부터 하자.
글 쓰기 전에 이미 찾았다.
앞으로는 글을 쓰면서 찾을 거다.
arm-linux-gnueabihf-로 시작하는 clang, clang++을 사용하여 컴파일 할 거다.
CMake 작성법부터 본다.

위의 사진을 참고했다.
아래의 것들을 세팅해주면 될 것 같다.
작년에 수정된 깃허브 코드를 발견했다. 👍️
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "arm-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER "arm-linux-gnueabihf-g++")
대충 위의 내용처럼 작성하면 되나보다
작성하고 컴파일 했는데 안된다.
확인해보니까 컴파일러가 설치가 안된 거 같아서 설치했다.
sudo apt install g++-arm-linux-gnueabihf
설치했는데도 안됐다.
그래서 찾아보니까 clang이 크로스 컴파일을 지원하는지는 아래의 명령어로 확인해봐야 한다고 하더라.
clang++ --target=arm-linux-gnueabihf --version
⬇️ 결과는 이렇게 나왔다.

CMake에서 크로스 컴파일을 하려면 툴체인 파일을 작성해야 한다.
# clang-arm.cmake
set(CMAKE_SYSTEM_NAME Linux) # 타겟 시스템 이름 (예: Linux)
set(CMAKE_SYSTEM_PROCESSOR arm) # 타겟 아키텍처 (예: arm)
# 크로스 컴파일러 설정
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER clang)
# 크로스 컴파일러에 타겟 지정
set(CMAKE_C_FLAGS "--target=arm-linux-gnueabihf")
set(CMAKE_CXX_FLAGS "--target=arm-linux-gnueabihf")
위와 같이 했는데 gcc로 컴파일 진행돼서 안됐다.
검색해보니 이전에 Cache 파일들을 지워줘야 한다고 했다.
rm -rf CMakeCache.txt CMakeFiles로 지웠다.
이후 실행을 하니까 또 오류가 났다.
알고 보니까 테스트 파일까지 같이 컴파일하려고 해서 gmock의 아키텍처 때문에 오류난 거라 테스트 파일을 빼고 컴파일했다.
이후 file 명령어를 사용해서 EABI5 버전으로 컴파일 된 것을 확인했다.
드디어 라즈베리파이에서 실행한다.
라즈베리파이 전원을 켜고 터미널을 열어 ssh 접속을 한다.
....
왜 접속했지?
일단 접속하기 전에 파일부터 보내야 한다.
ssh를 이용해서 파일을 보내려면 scp 명령어를 사용한다.
scp <로컬_파일_경로> <user_name>@<라즈베리파이_주소>:<라즈베리파이 디렉터리 목적지>

실행하려니까 cannot execute: required file not found라는 에러가 떴다.
라이브러리가 누락돼서 바이너리 파일을 실행할 수 없는 것이다.
readelf -d ./SocketApp | grep NEEDED 명령어로 확인했더니 아래와 같은 결과가 나왔다.

해당 라이브러리를 사용하기 위해 sudo apt install libc6:armhf libstdc++6:armhf 명령어를 실행해서 설치한다.
실행했더니 또 에러가 난다.
GLIBCXX_3.4.32' not found (required by ./SocketApp)
라즈베리파이에 설치되어있는 버전보다 최신 버전을 요구해서 실행되지 않는 거라고 한다.
최신 버전을 설치하기 위해서는 gcc를 설치해야 한다.
엥? clang으로 컴파일 했는데 왜 gcc를 설치함?
라이브러리는 gcc의 최신 버전으로 컴파일 되어있기 때문에 읽으려면 gcc가 필요한 걸로 이해했다.
GLIBCXX_3.4.32 버전 이상이 필요한데 나는 GLIBCXX_3.4.30 버전까지밖에 없다.
그래서 gcc 업그레이드를 해야 하는데 이미 있다고 또 업그레이드가 안된다.
find /usr -name "libstdc++.so.6" 명령어로 찾아보니까 2가지 버전의 libstdc가 있는 것을 확인했다.
그 이후에 어쩌고 저쩌고 했는데 계속 해서 라이브러리의 최신 버전이 필요하대서 그냥 CMakeLists.txt에다가 정적 컴파일 하라고 시켰다.
# 아래 내용 추가해서 정적 컴파일
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
이후 실행했는데 계획대로 동작했다.
🤔 : CMAKE 옵션들 각각의 기능