Raspberry Pi

Raspberry Pi 3 のクロスコンパイル環境を crosstool-NG で構築

投稿日:2018-12-03 更新日:

はじめに

Raspberry Pi 3 上で大きなプログラムをビルドするのは非常に時間が掛かるため、Linux PC 上に Raspberry Pi 3 のクロスコンパイル環境を構築してみましょう。Raspberry Pi 3 の OS としては Raspberry Pi Foundations の公式 OS である Raspbian を使用します。ツールチェインは crosstool-NG で生成します。

crosstool-NG
https://crosstool-ng.github.io/

Crosstool-NG is a versatile (cross) toolchain generator. It supports many architectures and components and has a simple yet powerful menuconfig-style interface.

とのことで、実際、crosstool-NG では Raspberry Pi 3 のツールチェインもサポートしています。

ただし、

macOS is no longer supported

https://crosstool-ng.github.io/2018/11/26/macos.html

とのことで、今後はクロスコンパイル環境として macOS はサポートされません。

なお、2012-12-03 時点の Raspbian のベースとなっているのは Debian 9 です。今回は、

  • Ubuntu 18.04.1
  • Debian 9

にクロスコンパイル環境を構築してみました。

Ubuntu 18.04

今回使用した Ubuntu 18.04.1 は、

Download Ubuntu Desktop
https://www.ubuntu.com/download/desktop

から 2018-12-03 時点でダウンロードできるものを使用しました。

具体的には、ubuntu-18.04.1-desktop-amd64.iso です。

Debian 9

今回使用した Debian 9 は、

Downloading Debian CD/DVD images via HTTP/FTP
https://www.debian.org/CD/http-ftp/

からダウンロードできるものを使用しました。

具体的には、

https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/

からダウンロードできる CD amd64 の debian-9.6.0-amd64-xfce-CD-1.iso です。

なお、インストールした Debian 9 の情報は以下の通りです。VirtualBox 上に、2 Core CPU, 4 GB Mem, 30 GB Disk で作成しました。

今回、クロスコンパイル環境を構築した目的の 1 つは、Raspberry Pi 3 用の OpenJDK 11 のビルドなのですが、メモリ 2 GB の場合、ビルド時にメモリ不足のエラーとなりました。そのため 4 GB に設定しています。

uname -a
Linux debian 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

crosstool-NG のインストール

以下の手順は、Ubuntu 18.04.1 でも Debian 9 でも同様です。

まず、crosstool-NG をインストールするための領域を作成します。今回は /opt/cross にインストールしてみます。

sudo mkdir /opt/cross
sudo chown $USER:$GROUP /opt/cross

続いて、必要なパッケージをインストールし、GitHub から crosstool-NG をクローンし、ビルドし、インストールします。

sudo apt-get -y install git autoconf gcc bison flex texinfo help2man gawk make libtool-bin libncurses5-dev g++ python-dev
git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
./bootstrap
./configure --prefix=/opt/cross
make -j$(nproc)
sudo make install

パスを通しておきます。

export PATH=$PATH:/opt/cross/bin

ツールチェインの生成

Raspberry Pi 3 のツールチェインを生成します。まず、適当な作業領域を作成します。

mkdir ~/ctng
cd ~/ctng

update-samples を実行します。

ct-ng update-samples

アップデートが完了すれば、list-samples を実行し、サンプルの一覧を表示させます。

ct-ng list-samples

実行結果です。armv8-rpi3-linux-gnueabihf が存在することを確認します。これが Raspberry Pi 3 のツールチェインです。

Status  Sample name
[G..]   aarch64-rpi3-linux-gnu
[G.X]   aarch64-unknown-linux-android
[G..]   aarch64-unknown-linux-gnu
[G..]   aarch64-unknown-linux-uclibc
[G..]   alphaev56-unknown-linux-gnu
[G..]   alphaev67-unknown-linux-gnu
[G..]   arc-arc700-linux-uclibc
[G..]   arc-multilib-elf32
[G..]   arc-multilib-linux-uclibc
[G..]   arm-bare_newlib_cortex_m3_nommu-eabi
[G..]   arm-cortex_a15-linux-gnueabihf
[G..]   arm-cortex_a8-linux-gnueabi
[G.X]   arm-cortexa5-linux-uclibcgnueabihf
[G.X]   arm-cortexa9_neon-linux-gnueabihf
[G.X]   x86_64-w64-mingw32,arm-cortexa9_neon-linux-gnueabihf
[G..]   arm-multilib-linux-uclibcgnueabi
[G..]   arm-nano-eabi
[G..]   arm-unknown-eabi
[G..]   arm-unknown-linux-gnueabi
[G.X]   arm-unknown-linux-musleabi
[G..]   arm-unknown-linux-uclibcgnueabi
[G.X]   arm-unknown-linux-uclibcgnueabihf
[G..]   armeb-unknown-eabi
[G..]   armeb-unknown-linux-gnueabi
[G..]   armeb-unknown-linux-uclibcgnueabi
[G..]   armv6-nommu-linux-uclibcgnueabi
[G..]   armv6-rpi-linux-gnueabi
[G..]   armv7-rpi2-linux-gnueabihf
[G..]   armv8-rpi3-linux-gnueabihf
[G..]   avr
[G..]   i586-geode-linux-uclibc
[G..]   i686-centos6-linux-gnu
[G..]   i686-centos7-linux-gnu
[G..]   i686-nptl-linux-gnu
[G..]   i686-ubuntu12.04-linux-gnu
[G..]   i686-ubuntu14.04-linux-gnu
[G..]   i686-ubuntu16.04-linux-gnu
[G.X]   i686-w64-mingw32
[G..]   m68k-unknown-elf
[G..]   m68k-unknown-uclinux-uclibc
[G..]   powerpc-unknown-linux-uclibc,m68k-unknown-uclinux-uclibc
[G..]   mips-ar2315-linux-gnu
[G..]   mips-malta-linux-gnu
[G..]   mips-unknown-elf
[G..]   mips-unknown-linux-uclibc
[G..]   mips64el-multilib-linux-uclibc
[G..]   mipsel-multilib-linux-gnu
[G..]   mipsel-sde-elf
[G..]   mipsel-unknown-linux-gnu
[GBX]   moxie-unknown-elf
[G.X]   moxie-unknown-moxiebox
[G.X]   x86_64-multilib-linux-uclibc,moxie-unknown-moxiebox
[G.X]   msp430-unknown-elf
[G..]   nios2-altera-linux-gnu
[G.X]   i686-w64-mingw32,nios2-spico-elf
[G..]   nios2-unknown-elf
[G..]   powerpc-405-linux-gnu
[G..]   powerpc-860-linux-gnu
[G..]   powerpc-e300c3-linux-gnu
[G..]   powerpc-e500v2-linux-gnuspe
[G..]   x86_64-multilib-linux-uclibc,powerpc-unknown-elf
[G..]   powerpc-unknown-linux-gnu
[G..]   powerpc-unknown-linux-uclibc
[G..]   powerpc-unknown_nofpu-linux-gnu
[G..]   powerpc64-multilib-linux-gnu
[G..]   powerpc64-unknown-linux-gnu
[G..]   powerpc64le-unknown-linux-gnu
[G.X]   riscv32-hifive1-elf
[G.X]   riscv32-unknown-elf
[G.X]   riscv64-unknown-elf
[G.X]   riscv64-unknown-linux-gnu
[G.X]   s390-ibm-linux-gnu
[G..]   s390x-ibm-linux-gnu
[G..]   sh-multilib-linux-gnu
[G..]   sh-multilib-linux-uclibc
[G..]   sh-unknown-elf
[G..]   sparc-leon-linux-uclibc
[G..]   sparc-unknown-linux-gnu
[G..]   sparc64-multilib-linux-gnu
[G..]   x86_64-centos6-linux-gnu
[G..]   x86_64-centos7-linux-gnu
[G..]   x86_64-multilib-linux-gnu
[G.X]   x86_64-multilib-linux-musl
[G..]   x86_64-multilib-linux-uclibc
[G.X]   x86_64-w64-mingw32,x86_64-pc-linux-gnu
[G..]   x86_64-ubuntu12.04-linux-gnu
[G..]   x86_64-ubuntu14.04-linux-gnu
[G..]   x86_64-ubuntu16.04-linux-gnu
[G..]   x86_64-unknown-linux-gnu
[G..]   x86_64-unknown-linux-uclibc
[G.X]   x86_64-w64-mingw32
[G..]   xtensa-fsf-linux-uclibc
 L (Local)       : sample was found in current directory
 G (Global)      : sample was installed with crosstool-NG
 X (EXPERIMENTAL): sample may use EXPERIMENTAL features
 B (BROKEN)      : sample is currently broken

設定ファイルを生成させます。

ct-ng armv8-rpi3-linux-gnueabihf

実行結果です。

  CONF  armv8-rpi3-linux-gnueabihf
#
# configuration written to .config
#

***********************************************************

(snip)

Comment:
crosstool-NG configuration for Raspberry Pi 3.

***********************************************************

Now configured for "armv8-rpi3-linux-gnueabihf"

詳細な設定をしたい場合、

ct-ng menuconfig

を実行すると、Crosstool-NG Configuration が起動します。

今回、クロスコンパイル環境を構築した目的の 1 つは、Raspberry Pi 3 用の OpenJDK 11 のビルドなのですが、armv8-rpi3-linux-gnueabihf のデフォルトでは glibc が 2.28 であり、一方で 2018-12-03 時点の Raspbian の glibc は 2.24 です。そのため、このデフォルト設定でクロスコンパイルした OpenJDK 11 は Raspbian では動作しません。よって、OpenJDK 11 をクロスコンパイルしたい場合、Crosstool-NG Configuration で glibc のバージョンを変更します。

Crosstool-NG Configuration の C-library ---> Version 0f glibc を確認すると、デフォルトでは 2。28 となっています。ここを 2.24 に変更し、Save します。

最後に、ツールチェインを生成します。

ct-ng build

実行結果です。Core i3 の Linux PC 上の VirtualBox 上で、50 分程度掛かりました。

作業用ディレクトリと同じ階層に、x-tools/armv8-rpi3-linux-gnueabihf という名前のディレクトリが生成されました。

[INFO ]  Performing some trivial sanity checks
[INFO ]  Build started 20181203.215712
[INFO ]  Building environment variables
[WARN ]  Directory 'src' does not exist.
[WARN ]  Will not save downloaded tarballs to local storage.
[EXTRA]  Preparing working directories
[EXTRA]  Installing user-supplied crosstool-NG configuration
[EXTRA]  =================================================================
[EXTRA]  Dumping internal crosstool-NG configuration
[EXTRA]    Building a toolchain for:
[EXTRA]      build  = x86_64-pc-linux-gnu
[EXTRA]      host   = x86_64-pc-linux-gnu
[EXTRA]      target = armv8-rpi3-linux-gnueabihf
[EXTRA]  Dumping internal crosstool-NG configuration: done in 0.08s (at 00:02)
[INFO ]  =================================================================
[INFO ]  Retrieving needed toolchain components' tarballs
[INFO ]  Retrieving needed toolchain components' tarballs: done in 0.42s (at 00:03)
[INFO ]  =================================================================
[INFO ]  Extracting and patching toolchain components
[INFO ]  Extracting and patching toolchain components: done in 0.51s (at 00:03)
[INFO ]  =================================================================
[INFO ]  Installing autoconf for build
[EXTRA]    Configuring autoconf
[EXTRA]    Building autoconf
[EXTRA]    Installing autoconf
[INFO ]  Installing autoconf for build: done in 2.68s (at 00:06)
[INFO ]  =================================================================
[INFO ]  Installing automake for build
[EXTRA]    Configuring automake
[EXTRA]    Building automake
[EXTRA]    Installing automake
[INFO ]  Installing automake for build: done in 2.34s (at 00:08)
[INFO ]  =================================================================
[INFO ]  Installing ncurses for build
[EXTRA]    Configuring ncurses
[EXTRA]    Building ncurses
[EXTRA]    Installing ncurses
[INFO ]  Installing ncurses for build: done in 17.55s (at 00:26)
[INFO ]  =================================================================
[INFO ]  Installing GMP for host
[EXTRA]    Configuring GMP
[EXTRA]    Building GMP
[EXTRA]    Installing GMP
[INFO ]  Installing GMP for host: done in 40.89s (at 01:07)
[INFO ]  =================================================================
[INFO ]  Installing MPFR for host
[EXTRA]    Configuring MPFR
[EXTRA]    Building MPFR
[EXTRA]    Installing MPFR
[INFO ]  Installing MPFR for host: done in 34.37s (at 01:41)
[INFO ]  =================================================================
[INFO ]  Installing ISL for host
[EXTRA]    Configuring ISL
[EXTRA]    Building ISL
[EXTRA]    Installing ISL
[INFO ]  Installing ISL for host: done in 27.00s (at 02:08)
[INFO ]  =================================================================
[INFO ]  Installing MPC for host
[EXTRA]    Configuring MPC
[EXTRA]    Building MPC
[EXTRA]    Installing MPC
[INFO ]  Installing MPC for host: done in 7.04s (at 02:15)
[INFO ]  =================================================================
[INFO ]  Installing expat for host
[EXTRA]    Configuring expat
[EXTRA]    Building expat
[EXTRA]    Installing expat
[INFO ]  Installing expat for host: done in 6.09s (at 02:21)
[INFO ]  =================================================================
[INFO ]  Installing ncurses for host
[EXTRA]    Configuring ncurses
[EXTRA]    Building ncurses
[EXTRA]    Installing ncurses
[INFO ]  Installing ncurses for host: done in 17.12s (at 02:38)
[INFO ]  =================================================================
[INFO ]  Installing libiconv for host
[EXTRA]    Skipping (included in GNU C library)
[INFO ]  Installing libiconv for host: done in 0.01s (at 02:38)
[INFO ]  =================================================================
[INFO ]  Installing gettext for host
[EXTRA]    Skipping (included in GNU C library)
[INFO ]  Installing gettext for host: done in 0.01s (at 02:38)
[INFO ]  =================================================================
[INFO ]  Installing binutils for host
[EXTRA]    Configuring binutils
[EXTRA]    Building binutils
[EXTRA]    Installing binutils
[EXTRA]    Installing ld wrapper
[INFO ]  Installing binutils for host: done in 230.03s (at 06:28)
[INFO ]  =================================================================
[INFO ]  Installing pass-1 core C gcc compiler
[EXTRA]    Configuring core C gcc compiler
[EXTRA]    Building gcc
[EXTRA]    Installing gcc
[EXTRA]    Housekeeping for core gcc compiler
[EXTRA]       '' --> lib (gcc)   lib (os)
[INFO ]  Installing pass-1 core C gcc compiler: done in 496.09s (at 14:45)
[INFO ]  =================================================================
[INFO ]  Installing kernel headers
[EXTRA]    Installing kernel headers
[EXTRA]    Checking installed headers
[INFO ]  Installing kernel headers: done in 7.63s (at 14:52)
[INFO ]  =================================================================
[INFO ]  Installing C library headers & start files
[INFO ]    =================================================================
[INFO ]    Building for multilib 1/1: ''
[EXTRA]      Configuring C library
[EXTRA]      Installing C library headers
[EXTRA]      Installing C library start files
[INFO ]    Building for multilib 1/1: '': done in 9.08s (at 15:01)
[INFO ]  Installing C library headers & start files: done in 9.14s (at 15:01)
[INFO ]  =================================================================
[INFO ]  Installing pass-2 core C gcc compiler
[EXTRA]    Configuring core C gcc compiler
[EXTRA]    Building gcc
[EXTRA]    Installing gcc
[EXTRA]    Housekeeping for core gcc compiler
[EXTRA]       '' --> lib (gcc)   lib (os)
[INFO ]  Installing pass-2 core C gcc compiler: done in 598.47s (at 25:00)
[INFO ]  =================================================================
[INFO ]  Installing C library
[INFO ]    =================================================================
[INFO ]    Building for multilib 1/1: ''
[EXTRA]      Cleaning up start files
[EXTRA]      Configuring C library
[EXTRA]      Building C library
[EXTRA]      Installing C library
[INFO ]    Building for multilib 1/1: '': done in 299.27s (at 29:59)
[INFO ]  Installing C library: done in 299.33s (at 29:59)
[INFO ]  =================================================================
[INFO ]  Installing final gcc compiler
[EXTRA]    Configuring final gcc compiler
[EXTRA]    Building final gcc compiler
[EXTRA]    Installing final gcc compiler
[EXTRA]    Housekeeping for final gcc compiler
[EXTRA]       '' --> lib (gcc)   lib (os)
[INFO ]  Installing final gcc compiler: done in 731.43s (at 42:11)
[INFO ]  =================================================================
[INFO ]  Installing cross-gdb
[EXTRA]    Configuring cross-gdb
[EXTRA]    Building cross-gdb
[EXTRA]    Installing cross-gdb
[EXTRA]    Installing '.gdbinit' template
[INFO ]  Installing cross-gdb: done in 250.41s (at 46:21)
[INFO ]  =================================================================
[INFO ]  Installing gdbserver
[EXTRA]    Configuring gdbserver
[EXTRA]    Building gdbserver
[EXTRA]    Installing gdbserver
[INFO ]  Installing gdbserver: done in 48.50s (at 47:10)
[INFO ]  =================================================================
[INFO ]  Finalizing the toolchain's directory
[INFO ]    Stripping all toolchain executables
[EXTRA]    Installing the populate helper
[EXTRA]    Installing a cross-ldd helper
[EXTRA]    Creating toolchain aliases
[EXTRA]    Removing installed documentation
[EXTRA]    Collect license information from: ctng/.build/armv8-rpi3-linux-gnueabihf/src
[EXTRA]    Put the license information to: x-tools/armv8-rpi3-linux-gnueabihf/share/licenses
[INFO ]  Finalizing the toolchain's directory: done in 5.93s (at 47:16)
[INFO ]  Build completed at 20181203.224428
[INFO ]  (elapsed: 47:15.35)
[INFO ]  Finishing installation (may take a few seconds)...
[47:16] /

エラーとその対処

bootstrap, configure, ct-ng build 実行時に発生したエラーとその対処法です。Debian 9 や Ubuntu 18.04 で発生しました。

INFO  :: *** Running autoreconf
./bootstrap: line 803: autoreconf: command not found

sudo apt-get -y install autoconf
configure: error: no acceptable C compiler found in $PATH

sudo apt-get -y install gcc
checking for bison... no
configure: error: missing required tool: bison

sudo apt-get -y install bison
checking for flex... no
configure: error: missing required tool: flex

sudo apt-get -y install flex
checking for makeinfo... no
configure: error: missing required tool: makeinfo

sudo apt-get -y install texinfo
checking for help2man... no
configure: error: missing required tool: help2man

sudo apt-get -y install help2man
checking for GNU awk... no
configure: error: Required tool not found: GNU awk

sudo apt-get -y install gawk
checking for GNU make >= 3.81... no
configure: error: Required tool not found: make

sudo apt-get -y install make
checking for GNU libtool >= 2.4... no
configure: error: Required tool not found: libtool

sudo apt-get -y install libtool-bin
checking for Curses library... no
configure: error: curses library not found

sudo apt-get -y install libncurses5-dev
[INFO ]  Performing some trivial sanity checks
[INFO ]  Build started 20181203.203908
[INFO ]  Building environment variables
[WARN ]  Directory 'src' does not exist.
[WARN ]  Will not save downloaded tarballs to local storage.
[EXTRA]  Preparing working directories
[ERROR]    collect2: error: ld returned 1 exit status
[ERROR]   
[ERROR]  >>
[ERROR]  >>  Build failed in step 'Checking that gcc can statically link libstdc++ (CT_WANTS_STATIC_LINK_CXX)'
[ERROR]  >>        called in step '(top-level)'
[ERROR]  >>
[ERROR]  >>  Error happened in: CT_DoExecLog[scripts/functions@374]
[ERROR]  >>        called from: main[scripts/crosstool-NG.sh@609]
[ERROR]  >>
[ERROR]  >>  For more info on this error, look at the file: 'build.log'
[ERROR]  >>  There is a list of known issues, some with workarounds, in:
[ERROR]  >>      https://crosstool-ng.github.io/docs/known-issues/
[ERROR]  >>
[ERROR]  >>  If you feel this is a bug in crosstool-NG, report it at:
[ERROR]  >>      https://github.com/crosstool-ng/crosstool-ng/issues/
[ERROR]  >>
[ERROR]  >>  Make sure your report includes all the information pertinent to this issue.
[ERROR]  >>  Read the bug reporting guidelines here:
[ERROR]  >>      http://crosstool-ng.github.io/support/
[ERROR]   
[ERROR]  (elapsed: 0:00.67)
[00:01] / /opt/cross/bin/ct-ng:236: recipe for target 'build' failed
make: *** [build] Error 1

sudo apt-get -y install g++
checking for gperf... no
configure: error: missing required tool: gperf

sudo apt-get -y install gperf
checking for curses.h... no
configure: error: could not find curses header, required for the kconfig frontends

sudo apt-get install libncurses5-dev
[INFO ]  Installing final gcc compiler: done in 733.90s (at 48:32)
[INFO ]  =================================================================
[INFO ]  Installing cross-gdb
[EXTRA]    Configuring cross-gdb
[EXTRA]    Building cross-gdb
[ERROR]    configure: error: no usable python found at /usr/bin/python
[ERROR]    make[2]: *** [configure-gdb] Error 1
[ERROR]    make[1]: *** [all] Error 2
[ERROR]   
[ERROR]  >>
[ERROR]  >>  Build failed in step 'Installing cross-gdb'
[ERROR]  >>        called in step '(top-level)'
[ERROR]  >>
[ERROR]  >>  Error happened in: CT_DoExecLog[scripts/functions@374]
[ERROR]  >>        called from: do_debug_gdb_build[scripts/build/debug/300-gdb.sh@156]
[ERROR]  >>        called from: do_debug[scripts/build/debug.sh@35]
[ERROR]  >>        called from: main[scripts/crosstool-NG.sh@682]
[ERROR]  >>
[ERROR]  >>  For more info on this error, look at the file: 'build.log'
[ERROR]  >>  There is a list of known issues, some with workarounds, in:
[ERROR]  >>      https://crosstool-ng.github.io/docs/known-issues/
[ERROR]  >>
[ERROR]  >>  If you feel this is a bug in crosstool-NG, report it at:
[ERROR]  >>      https://github.com/crosstool-ng/crosstool-ng/issues/
[ERROR]  >>
[ERROR]  >>  Make sure your report includes all the information pertinent to this issue.
[ERROR]  >>  Read the bug reporting guidelines here:
[ERROR]  >>      http://crosstool-ng.github.io/support/
[ERROR]   
[ERROR]  (elapsed: 49:29.65)
[49:30] / /opt/cross/bin/ct-ng:236: recipe for target 'build' failed
make: *** [build] Error 2

sudo apt-get install -y python-dev
[INFO ]  Installing cross-gdb
[EXTRA]    Configuring cross-gdb
[EXTRA]    Building cross-gdb
[ERROR]    configure: error: no usable python found at /usr/bin/python
[ERROR]    make[2]: *** [configure-gdb] Error 1
[ERROR]    make[1]: *** [all] Error 2

sudo apt-get install -y python-dev

リリースバージョンではなく GitHub のソースコードを使用する理由

2018-12-03 時点では crosstool-NG のリリースバージョンは、1.23.0 です。しかし、私の環境では、Ubuntu 18.04 を使用した場合に下記のようなエラーが発生しました。Debian 9 でも発生するかどうかは確かめていません。

[ERROR]   /ctng/.build/src/gcc-6.3.0/gcc/ubsan.c:1474:23: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

詳細は下記に。

https://github.com/crosstool-ng/crosstool-ng/issues/992

-Raspberry Pi

Copyright© hirooka.pro , 2013-2018 All Rights Reserved.