본문 바로가기
💻 programming

리눅스PC에서 NVIDIA Jetson 바이너리 크로스 컴파일하기

by 연구원-A 2022. 12. 9.
반응형

I. 문제점

  • bash: ./a.out: cannot execute binary file: Exec format error
  • 같은 리눅스 OS라고 해서 다른 PC에서 빌드한 바이너리를 그대로 복사해서 사용할 수 없다
  • 컴퓨터 아키텍처가 다르면 바이너리를 실행할 수 없다 (=아키텍처가 같으면 실행할 수 있다)
    • x86 리눅스에서 빌드한 바이너리를 Jetson에 복사-붙여넣기 한다고 실행되지 않는다

I-1. 컴퓨터 아키텍처 확인하기

  • uname -a 명령어를 통해 서버와 Jetson TX2 보드의 아키텍처를 확인해보자
    • 서버는 x86_64, Jetson TX2 보드는 ARM 기반의 aarch64 아키텍처로 다르다
uname - a

Linux data 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Linux GTW-TX2NX-C19EBDV9 4.9.253-tegra #1 SMP PREEMPT Mon Jul 26 12:19:28 PDT 2021 aarch64 aarch64 aarch64 GNU/Linux

II. 해결하기

  • 리눅스 PC에 Jetson 바이너리를 컴파일할 수 있는 툴체인을 설치하고 크로스 컴파일을 수행하면된다

II-1. Jetson Linux 툴체인 설치하기

Jetson Linux 툴체인 다운로드

  • 본인 컴퓨터의 OS, 아키텍처를 확인하고 ARM 툴체인을 다운받는다

Arm GNU Toolchain | GNU Arm Embedded Toolchain Downloads - Arm Developer

<https://developer.nvidia.com/gcc-linaro-731-201805-sources>

Jetson Linux 툴체인 환경설정

  • 압축을 해제하고 /opt 경로에 복사한다
$ tar -xvf gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
$ sudo cp -r gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu /opt
  • .bashrc를 편집해서 환경변수를 수정한다
    • (+) gcc —version을 확인한다
$ vim ~/.bashrc
# export PATH=/opt/gcc-linaro-7.3-2018.05.tar.xz/bin/:$PATH

$ source ~/.bashrc
$ /opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --version

#aarch64-linux-gnu-gcc (Linaro GCC 7.3-2018.05) 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701]
#Copyright (C) 2017 Free Software Foundation, Inc.
#This is free software; see the source for copying conditions.  There is NO
#warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

II-2. CMAKE 수정하기

study-space/crosscompile at master · taemin-hwang/study-space

.cmake 파일 만들기

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)

SET(COMPILER_ROOT /opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-)

SET(CMAKE_C_COMPILER ${COMPILER_ROOT}gcc)
SET(CMAKE_CXX_COMPILER ${COMPILER_ROOT}g++)
SET(CMAKE_LINKER ${COMPILER_ROOT}ld)
SET(CMAKE_NM ${COMPILER_ROOT}nm)
SET(CMAKE_OBJCOPY ${COMPILER_ROOT}objcopy)
SET(CMAKE_OBJDUMP ${COMPILER_ROOT}objdump)
SET(CMAKE_RANLIB ${COMPILER_ROOT}ranlib)

bash로 cmake 호출하기

# !/bin/bash

mkdir -p build
pushd build
  cmake -DCMAKE_TOOLCHAIN_FILE=./etc/toolchain.linux-tegra.cmake ..
  make -j2
popd
$ ./run_build.sh
~/Workspace/git/study-space/crosscompile/build ~/Workspace/git/study-space/crosscompile
-- The C compiler identification is GNU 7.3.1
-- The CXX compiler identification is GNU 7.3.1
-- Check for working C compiler: /opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
-- Check for working C compiler: /opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
-- Check for working CXX compiler: /opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/keti/Workspace/git/study-space/crosscompile/build
Scanning dependencies of target driver-tracker
Scanning dependencies of target addon
[  9%] Building CXX object addon/CMakeFiles/addon.dir/main.o
[ 18%] Building CXX object CMakeFiles/driver-tracker.dir/src/camera/camera_manager.o
[ 27%] Building CXX object CMakeFiles/driver-tracker.dir/src/driver_tracker.o
[ 36%] Linking CXX executable addon
[ 36%] Built target addon
[ 45%] Building CXX object CMakeFiles/driver-tracker.dir/src/estimator/estimator.o
[ 54%] Building CXX object CMakeFiles/driver-tracker.dir/src/main.o
[ 63%] Building CXX object CMakeFiles/driver-tracker.dir/src/transfer/messagequeue/messagequeue_manager.o
[ 72%] Building CXX object CMakeFiles/driver-tracker.dir/src/transfer/sharedmemory/sharedmemory_manager.o
[ 81%] Building CXX object CMakeFiles/driver-tracker.dir/src/transfer/socket/socket_manager.o
[ 90%] Building CXX object CMakeFiles/driver-tracker.dir/src/transfer/transfer_manager.o
[100%] Linking CXX executable driver-tracker
[100%] Built target driver-tracker
~/Workspace/git/study-space/crosscompile

II-3. Jetson에서 실행하기

  • x86_64 서버에서 빌드한 바이너리가 Jetson에서 동작한다...!
user@GTW-TX2NX-C19EBDV9:~
$ ./driver-tracker
DriverTracker
TransferManager
SocketManager::SocketManager
[1] PORT NUM  : 50001
MessageQueueManager::MessageQueueManager
[1] KEY ID    : 50002
SharedMemoryManager::SharedMemoryManager
[1] KEY ID    : 50003
[2] SIZE      : 100
SharedMemoryManager::SharedMemoryManager
[1] KEY ID    : 50004
[2] SIZE      : 140
SharedMemoryManager::SharedMemoryManager
[1] KEY ID    : 50005
[2] SIZE      : 12
Initialize
Initialize
SocketManager::Initialize
MessageQueueManager::Initialize
MessageQueue id : 0
SharedMemoryManager::Initialize
SharedMemoryManager::Initialize
SharedMemoryManager::Initialize
반응형

댓글