Debian GNU/Linux の gcc-h8300-hms について

Debianで手っ取り早くH8(H8/3694F)の開発をしようとしたら、いまひとつライブラリが揃ってなくて手っ取り早くありませんでした。
OSのバージョンはDebian GNU/Linux 7。野良ビルドをしない方針。
Debianにはbinutils-h8300-hmsパッケージ [debian.org]とgcc-h8300-hmsパッケージ [debian.org]があるのですが、こういう問題があります。

  1. libgcc.aがH8/300用のものしかついてない。H8/300H用のものが欲しい。
  2. 標準Cライブラリがない

以下、詳細。

1. libgcc.aがH8/300用のものしかついてない。H8/300H用のものが欲しい

libgcc.a [gnu.org]は整数演算や浮動小数点演算のルーチンが入っているライブラリです。H8では32ビット同士の乗除算や、浮動小数点演算をするときにlibgcc.aのルーチンが使われます。
h8300-hms-gccではH8/300とH8/300HとH8Sの3種類のアーキテクチャのバイナリを生成できるので、libgcc.aも各アーキテクチャ分あって欲しいのですが、gcc-h8300-hmsパッケージにはH8/300用のlibgcc.aしか入っていません。

libgcc.aが1個しか入ってない
$ dpkg -L gcc-h8300-hms | grep libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a
そしてそのアーキテクチャはh8300(H8/300用)
$ h8300-hms-objdump -x /usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a | grep architecture | head -n 1
architecture: h8300, flags 0x00000231:

コンパイル時、libgcc.aはデフォルトで(暗黙で)リンクされます。このとき、H8/300H用のバイナリを生成しているのに、H8/300用のlibgcc.aをリンクしようとしてエラーが出ます。

エラーが出ているところ
$ h8300-hms-gcc -T h8rom.x -nostartfiles -mh -mn h8crt0.s test.c
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/ld: skipping incompatible /usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a when searching for -lgcc
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/ld: skipping incompatible /usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a when searching for -lgcc
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/ld: cannot find -lgcc
collect2: ld returned 1 exit status
-vオプションをつけてみた
$ h8300-hms-gcc -T h8rom.x -nostartfiles -mh -mn h8crt0.s test.c -v
Reading specs from /usr/lib/gcc/h8300-hitachi-coff/3.4.6/specs
Configured with: ../configure coff
Thread model: single
gcc version 3.4.6
 /usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/as -o /tmp/ccAsIDlu.o h8crt0.s
 /usr/lib/gcc/h8300-hitachi-coff/3.4.6/cc1 -quiet -v test.c -quiet -dumpbase test.c -mh -mn -auxbase test -version -o /tmp/ccatYze5.s
ignoring nonexistent directory "/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/sys-include"
ignoring nonexistent directory "/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/h8300-hitachi-coff/3.4.6/include
End of search list.
GNU C version 3.4.6 (h8300-hitachi-coff)
        compiled by GNU C version 4.7.2.
GGC heuristics: --param ggc-min-expand=55 --param ggc-min-heapsize=47469
 /usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/as -o /tmp/ccOhkt9F.o /tmp/ccatYze5.s
 /usr/lib/gcc/h8300-hitachi-coff/3.4.6/collect2 -m h8300hn -L/usr/lib/gcc/h8300-hitachi-coff/3.4.6 -L/usr/lib/gcc/h8300-hitachi-coff/3.4.6 -L/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/lib /tmp/ccAsIDlu.o /tmp/ccOhkt9F.o -lgcc -lc -lgcc -T h8rom.x
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/ld: skipping incompatible /usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a when searching for -lgcc
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/ld: skipping incompatible /usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a when searching for -lgcc
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/../../../../h8300-hitachi-coff/bin/ld: cannot find -lgcc
collect2: ld returned 1 exit status

対策としては、-nodefaultlibsオプションをつけるとリンクされなくなります。http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Link-Options.html

-nodefaultlibsオプションをつけたところ
$ h8300-hms-gcc -T h8rom.x -nostartfiles -nodefaultlibs -mh -mn h8crt0.s test.c

この場合libgcc.aがリンクされないので、32ビット同士の乗除算や、浮動小数点演算を使うとリンクエラーになります。

浮動小数点演算を使うとリンクエラー
$ cat test.c
int main(void)
{
    volatile double f = 0.0;
    return (int)f;
}
$ h8300-hms-gcc -T h8rom.x -nostartfiles -nodefaultlibs -mh -mn h8crt0.s test.c
/tmp/ccTb77Ee.o:test.c:(.text+0x16): undefined reference to `___fixsfsi'
collect2: ld returned 1 exit status

2. 標準Cライブラリがない

Newlibが欲しいところですがそんなパッケージはなさそうです。したがって標準C関数を使ったプログラムはコンパイルできません。

stdio.hがないのでエラー
$ cat test.c
#include <stdio.h>
int main(void)
{
  volatile char* s = "";
  return strlen(s);
}
$ h8300-hms-gcc -T h8rom.x -nostartfiles -nodefaultlibs -mh -mn h8crt0.s test.c
test.c:1:19: stdio.h: No such file or directory
test.c: In function `main':
test.c:5: warning: passing arg 1 of `strlen' discards qualifiers from pointer target type
stdio.hをインクルードするのをやめてもstrlenがないのでエラー
$ cat test.c
int main(void)
{
  volatile char* s = "";
  return strlen(s);
}
$ h8300-hms-gcc -T h8rom.x -nostartfiles -nodefaultlibs -mh -mn h8crt0.s test.c
test.c: In function `main':
test.c:4: warning: passing arg 1 of `strlen' discards qualifiers from pointer target type
/tmp/ccZxUnsz.o:test.c:(.text+0x14): undefined reference to `_strlen'
collect2: ld returned 1 exit status

おまけ。各アーキテクチャ向きのlibgcc.aを作ってみる

アーキテクチャ用のlibgcc.aを含むようにパッケージを作りなおしてみます。



以下ずっと書き中

# apt-get build-dep gcc-h8300-hms
# apt-get install gcc-multilib

$ apt-get source gcc-h8300-hms
$ cd gcc-h8300-hms-3.4.6+dfsg
$ vi debian/rules

rulesを編集する。

--- a/debian/rules	Thu Sep 19 00:09:36 2013 +0900
+++ b/debian/rules	Thu Sep 19 03:38:53 2013 +0900
@@ -46,7 +46,6 @@
 				--with-gnu-ld \
 				--disable-libssp \
 				--enable-target-optspace \
-				--disable-multilib \
         --target=$(TARGET) 
 	touch configure-stamp
 

パッケージを作る

$ dpkg-buildpackage -us -uc
$ cd ..

# dpkg -i gcc-h8300-hms_3.4.6+dfsg-1_amd64.deb
$ dpkg -L gcc-h8300-hms | grep libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300s/int32/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300s/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300s/normal/int32/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300s/normal/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300h/int32/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300h/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300h/normal/int32/libgcc.a
/usr/lib/gcc/h8300-hitachi-coff/3.4.6/h8300h/normal/libgcc.a

H8にはH8/300とH8/300HとH8Sの3種類のアーキテクチャがある。
このうち、H8/300HとH8Sにはノーマルモードとアドバンストモードの2つのCPU動作モードがある。
そして、H8/300HとH8Sではintを16ビットにするオプションとintを32ビットにするオプションがある。
http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/H8_002f300-Options.html

gcc-h8300-hms-3.4.6+dfsg/builddir-h8300-hitachi-coff/gcc/multilib.h
gcc-h8300-hms-3.4.6+dfsg/builddir-h8300-hitachi-coff/gcc/libgcc.mk
gcc-h8300-hms-3.4.6+dfsg/builddir-h8300-hitachi-coff/gcc/specs

/usr/lib/gcc/h8300-hitachi-coff/3.4.6/

architecture -mh -ms -mn -mint32
libgcc.a h8300
h8300h/libgcc.a h8300h
h8300h/int32/libgcc.a h8300h
h8300h/normal/libgcc.a h8300hn
h8300h/normal/int32/libgcc.a h8300hn
h8300s/libgcc.a h8300s
h8300s/int32/libgcc.a h8300s
h8300s/normal/libgcc.a h8300sn
h8300s/normal/int32/libgcc.a h8300sn