Raspberry Pi

Raspberry Pi 3 用の OpenJDK 11 をクロスコンパイルで作成

投稿日:

はじめに

オラクルの Java 11 では以前のバージョンと比較してライセンスや提供形態の面で大きな変化がありました。

それはさておき、Raspberry Pi Foundation の公式 OS である Raspbian で Java 11 のアプリケーションを動かしてみます。

しかし! Raspberry Pi の CPU は ARM です! Raspbian は Debian ベースですが、32bit OS です! Raspbian は hard-foat です!

しかも! OpenJDK 11 のダウンロードサイト https://jdk.java.net/11/ では、Linux, macOS, Windows の 64 bit 向けのバイナリしか提供されていません。

その背景としては、2018 年 5 月のオラクルのブログを見てみます。

https://blogs.oracle.com/jtc/build-jdk-10-for-your-raspberry-pi-right-on-your-device

オラクルは JDK 9 以降、サポートするハードウェアや OS を減らしました。32bit 版は提供されませんし、Raspberry Pi を含む ARM 向けのバイナリも提供されません。しかし、ソースコードには、32bit armhf もサポートするように組み込まれているようです。ただし、言及されているのは OpenJDK 10 までであり、OpenJDK 11 については言及されていません。このオラクルのブログ記事が 2018 年 5 月のものですし。それはさておき、つまり、Raspberry Pi のようなデバイスでも最新の Java を動かすには 2 つの選択肢が存在することになります。

  1. 自分が望むものを誰かがビルドして提供してくれるのを待つ
  2. 自分でビルドする

1 のような都合の良い話は無いでしょう。そのため、Raspberry Pi で OpenJDK 11 を動かしたい場合、ソースコードを取得して自分でビルドしなければなりません。しかし、非力な計算能力である Raspberry Pi 上での OpenJDK 11 のビルドは、非常に時間がかかることが予想されます。

その課題を解決するために、Linux PC 上に Raspberry Pi のツールチェーンを作成し、クロスコンパイル環境を構築し、Linux PC 上で Raspberry Pi 用の OpenJDK 11 をビルドします。

今回使用する Raspberry Pi は、Raspberry Pi 3 Model B です。

Raspbian は、Raspbian Stretch Lite の Version:November 2018 です。

ちなみに、Raspberry Pi Foundation の公式 OS である、Debian ベースの Raspbian は 32bit であり、当分 64bit はサポートしない雰囲気です。

https://www.raspberrypi.org/blog/raspbian-stretch/

https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=208314

よって、Raspbian on Raspberry Pi で動くように、ARM hard-float 32bit 用の OpenJDK 11 をビルドします。

なお、このポストでは、java.net で提供されるオラクルの OpenJDK 11 を、単に OpenJDK 11 と記述しています。

クロスコンパイル環境を構築した OS

  • Ubuntu 18.04.1
  • Debian 9

VirtualBox 上に、2 Core CPU, 4 GB Mem, 30 GB Disk で作成しました。私の環境では、メモリ 2 GB の場合、ビルド時にメモリ不足のエラーとなりました。

クロスコンパイル環境の構築

Ubuntu 18.04.1、Debian 9 で、crosstool-NG の Raspberry Pi 3 用のツールチェーンを使用してクロスコンパイル環境を構築したメモです。注意点としては、下記のメモ中にもあるように、glibc のバージョンを 2.24 に設定する必要があります。

Raspberry Pi 3 のクロスコンパイル環境を crosstool-NG で構築
https://hirooka.pro/?p=10158

OpenJDK 11 のビルドに必要なパッケージのダウンロード

Raspberry Pi 向けに OpenJDK 11 をビルドするために必要な armhf のパッケージをダウンロードして展開しておきます。なお、各パッケージのバージョンは、2018−12−02 時点のものです。

最新のものは、

https://www.debian.org/distrib/packages

で検索してみてください。

作業用に適当なディレクトリを作成します。

mkdir ~/openjdk11tmp

作成したディレクトリにパッケージを放り込んでいきます。

ALSA, Advanced Linux Sound Architecture

mkdir ~/openjdk11tmp/alsa
cd ~/openjdk11tmp/alsa
curl -O http://ftp.jp.debian.org/debian/pool/main/a/alsa-lib/libasound2_1.1.3-5_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/a/alsa-lib/libasound2-dev_1.1.3-5_armhf.deb
mkdir ~/x-tools/alsa
cd ~/x-tools/alsa
dpkg-deb -x ~/openjdk11tmp/alsa/libasound2_1.1.3-5_armhf.deb .
dpkg-deb -x ~/openjdk11tmp/alsa/libasound2-dev_1.1.3-5_armhf.deb .

X11

mkdir ~/openjdk11tmp/x11
cd ~/openjdk11tmp/x11
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxi/libxi6_1.7.9-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxi/libxi-dev_1.7.9-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/x/x11proto-core/x11proto-core-dev_7.0.31-1_all.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/x/x11proto-input/x11proto-input-dev_2.3.2-1_all.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/x/x11proto-kb/x11proto-kb-dev_1.0.7-1_all.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/x/x11proto-render/x11proto-render-dev_0.11.1-2_all.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/x/x11proto-xext/x11proto-xext-dev_7.3.0-1_all.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libi/libice/libice-dev_1.0.9-2_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxrender/libxrender1_0.9.10-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxrender/libxrender-dev_0.9.10-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libs/libsm/libsm-dev_1.2.2-1+b3_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxt/libxt-dev_1.1.5-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libx11/libx11-6_1.6.4-3+deb9u1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libx11/libx11-dev_1.6.4-3+deb9u1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxtst/libxtst6_1.2.3-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxtst/libxtst-dev_1.2.3-1_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxext/libxext6_1.3.3-1+b2_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/libx/libxext/libxext-dev_1.3.3-1+b2_armhf.deb
mkdir ~/x-tools/x11
cd ~/x-tools/x11
for deb in ~/openjdk11tmp/x11/*.deb ; do dpkg-deb -x $deb . ; done

この際、libICE.so libSM.so libXt.so へのシンボリックリンクが張られていませんが、ビルドには影響しないため、気にしないでください。

CUPS, Common UNIX Printing System

mkdir ~/openjdk11tmp/cups
cd ~/openjdk11tmp/cups
curl -O http://ftp.jp.debian.org/debian/pool/main/c/cups/libcups2-dev_2.2.1-8+deb9u2_armhf.deb
mkdir ~/x-tools/cups
cd ~/x-tools/cups
dpkg-deb -x ~/openjdk11tmp/cups/libcups2-dev_2.2.1-8+deb9u2_armhf.deb .

fontconfig

mkdir ~/openjdk11tmp/fontconfig
cd ~/openjdk11tmp/fontconfig
curl -O http://ftp.jp.debian.org/debian/pool/main/f/fontconfig/libfontconfig1-dev_2.11.0-6.7+b1_armhf.deb
mkdir ~/x-tools/fontconfig
cd ~/x-tools/fontconfig
dpkg-deb -x ~/openjdk11tmp/fontconfig/libfontconfig1-dev_2.11.0-6.7+b1_armhf.deb .

cupsimage2

mkdir ~/openjdk11tmp/cupsimage2
cd ~/openjdk11tmp/cupsimage2
curl -O http://ftp.jp.debian.org/debian/pool/main/c/cups/libcupsimage2-dev_2.2.1-8+deb9u2_armhf.deb
dpkg-deb -x libcupsimage2-dev_2.2.1-8+deb9u2_armhf.deb .
cp usr/include/cups/* ~/x-tools/cups/usr/include/cups/
cp usr/lib/arm-linux-gnueabihf/* ~/x-tools/cups/usr/lib/arm-linux-gnueabihf/

下記のようなメッセージが表示されるかもしれませんが、ビルドには影響しないため、気にしないでください。

cp: cannot stat 'usr/lib/arm-linux-gnueabihf/libcupsimage.so': No such file or directory

freetype2

mkdir ~/openjdk11tmp/freetype2
cd ~/openjdk11tmp/freetype2
curl -O http://ftp.jp.debian.org/debian/pool/main/f/freetype/libfreetype6_2.6.3-3.2_armhf.deb
curl -O http://ftp.jp.debian.org/debian/pool/main/f/freetype/libfreetype6-dev_2.6.3-3.2_armhf.deb
mkdir ~/x-tools/freetype2
cd ~/x-tools/freetype2
dpkg-deb -x ~/openjdk11tmp/freetype2/libfreetype6_2.6.3-3.2_armhf.deb .
dpkg-deb -x ~/openjdk11tmp/freetype2/libfreetype6-dev_2.6.3-3.2_armhf.deb .

Linux 向けの OpenJDK 11 のインストール

OpenJDK 11 をソースコードからビルドするためには、予めビルドを行うコンピュータに OpenJDK のバイナリがインストールされていることが必要です。そのため、Linux 向けの OpenJDK 11 のバイナリをインストールしておきます。例えば、下記の通り。

cd /tmp
curl -O https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz
sudo mkdir /usr/lib/jvm
sudo tar zxvf openjdk-11.0.1_linux-x64_bin.tar.gz -C /usr/lib/jvm/
sudo sh -c "echo 'export JAVA_HOME=/usr/lib/jvm/jdk-11.0.1' >> /etc/profile.d/jdk.sh"
sudo sh -c "echo 'export PATH=\$JAVA_HOME/bin:\$PATH' >> /etc/profile.d/jdk.sh"
source /etc/profile.d/jdk.sh

OpenJDK 11 のソースコードのダウンロード

続いて、OpenJDK 11 のソースコードをダウンロードします。OpenJDK 11 のソースコードは、Mercurial で管理されています。そのため、APT でインストールします。

sudo apt-get -y install mercurial

適当な作業用ディレクトリを作成し、hg コマンドで OpenJDK 11 のソースコードをダウンロードします。例えば下記の通り。この例ではバージョン 11.0.1 としてリリースされたタグを指定してダウンロードしています。

mkdir ~/openjdk11build
cd ~/openjdk11build
hg clone -r jdk-11.0.1+13 https://hg.openjdk.java.net/jdk-updates/jdk11u

これが曲者で、私の環境では何度もダウンロードに途中で失敗しました。何度も何度も繰り返し、数時間以上要しました。私の Mercurial の使い方が適切ではないのでしょうか。

destination directory: jdk11u
adding changesets
adding manifests                                                                                                                                                                                               
adding file changes                                                                                                                                                                                            
added 51300 changesets with 442215 changes to 178405 files                                                                                                                                                     
new changesets fd16c54261b3:8513ac27b651
updating to branch default
(warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
66158 files updated, 0 files merged, 0 files removed, 0 files unresolved

OpenJDK 11 のビルド

いよいよビルドです。

cd ~/openjdk11build/jdk11u
chmod 755 configure
./configure --openjdk-target=armv8-rpi3-linux-gnueabihf \
  --with-tools-dir=/home/$USER/x-tools/armv8-rpi3-linux-gnueabihf/bin \
  --with-alsa=/home/$USER/x-tools/alsa/usr \
  --with-alsa-include=/home/$USER/x-tools/alsa/usr/include \
  --with-alsa-lib=/home/$USER/x-tools/alsa/usr/lib/arm-linux-gnueabihf \
  --with-x=/home/$USER/x-tools/x11/usr \
  --x-includes=/home/$USER/x-tools/x11/usr/include \
  --x-libraries=/home/$USER/x-tools/x11/usr/lib/arm-linux-gnueabihf \
  --with-cups=/home/$USER/x-tools/cups/usr \
  --with-fontconfig=/home/$USER/x-tools/fontconfig/usr \
  --disable-warnings-as-errors \
  --with-freetype-include=/home/$USER/x-tools/freetype2/usr/include \
  --with-freetype-lib=/home/$USER/x-tools/freetype2/usr/lib/arm-linux-gnueabihf
make JOBS=$(nproc)

ビルドが完了すると、下記のようなメッセージが表示されます。

Finished building target 'default (exploded-image)' in configuration 'linux-arm-normal-server-release'

build という名前のディレクトリが作成され、その下に linux-arm-normal-server-release という名前のディレクトリが作成されます。

ディレクトリの内容は、

ls -al build/linux-arm-normal-server-release/

total 284
drwxr-xr-x  8 hirooka hirooka  4096 12月  2 11:12 .
drwxr-xr-x  4 hirooka hirooka  4096 11月 28 23:30 ..
-rw-r--r--  1 hirooka hirooka  2681 12月  2 11:12 bootcycle-spec.gmk
-rw-r--r--  1 hirooka hirooka  7254 12月  2 11:12 buildjdk-spec.gmk
-rw-r--r--  1 hirooka hirooka 69553 12月  2 11:12 build.log
-rw-r--r--  1 hirooka hirooka  1022 12月  2 11:11 build.log.old
drwxr-xr-x 12 hirooka hirooka  4096 12月  2 03:40 buildtools
-rwxr-xr-x  1 hirooka hirooka  3841 12月  2 11:12 compare.sh
-rw-r--r--  1 hirooka hirooka 16654 12月  2 11:12 configure.log
-rw-r--r--  1 hirooka hirooka 99638 12月  2 10:45 configure.log.old
drwxr-xr-x  2 hirooka hirooka  4096 12月  2 11:12 configure-support
drwxr-xr-x  3 hirooka hirooka  4096 12月  2 03:34 hotspot
drwxr-xr-x  7 hirooka hirooka  4096 12月  2 03:47 jdk
-rw-r--r--  1 hirooka hirooka  1279 12月  2 11:12 Makefile
drwxr-xr-x  6 hirooka hirooka  4096 12月  2 11:12 make-support
-rw-r--r--  1 hirooka hirooka 37810 12月  2 11:12 spec.gmk
drwxr-xr-x 13 hirooka hirooka  4096 12月  2 03:47 support

さらにその下の jdk ディレクトリの内容は、

ls -al build/linux-arm-normal-server-release/jdk/

total 32
drwxr-xr-x  7 hirooka hirooka 4096 12月  2 03:47 .
drwxr-xr-x  8 hirooka hirooka 4096 12月  2 11:12 ..
drwxr-xr-x  2 hirooka hirooka 4096 12月  2 03:47 bin
drwxr-xr-x  4 hirooka hirooka 4096 12月  2 03:34 conf
drwxr-xr-x  3 hirooka hirooka 4096 12月  2 03:34 include
drwxr-xr-x  6 hirooka hirooka 4096 12月  2 11:12 lib
drwxr-xr-x 68 hirooka hirooka 4096 12月  2 03:42 modules
-rw-r--r--  1 hirooka hirooka  104 12月  2 03:34 release

Raspberry Pi (Raspbian) での動作確認

ビルドで作成された OpenJDK 11 を tar で固めて圧縮するなりして、SSH なりで Raspberry Pi へ送信します。例えば下記の通り。

cd build
tar zcvf linux-arm-normal-server-release.tar.gz linux-arm-normal-server-release
scp linux-arm-normal-server-release.tar.gz pi@192.168.xxx.yyy:/home/pi/

Raspberry Pi にログインし、送信されたファイルを解凍し、java コマンドを実行してみます。

tar zxvf linux-arm-normal-server-release.tar.gz
./linux-arm-normal-server-release/jdk/bin/java --version

実行結果です。

openjdk 11.0.1-internal 2018-10-16
OpenJDK Runtime Environment (build 11.0.1-internal+0-adhoc.hirooka.jdk11u)
OpenJDK Server VM (build 11.0.1-internal+0-adhoc.hirooka.jdk11u, mixed mode)

おわりに

Raspberry Pi 3 (Raspbian) でも Java 11 をライフを!

-Raspberry Pi

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