SNSへはこちら

RXマイコンでprintf系の%fが使えた! on Mac

新年明けましておめでとうございます。元日は忙しく、日付が変わってしまいしたが、今年もよろしくお願いします〜
さて、新年1発目の記事は、なななんと、前回の振り返り記事もうだめだぁ的な事を言っていた、RX マイコンの printf%f のフォーマット指定子を使う方法です。ピンと閃いてちょっと試行錯誤をしたら出来てしまいました!大進捗です。

また、RX71M を使いたい方は、これまで紹介してきた方法ではコンパイラが対応できていないので、この記事の内容に従ってください。

概要

結論から言うと、%f を動かすためにすることは、生粋の gcc をビルドすることではありません(悔しいですが)。そして Windows が一瞬必要になるという反則技です。

実験した内容

思いついた内容を裏付けるためにした実験です。Windows 版の GNU Tools が提供する gcc を使ったところ、使用ライブラリが optlib(コンパイラのオプションで Optilized を選択)のときは %f が使えるが、Newlib の時は使えずロックアップしてしまうということが分かったのです。

ということは、この Optlib というライブラリを拝借してしまえば良いのでは?と考えました。どうやら RX マイコンに最適化されているようで、ライブラリサイズがとても小さいようです。以前僕が「Mac でビルドするとプログラムサイズが大きい」と言っていたのはおそらくこれが理由です。

そこで既にビルドしてある、GNU 公式の(GNU Tools のではない) gcc のディレクトリに optlib をコピーしたところ、動かず。一方 GNU Tools のソースファイルをビルドしてできた gcc にコピーしたら動きました

準備

GNU Tools の gcc を使います。以下のサイトから各種ソースコードをダウンロード。ユーザ登録が必要なので、従ってあげてください。

各種アーカイブを展開します。なお以下に示すビルドは、各ソフトウェアのディレクトリ内に新しくディレクトリを作ってから、その中で実行してください。例えば以下のように。

binutils
├── autom4te.cache
├── bfd
├── binutils
├── config
├── cpu
├── elfcpp
├── etc
├── gas
├── gold
├── gprof
├── include
├── intl
├── ld
├── libiberty
├── opcodes
├── rx_build <= 作ったやつ。この中でコマンド実行。
└── texinfo

さらに、Windows PC でビルド済みの gcc をインストールしておいてください。

ビルドをする

ここではコマンドをサクッと載せておきます。時間がある時に実行してください。configure したあとは

  • make -j4
  • sudo make install

で出来ます。各自で prefix は好みのインストール先に指定してください。

binutils

$ ../configure --prefix=/usr/local/gnu-rx-elf --target=rx-elf --enable-multilib --disable-werror --disable-bootstrap

gcc(1回目)

注意点を掲載します。

$ ../configure --prefix=/usr/local/gnu-rx-elf --target=rx-elf --enable-multilib --disable-libstdcxx-pch --enable-languages=c,c++ --with-newlib --disable-werror --disable-bootstrap --disable-nls

途中、gcc のビルドがヘッダがインクルードされないせいで失敗するので、止まったソースファイルにおいて適当なヘッダをインクルード追加する。(多分各ファイルに書くよりも config.h とか言うヘッダに追記したほうが早い)
さらに、libc_name_p 関連でエラーが出た場合は、このように該当ファイルに小細工をしてやるとビルドが通ります。

ここで、以下の表示が出てビルドが止まってしまった場合は、無視してOKです。後々に解決しますから。

checking for the value of EOF... configure: error: computing EOF failed
make[1]: *** [configure-target-libstdc++-v3] Error 1
make: *** [all] Error 2

そのまま sudo make install してしまってください。ここでもエラーが起きるとは思いますが、無視で結構です。

newlib

実行前にパスを通すことをお忘れなく。僕の指定した prefix では以下のよう。

$ PATH = /usr/local/gnu-rx-elf/bin:$PATH

以下が configure。

$ ../configure --prefix=/usr/local/gnu-rx-elf --target=rx-elf --enable-multilib --disable-werror --disable-bootstrap --enable-newlib-hw-fp

gcc(2回目)

特に何もせず make してください。今度は libstdc++-v3 のビルドが通るようになっています。

optlibを拝借

さぁ、ここからが Windows の出番です。と言っても、見出しに書いてある通り、optlib をパクるコピるだけです。どうやら optlib はルネサス社のものらいいので[要出典]、使用は個人の範囲内にとどめてください。

Windows 版の gcc をインストールしてしまったら、あとはそのディレクトリに Mac 側からアクセスするだけなので、もう Windows はシャットダウンしてもらって構わないです。

以下に示すのが、コピーに使用するシェルコマンドです。(インストール先)/rx-elf/rx-elf/rx-elf/libで実行しましょう。インストール先は通常 /Volumes/BOOTCAMP/Program\ Files\ \(x86\)/GCC\ for\ Renesas\ RX\ 4.8.4.201801-GNURX-ELF のはずです。

$ find . -name "liboptc.a" | xargs -I {} sudo cp {}  /usr/local/gnu-rx-elf/rx-elf/lib/{}
$ find . -name "liboptm.a" | xargs -I {} sudo cp {}  /usr/local/gnu-rx-elf/rx-elf/lib/{}

1階層上に出て、sudo cp -r optlibinc /usr/local/gnu-rx-elf/rx-elf/optlib 用のヘッダをコピー。

できた

以上で完了です。結構ビルド時間が長くて待ちくたびれてしまったのではないでしょうか。でもこれで完成です。ちょっとソースファイルの改変が面倒くさかったですかね。

この Optlib を使うためには、リンク時に指定してあげればいいです。例えば次のように。

CFLAGS = -mcpu=rx200 -nofpu -mlittle-endian-data -m64bit-doubles -Os -ffunction-sections -fdata-sections -std=gnu11 -I /usr/local/gnu-rx-elf/rx-elf/optlibinc

    rx-elf-gcc -nostartfiles -Wl,--gc-sections -T"linker.ld" $(CFLAGS) -o $@ $(オブジェクトファイルたち) -nostdlib -loptc -loptm -lgcc

何を言いたいかと言うと、コツは -nostdlib として Newlib (この場合は libc.a と libm.a)が使用されるのを回避しつつ、-loptc -loptm とすることで Optlib を使うように仕向けるということです。

てなわけで、遂に printf までが完璧になってしまいました…と同時に、プログラムのバイナリサイズを大きく削減することが出来て、僕は嬉しくてたまらないです。途中 Windows の力を借りてしまっていますが、一度 Optlib を取り出してしまえば Mac 単独で RX マイコンの開発が出来ます
これで遂に胸を張って、「Mac でも RX マイコンは開発できるんだよ」と言えるようになりました!!!実はこの問題に直面したのが1年くらい前なので、長年つかえていたものが取れたような気持ちでとてもスッキリしています。

あ、あとさっきデレステの10連ガチャで SSR を2枚引きしたので、これもまた嬉しいんですね。

参考サイト