태그 보관물: cross-compiling

cross-compiling

내 Linux 호스트 컴퓨터에 Raspberry Pi 크로스 컴파일러를 설치하는 방법은 무엇입니까? 사용할 수있었습니다. 그러나 저는

내 Ubuntu 컴퓨터에서 작동하는 Raspberry Pi에 대한 크로스 컴파일을 시도하고 있습니다.

처음 시도하는 동안 Ubuntu 리포지토리에서 사용할 수있는 arm-linux-gnueabi 컴파일러를 사용했습니다. 나는이 일을했다. 내 모든 종속성을 구축하고 내 cmake 프로젝트에서 크로스 컴파일러를 사용할 수있었습니다.

그러나 저는 hf 버전을 사용해야한다고 생각하므로 arm-linux-gnueabihf로 전환했습니다. 그런 다음 이것이 armv6이기 때문에 Raspberry Pi에서 작동하지 않는다는 것을 깨달았습니다.

인터넷 검색 후 GitHub에서 미리 빌드 된 도구 모음 을 찾았습니다 .

툴체인을 다운로드했지만 “설치”하는 방법을 잘 모르겠습니다. 내 홈 디렉토리에 파일을 추출했습니다. 디렉토리 구조는 다음과 같습니다.

/gcc-linearo-arm-linux-gnueabihf-raspbian
    /arm-linux-gnueabihf
        /bin
            (contains g++, gcc, etc)
        /lib
            (contains libstdc++ library)
    /bin
        (contains arm-linux-gnueabihf-g++, arm-linux-gnueabihf-...)
    /lib
        (gcc lib stuff)

INNER bin 폴더로 디렉토리를 변경하면 문제없이 터미널에서 테스트 프로그램을 컴파일 할 수 있습니다.

~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/
arm-linux-gnueabihf/bin$ g++ test.cpp -o test

그런 다음 도구의 접두사 버전이 포함 된 OUTER bin 폴더에서 테스트 프로그램을 컴파일하려고했습니다.

 ~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin$
 arm-linux-gnueabihf-g++ test.cpp -o test

그러나 지금 컴파일러를 사용하려고하면 (내부 bin 디렉터리 외부에서) 도구 모음과 함께 제공되는 libstdc ++ 공유 라이브러리를 찾을 수 없습니다.

arm-linux-gnueabihf-gcc: error while loading shared libraries:
libstdc++.so.6: cannot open shared object file: No such file or directory.

또한 bin 디렉토리로 이동하지 않고도 컴파일러를 사용할 수 있기를 원합니다. 그래서 나는 OUTER bin 디렉토리 (접두사가 붙은 버전을 원하기 때문에)와 두 lib 디렉토리를 내 PATH에 추가하려고했습니다.

export PATH=$PATH:~/tools/.../bin
export PATH=$PATH:~/tools/.../lib
export PATH=$PATH:~/tools/.../.../lib

그러나 이로 인해 동일한 오류가 발생합니다. Ubuntu 리포지토리에서 크로스 컴파일러를 사용할 때와 마찬가지로 어디에서나 도구 체인을 사용할 수 있도록 도구 체인을 “설치”하려면 어떻게해야합니까?



답변

이해하기 쉽도록 튜토리얼로 작성하겠습니다.

참고 :이 자습서는 이전 raspbian 이미지에 대해서만 작동합니다. Debian Buster를 기반으로 한 최신 Raspbian의 경우이 스레드에서 다음 방법을 참조하십시오. https://stackoverflow.com/a/58559140/869402

사전 요구 사항

시작하기 전에 다음이 설치되어 있는지 확인해야합니다.

apt-get install git rsync cmake ia32-libs

파이를 크로스 컴파일합시다!

홈 디렉토리에 raspberrypi.

이 폴더로 이동하여 위에서 언급 한 전체 도구 폴더를 아래로 당깁니다.

git clone git://github.com/raspberrypi/tools.git

gcc-linaro-arm-linux-gnueabihf-raspbian내가 잘못 읽지 않았다면 다음 세 가지 중 하나를 사용하고 싶었 습니다.

홈 디렉토리로 이동하여 다음을 추가하십시오.

export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin

이름이 지정된 파일의 끝까지 ~/.bashrc

이제 로그 아웃했다가 다시 로그인하거나 (즉, 터미널 세션을 다시 시작) . ~/.bashrc터미널에서 실행 PATH하여 현재 터미널 세션에 추가 된 항목 을 선택할 수 있습니다.

이제 컴파일러에 액세스 할 수 있는지 확인합니다 arm-linux-gnueabihf-gcc -v. 다음과 같은 결과를 얻을 수 있습니다.

Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/tudhalyas/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.b
 uild/src/gcc-linaro-4.7-2012.08/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-
 linux-gnu --target=arm-linux-gnueabihf --prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-l
 inux-gnueabihf-raspbian-linux/install --with-sysroot=/cbuild/slaves/oort61/crosstool-ng/builds/
 arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fo
 rtran --disable-multilib --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=
 hard --with-pkgversion='crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08' --with-bugurl=
 https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgom
 p --enable-libssp --with-gmp=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-rasp
 bian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/cbuild/slaves/oort61/crosstool-
 ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc
 =/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-
 gnueabihf/build/static --with-ppl=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf
 -raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/cbuild/slaves/oort61/cros
 stool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --wi
 th-libelf=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/a
 rm-linux-gnueabihf/build/static --with-host-libstdcxx='-L/cbuild/slaves/oort61/crosstool-ng/bui
 lds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static/lib -lpwl' --ena
 ble-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gol
 d --with-local-prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-li
 nux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08
 )

하지만 헤이! 나는 그것을했고 libs는 여전히 작동하지 않습니다!

아직 끝나지 않았습니다! 지금까지 우리는 기본 만했습니다.

당신에 raspberrypi폴더라는 폴더를 만들어 rootfs.

이제 전체 /lib/usr디렉터리를 새로 만든이 폴더 에 복사해야 합니다. 일반적으로 rpi 이미지를 가져와 rsync를 통해 복사합니다.

rsync -rl --delete-after --safe-links pi@192.168.1.PI:/{lib,usr} $HOME/raspberrypi/rootfs

여기서 192.168.1.PI당신의 라즈베리 파이의 IP로 대체됩니다.

이제 cmake구성 파일 을 작성해야 합니다. ~/home/raspberrypi/pi.cmake좋아하는 편집기에서 열고 다음을 삽입하십시오.

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++)
SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

이제 다음과 cmake같은 추가 플래그를 추가하기 만하면 프로그램 을 컴파일 할 수 있습니다 -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake..

사용 cmake 안녕하세요 세계 예제 :

git clone https://github.com/jameskbride/cmake-hello-world.git 
cd cmake-hello-world
mkdir build
cd build
cmake -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake ../
make
scp CMakeHelloWorld pi@192.168.1.PI:/home/pi/
ssh pi@192.168.1.PI ./CMakeHelloWorld


답변

최신 Raspbian Debian Buster 이미지 및 ARMv6 용 빌드

@Stenyg의 답변은 이전 Raspbian 이미지에서만 작동합니다. Debian Buster를 기반으로 최근에 출시 된 Raspbian에는 업데이트 된 도구 모음이 필요합니다.

Debian Buster에서 gcc 컴파일러와 glibc가 버전 8.3으로 업데이트되었습니다. 의 툴체인 git://github.com/raspberrypi/tools.git은 여전히 ​​이전 gcc 6 버전을 기반으로합니다. 즉, 사용 git://github.com/raspberrypi/tools.git하면 많은 컴파일 오류가 발생합니다.

이 튜토리얼은 @Stenyg 답변을 기반으로합니다. 인터넷의 다른 많은 솔루션 외에도이 자습서는 ARMv6 CPU를 기반으로하는 이전 Rasperry Pi (A, B, B +, Zero ) 도 지원합니다 . 참고 항목 :
GCC 8 크로스 컴파일러는 ARMv6 대신 ARMv7 실행 파일을 출력합니다.

도구 모음 설정

업데이트 된 툴체인을 포함하는 공식 git 저장소는 없습니다 ( https://github.com/raspberrypi/tools/issues/102 참조 ).

GCC8 이상을 기반으로 ARMv6 용 빌드 및 미리 컴파일 된 도구 모음을 포함하는 새로운 github 저장소를 만들었습니다.

https://github.com/Pro/raspi-toolchain

프로젝트의 추가 정보에서 언급했듯이 다음은 도구 모음을 가져 오는 단계입니다. 직접 만들 수도 있습니다 (자세한 내용은 README 참조).

  1. 툴체인 다운로드 :
wget https://github.com/Pro/raspi-toolchain/releases/latest/download/raspi-toolchain.tar.gz
  1. 그것을 추출하십시오. 참고 : 도구 모음은 /opt/cross-pi-gcc위치 독립적이지 않기 때문에 안에 있어야합니다 .
sudo tar xfz raspi-toolchain.tar.gz --strip-components=1 -C /opt
  1. 완료되었습니다! 툴체인은 이제/opt/cross-pi-gcc

  2. 선택 사항으로 다음을 추가하여 경로에 도구 체인을 추가하십시오.

export PATH=$PATH:/opt/cross-pi-gcc/bin

이름이 지정된 파일의 끝까지 ~/.bashrc

이제 로그 아웃했다가 다시 로그인하거나 (즉, 터미널 세션을 다시 시작) . ~/.bashrc터미널에서 실행 PATH하여 현재 터미널 세션에 추가 된 항목 을 선택할 수 있습니다.

Raspberry PI에서 라이브러리 가져 오기

일부 사용자 지정 라이브러리가 설치되어있을 수있는 자체 Raspberry Pi에 대해 크로스 컴파일하려면 이러한 라이브러리를 호스트로 가져와야합니다.

폴더를 만듭니다 $HOME/raspberrypi. 당신에 raspberrypi폴더라는 폴더를 만들어 rootfs.

이제 전체 /lib/usr디렉터리를 새로 만든이 폴더 에 복사해야 합니다. 일반적으로 rpi 이미지를 가져와 rsync를 통해 복사합니다.

rsync -vR --progress -rl --delete-after --safe-links pi@192.168.1.PI:/{lib,usr,opt/vc/lib} $HOME/raspberrypi/rootfs

여기서 192.168.1.PI당신의 라즈베리 파이의 IP로 대체됩니다.

CMake를 사용하여 프로젝트 컴파일

CMake에 자체 도구 모음을 사용하도록 지시하려면 컴파일러 설정을 초기화하는 도구 모음 파일이 있어야합니다.

https://github.com/Pro/raspi-toolchain/blob/master/Toolchain-rpi.cmake 에서이 도구 모음 파일을 가져옵니다.

이제 cmake다음 -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake과 같은 추가 플래그를 추가 하고 올바른 환경 변수를 설정 하여 프로그램 을 컴파일 할 수 있습니다 .

export RASPBIAN_ROOTFS=$HOME/raspberry/rootfs
export PATH=/opt/cross-pi-gcc/bin:$PATH
export RASPBERRY_VERSION=1
cmake -DCMAKE_TOOLCHAIN_FILE=$HOME/raspberry/Toolchain-rpi.cmake ..

Hello World의 예는 다음과 같습니다.
https://github.com/Pro/raspi-toolchain/blob/master/build_hello_world.sh


답변

추가 할 때까지 컴파일러 ( x64버전)를 사용할 수 없습니다.sysrootSET(CMAKE_SYSROOT $ENV{HOME}/raspberrypi/rootfs)pi.cmake .


답변

Windows 호스트의 경우 다음 자습서 를 적극 권장 합니다. :

  • 도구 체인 다운로드 및 설치
  • RPi include / lib 디렉토리와 sysroot 동기화
  • 코드 컴파일
  • 다음을 사용하여 실행 파일을 RPi로 끌어다 놓습니다. SmarTTY를
  • 실행 해!

그 이상도 그 이하도 아닙니다!

Raspberry, Beaglebone, Cubieboard, AVR (Atmel) 등에 사용할 수있는 사전 빌드 된 GNU 툴체인


답변

clang 도 사용할 수 있습니다 . 예전에는 GCC보다 빠르지 만 이제는 상당히 안정적인 것입니다. 소스에서 clang을 만드는 것이 훨씬 쉽습니다 ( 빌드 과정에서 실제로 커피 한 잔을 마실 수 있습니다. ).

요컨대 :

  1. clang 바이너리 가져 오기 (sudo apt-get install clang) .. 또는 다운로드 및 빌드 ( 여기에서 지침 읽기 )
  2. 라즈베리 rootfs를 마운트하십시오 (sshfs 또는 이미지를 통해 마운트 된 실제 rootfs 일 수 있습니다).
  3. 코드를 컴파일하십시오.

    path/to/clang --target=arm-linux-gnueabihf --sysroot=/some/path/arm-linux-gnueabihf/sysroot my-happy-program.c -fuse-ld=lld

선택적으로 기존 arm-linux-gnueabihf binutils를 사용할 수 있습니다. 그런 다음 끝에 “-fuse-ld = lld”플래그를 제거 할 수 있습니다.

아래는 내 cmake 도구 모음 파일입니다.

toolchain.cmake

set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# Custom toolchain-specific definitions for your project
set(PLATFORM_ARM "1")
set(PLATFORM_COMPILE_DEFS "COMPILE_GLES")

# There we go!
# Below, we specify toolchain itself!

set(TARGET_TRIPLE arm-linux-gnueabihf)

# Specify your target rootfs mount point on your compiler host machine
set(TARGET_ROOTFS /Volumes/rootfs-${TARGET_TRIPLE})

# Specify clang paths
set(LLVM_DIR /Users/stepan/projects/shared/toolchains/llvm-7.0.darwin-release-x86_64/install)
set(CLANG ${LLVM_DIR}/bin/clang)
set(CLANGXX ${LLVM_DIR}/bin/clang++)

# Specify compiler (which is clang)
set(CMAKE_C_COMPILER   ${CLANG})
set(CMAKE_CXX_COMPILER ${CLANGXX})

# Specify binutils

set (CMAKE_AR      "${LLVM_DIR}/bin/llvm-ar" CACHE FILEPATH "Archiver")
set (CMAKE_LINKER  "${LLVM_DIR}/bin/llvm-ld" CACHE FILEPATH "Linker")
set (CMAKE_NM      "${LLVM_DIR}/bin/llvm-nm" CACHE FILEPATH "NM")
set (CMAKE_OBJDUMP "${LLVM_DIR}/bin/llvm-objdump" CACHE FILEPATH "Objdump")
set (CMAKE_RANLIB  "${LLVM_DIR}/bin/llvm-ranlib" CACHE FILEPATH "ranlib")

# You may use legacy binutils though.
#set(BINUTILS /usr/local/Cellar/arm-linux-gnueabihf-binutils/2.31.1)
#set (CMAKE_AR      "${BINUTILS}/bin/${TARGET_TRIPLE}-ar" CACHE FILEPATH "Archiver")
#set (CMAKE_LINKER  "${BINUTILS}/bin/${TARGET_TRIPLE}-ld" CACHE FILEPATH "Linker")
#set (CMAKE_NM      "${BINUTILS}/bin/${TARGET_TRIPLE}-nm" CACHE FILEPATH "NM")
#set (CMAKE_OBJDUMP "${BINUTILS}/bin/${TARGET_TRIPLE}-objdump" CACHE FILEPATH "Objdump")
#set (CMAKE_RANLIB  "${BINUTILS}/bin/${TARGET_TRIPLE}-ranlib" CACHE FILEPATH "ranlib")

# Specify sysroot (almost same as rootfs)
set(CMAKE_SYSROOT ${TARGET_ROOTFS})
set(CMAKE_FIND_ROOT_PATH ${TARGET_ROOTFS})

# Specify lookup methods for cmake
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# Sometimes you also need this:
# set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# Specify raspberry triple
set(CROSS_FLAGS "--target=${TARGET_TRIPLE}")

# Specify other raspberry related flags
set(RASP_FLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS")

# Gather and distribute flags specified at prev steps.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")

# Use clang linker. Why?
# Well, you may install custom arm-linux-gnueabihf binutils,
# but then, you also need to recompile clang, with customized triple;
# otherwise clang will try to use host 'ld' for linking,
# so... use clang linker.
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld)


답변

git : //github.com/raspberrypi/tools.git의 (상당히 오래된) 도구 모음으로 QT5를 컴파일 할 수 없습니다. 구성 스크립트는 “아키텍처를 결정할 수 없음”오류와 include 디렉토리에 대한 대규모 경로 문제로 계속 실패했습니다. 나를 위해 일한 것은 Linaro 도구 모음을 사용하는 것이 었습니다.

http://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabihf/runtime-linaro-gcc4.9-2016.02-arm-linux-gnueabihf.tar.xz

함께

https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py

sysroot의 심볼릭 링크를 수정하지 못하면 여기에 설명 된대로 정의되지 않은 기호 오류가 발생 합니다. 라즈베리 파 이용 Qt 라이브러리를 빌드하는 동안 오류가 발생
했습니다. tools.git에서 fixQualifiedLibraryPaths 스크립트를 시도했을 때 발생했습니다. 다른 모든 것은 http://wiki.qt.io/RaspberryPi2EGLFS 에 자세히 설명되어 있습니다. 내 구성 설정은 다음과 같습니다.

./configure -opengl es2 -device linux-rpi3-g ++ -device-option CROSS_COMPILE = / usr / local / rasp / gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf / bin / arm-linux-gnueabihf- -sysroot / usr / local / rasp / sysroot -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -prefix / usr / local / qt5pi -hostprefix / usr / local / qt5pi

/ usr / local / rasp / sysroot는 내 로컬 Raspberry Pi 3 Raspbian (Jessie) 시스템 복사본의 경로이고 / usr / local / qt5pi는 장치에 복사해야하는 교차 컴파일 된 QT의 경로입니다. 도구 체인을 선택할 때 Jessie는 GCC 4.9.2와 함께 제공됩니다.


답변

초기 질문은 꽤 오래 전에 게시되었으며 그 동안 데비안은 다중 아키텍처 지원 분야에서 큰 진전을 이루었습니다.

Multiarch는 크로스 컴파일을위한 훌륭한 업적입니다!

간단히 말해서 Raspbian Jessie 교차 컴파일을 위해 멀티 아크를 활용하려면 다음 단계가 필요합니다.

  • Ubuntu 호스트에서 chroot 또는 LXC 컨테이너 내에 Debian Jessie amd64를 설치합니다.
  • 외부 아키텍처 armhf를 활성화합니다.
  • emdebian 도구 저장소에서 크로스 컴파일러를 설치합니다.
  • 사용자 지정 gcc 사양 파일을 작성하여 크로스 컴파일러 (기본적으로 ARMv7-A 용 코드를 생성 함)를 조정합니다.
  • Raspbian 저장소에서 armhf 라이브러리 (libstdc ++ 등)를 설치합니다.
  • 소스 코드를 빌드하십시오.

이것은 많은 작업이기 때문에 위의 설정을 자동화했습니다. 여기에서 읽을 수 있습니다.

Raspbian 용 크로스 컴파일