ARM版のyuniもamd64のDockerでCIする

追記: RunaboveのようなARM VPSを使えば良いじゃんというツッコミ( https://twitter.com/nalsh/status/827884020591505408 )が有った。ごもっとも。。
諸般の事情でARM版のCI環境が必要になったので、ついでにyunibaseでも同様に用意した。

基本的にはこのblogの通りで、

  1. 静的リンクされたqemu-userとARM版のユーザランドが入ったDocker imageを使う
  2. 事前にbinfmt_miscにARM版のバイナリをqemuで実行するように設定しておく
  3. 普通にamd64上のDockerでARMイメージを生成、実行する

という手順で良いことになる。

手順1: binfmt_miscに各種qemuを登録する

上のblogだとこの手順にもDockerを使っていて、

docker run --rm --privileged multiarch/qemu-user-static:register --reset

のようにして登録している。このコンテナの実態は https://github.com/multiarch/qemu-user-static で、ここからregister.shを拾ってきて実行するだけでも十分と言える。
yuniのtravis.yml( https://github.com/okuoku/yuni/blob/1fa3d4306b30080d317638b42d151df5cc56f542/.travis.yml )には

script:
    - sudo integration/buildhost-qemu-static/register.sh
    - docker pull $DOCKER_IMG
    - cmake -DIMAGE=$DOCKER_IMG -P integration/buildhost-docker-linux/test-on-docker.cmake

のように直接sudoで実行している。

手順2: 適当なARMユーザランドを含んだDockerイメージを拾ってきて実行する

上のblogのように、今回はresinのイメージを採用した。

FROM resin/rpi-raspbian
WORKDIR /build

RUN apt-get update && apt-get install -y \
make cmake gcc g++ \
autoconf automake \
libgmp-dev libonig-dev \
libtool flex gettext pkg-config libunistring-dev libffi-dev libgc-dev \
time texinfo \
ncurses-dev libx11-dev zlib1g-dev

... apt-getするだけ。

結果


1度のテストに16分!遅い!(yuniのTravis: https://travis-ci.org/okuoku/yuni )
今のところ、一度のテストに7分掛かっているデフォルトのイメージ(Ubuntu LTSベース)にはChibi-schemeGauche、nmosh、Sagittarius、Chicken、Guile、Racket、Vicare、Chez scheme、Gambit、PicrinとMIT/GNU Shemeの12処理系が入っている。ARM版はChibi-scheme、GambitとChickenの3処理系しか入れていない。
ちなみに、この3処理系をコンパイルする(処理系を含んだDockerイメージを用意する)のにも2時間以上掛かっている。これはコンパイラがクロスコンパイラではなくqemu上で実行されるネイティブコンパイラになっているのが原因だけど、それにしても遅い。。
FFIライブラリをロードするだけのテストffitrivialだと

      Start 62: app-ffitrivial-CHIBI_SCHEME
62/66 Test #62: app-ffitrivial-CHIBI_SCHEME ..........   Passed    0.91 sec
      Start 15: app-ffitrivial-CHIBI_SCHEME
15/15 Test #15: app-ffitrivial-CHIBI_SCHEME ......   Passed   10.01 sec

のように10倍以上の実行時間差がある。
これが実用的かと言われると何とも言えないが、少くともyuniのユースケースではいちいちARM機でテスト環境を用意するよりは手軽で良いのかなと。。