intel edison 向けバイナリを cross compile する (OSX)

Macでedison向けのバイナリをビルドできるようにした。ついでにBoostもビルドした。
元ネタのほとんどは https://gist.github.com/pbosetti/027125c4ba066f51bf2c

ちなみにBoostについては一部のライブラリのビルドがまだうまくできていないので、ご注意を...。

# コンパイラの準備
## ダウンロード
以下からEdisonのSDKをダウンロードする。
https://downloadcenter.intel.com/download/25028/Intel-Edison-Board-Software-Package

↓2017年2月現在、OSX版の最新はこれらしい。
http://downloadmirror.intel.com/25028/eng/edison-sdk-macosx-ww25.5-15.zip

ちなみに
https://software.intel.com/en-us/iot/hardware/edison/downloads
にある"Cross-Compile SDK" はうまく解凍できなかった。

どれを使えばいいのか全然わからない。俺達は雰囲気でコンパイラを選んでいる。誰か事情を教えてほしい。

## インストール
ダウンロードしたzipを適当なところに解凍する。

```bash
$ unzip edison-sdk-macosx-ww25.5-15.zip
```
`poky-edison-glibc-i386-edison-image-core2-32-toolchain-1.7.2.tar.bz2`が入っているので、こいつも解凍してやる。ただし、環境変数を勝手に設定してくれるスクリプトを後で実行するのだが、それが`/opt/poky-edison/`以下にツールが入っていることを前提にしているので、

```bash
$ sudo mkdir -p /opt/poky-edison/1.7.2
$ sudo tar xvf poky-edison-glibc-i386-edison-image-core2-32-toolchain-1.7.2.tar.bz2 -C /opt/poky-edison/1.7.2/
```
として、`/opt/poky-edison/`以下に解凍する。

そして、次に`environment-setup-core2-32-poky-linux`を使って環境変数を設定してやるのだが、これをそのまま使うとうまくコンパイルできないので(なんでや！）、修正する。
以下のようにパッチをダウンロードして適用する

```bash
$ wget https://gist.githubusercontent.com/syundo0730/b1060e5361a3d03c7be74b0159dc96f2/raw/71a69b9b31277d3493dcc2b316086c122cdb551b/environment-setup.diff
$ patch /opt/poky-edison/1.7.2/environment-setup-core2-32-poky-linux environment-setup.diff
```

さらに、これだけだとビルド済みファイルをリンクするようなビルドをした時に`libfl.2.dylib`が無いと言われるので、https://sourceforge.net/projects/flex/
からflexをダウンロード、解凍してインストールしてやる。

```bash
$ ./configure --prefix=/opt/poky-edison/1.7.2/sysroots/i386-pokysdk-darwin/usr/ CFLAGS='-arch i386'
$ make -j8
$ sudo make install
```

# Boostを使う場合
C++ で書いてるとBoostも使いたくなると思うので、Boostもビルドしておく。もちろん、ヘッダファイルだけincludeすれば使えるライブラリ (詳細: http://www.boost.org/doc/libs/1_63_0/more/getting_started/unix-variants.html#header-only-libraries) はビルドしなくても利用可能。


まず適当なディレクトリにダウンロードして展開する。

```bash
$ mkdir ./boost
$ wget -O Boost.tar.gz https://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.gz/download
$ tar xvzf Boost.tar.gz
```
install.shを実行してb2を生成。

```bash
$ ./install.sh
```

次にcross compileのために設定ファイル`~/user-config.jam`を作成する。

詳細: http://www.boost.org/build/doc/html/bbv2/tasks/crosscompile.html

```bash:user-config.jam
using gcc : i586
  : i586-poky-linux-g++
  : <compileflags>--sysroot=/opt/poky-edison/1.7.2/sysroots/core2-32-poky-linux
  <cxxflags>-I/opt/poky-edison/1.7.2/sysroots/core2-32-poky-linux/usr/include/c++/4.9.1
  <cxxflags>-I/opt/poky-edison/1.7.2/sysroots/core2-32-poky-linux/usr/include/c++/4.9.1/i586-poky-linux
  ;

using python : 2.7
  : /opt/poky-edison/1.7.2/sysroots/i386-pokysdk-darwin/usr
  : /opt/poky-edison/1.7.2/sysroots/core2-32-poky-linux/usr/include/python2.7
  ;
```

そしてビルドする。

```bash
$ ./b2 install -j2 --prefix=./stage --toolset=gcc
```
適当に`./stage`以下に生成するようにした。`prefix`を指定しないとデフォルトの場所(`/usr/local/`)に生成されてedison用とそうでないのが混ざってしまうので指定したほうがいい。また、`toolset`を指定しないとdarwin向けにビルドしてしまう。

ちなみに一部のライブラリのビルドがまだうまくいってない。

```
...failed updating 7 targets...
...skipped 8 targets...
...updated 13433 targets...
```

```
clang: error: unsupported option '--32'
clang: error: no input files
```

どうしよう。

# 動作確認
以下のようなBoostを使ったこコードをコンパイルしてみる。

```cpp:boost_timer.cpp
#include <boost/timer/timer.hpp>
#include <cmath>

int main()
{
  boost::timer::auto_cpu_timer t;

  for (long i = 0; i < 100000000; ++i)
    std::sqrt(123.456L); // burn some time

  return 0;
}
```
```bash
$ source /opt/poky-edison/1.7.2/environment-setup-core2-32-poky-linux
$ $CXX ./src/main.cpp -I../thirdparty/boost/stage/include -L../thirdparty/boost/stage/lib -lboost_timer -lboost_chrono -lboost_system -o boost_timer
```
scpなどでedisonに転送して、実行すると、

```bash
$ ./boost_timer
 18.929318s wall, 18.890000s user + 0.000000s system = 18.890000s CPU (99.8%)
```
ちゃんと動いた。

# 参考
https://gist.github.com/pbosetti/027125c4ba066f51bf2c
http://shawnhymel.com/809/cross-compiling-on-linux-for-the-edison/
https://daisukekobayashi.com/blog/build-boost-cpp-for-intel-edison/