
newlibのコンパイル
(1)ゲット
RedHatのHPからnewlib-1.14.0.tar.gzをげっと
gnuWin32のHPからlibgw32cをげっと
(2)コンパイル
1)configure.hostの書き換え
136行目からmingwはsetjmp.hをもってるのでmach_add_setjmp=trueしない。
*-*-sco* | *-*-cygwin*| *-*-mingw*)
libm_machine_dir=i386
machine_dir=i386
;;
271行目からマルチバイトサポートを有効にする。
i[34567]86-pc-linux-*|*-*-cygwin*|*-*-mingw*)
newlib_mb=yes
;;
479行目に以下を足す
*-*-mingw*)
default_newlib_io_long_long="yes"
default_newlib_io_long_double="yes"
default_newlib_io_pos_args="yes"
newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES -DHAVE_OPENDIR -DSIGNAL_PROVIDED
-DHAVE_FCNTL -D_COMPILING_NEWLIB -DHAVE_FCNTL -DMALLOC_PROVIDED"
syscall_dir=syscalls
;;
libgw32cのdirent.hを使うのでHAVE_OPENDIRをON
libgw32cのsignal.hを使うのでSIGNAL_PROVIDEDをON
libgw32cのfcntl.hを使うのでHAVE_FCNTL
MISSING_SYSCALL_NAMESを指定すると。_syslist.hでシステムコール関数のリネームができる。
ヘッダのかきかえ
ヘッダは libc/includeにある。
<fcntl.h><sys/fcntl.h>
mingwのをつかう
<stdlib.h>
malloc.hを読み込むようにする26行目
#ifdef __MINGW32__
#include <malloc.h>
#endif
*/
<dirent.h>関係
libgw32cのを使う
mingwのdirent.hの最後の方に以下を追加
#if !defined(MAXNAMLEN) && !defined(_POSIX_SOURCE)
#define MAXNAMLEN 1024
#endif
<setjmp.h>関係
mingwのを使う
<signal.h>関係
gw32cのを使うようにする
<sys/types.h>
mingwのを使い以下のようにやって エラーがでたらnewlibのほうから重なってるものを消す。
#define __USE_W32_SOCKETS 1
#include <sys/mingw_types.h>
#include <sys/newlib_types.h>
最後のほうにsigset_tの定義をつける
#ifndef _SIGSET_T_
#define _SIGSET_T_
typedef int _sigset_t;
#ifndef _NO_OLDNAMES
typedef _sigset_t sigset_t;
#endif
#endif /* Not _SIGSET_T_ */
# if !(defined (_POSIX_SOURCE) || defined (_WINSOCK_H) || defined (__USE_W32_SOCKETS)) のまえに
#define __USE_W32_SOCKETS 1 をつける
<sys/stat.h>
gw32cのをつかう
$cd newlib
$LIBS="-lgw32c
-lole32 -luuid -lwsock32" CC="gcc -O2
-D__GW32__ " ./configure
$make
エラーが出るが頑張る!(おぃ)
libc/searchはコンパイルできないのであきらめる
libcがどんな関数を参照してるか調べてみる
$mkdir c
$cd c
$ar -x ../libc.a
$cd ..
$ gcc -shared `ls c/*.o` &>log
参照不可だったのは
_realloc_r _calloc_r _malloc_r _free_r
_fork _wait _kill _sbrk _times
_fcntl _link _gettimeofday
sigfillset sigprocmask
だった
参照不可だった関数から libgw32への橋渡し用プログラムを書く
(newlib_link.c)
$ C_INCLUDE_PATH=./libc/include gcc -O2 -D__GW32__ -c newlib_link.c
そしてりんく
$ gcc -Wl,--allow-multiple-definition -shared `ls c/*.o` newlib_link.o -lgw32c -luuid -lole32 -o libnewlib.dll
完成♪
とおもいきや。。。。 このdllをリンクすると newlibのではなくmsvcrtの関数が使われてしまうようだ。。。がく。。。
というわけでダイナミックリンクはあきらめて。。。
$cp libc.a libnewlib.a
$ar -ru libnewlib.a newlib_link.o
完成かな。。。
コンパイルするとエラーがでるので、ヘッダファイルをちょこちょこ書き換え
TiMidity++はうごいたけどfreecivはうごかなかった(サーバーもクライアントも)
とりあえずコンソールに12バイトlong doubleが出力させるという目標は達成できた(苦労の割に結果がしょぼくないか?)
やっぱ libcのコンパイルは 甘くないね。。。
追加情報
libnewlib.dllを使うとmsvcの関数が使われてしまうのはdefファイルから不要な関数名を除くことで防げることが判明した。
まず libgw32c.aから 必要な関数を_nlrt_xxxxという名前でエクスポートした最小限のランタイムライブラリをつくる。
インターフェース newlmcrt.c
$C_INCLUDE_PATH=./libc/include gcc -O2 -D__GW32__ -D_LARGEFILE_SOURCE=1 \
-D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -c newlmcrt.c
$ gcc -shared newlmcrt.o newlmcrt.def -L. -lgw32c -o libnewlmcrt.dll
このランタイムだけをリンクしてlibc.a からdllをつくる。
次に newlib と libnewlmcrt.dllとのインターフェースを書いてから、newlibのdllを作る。
インターフェース newl_link.c
$C_INCLUDE_PATH=./libc/include gcc -O2 -D__GW32__ -D_LARGEFILE_SOURCE=1 \
-D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -c newl_link.c
$gcc -Wl,--allow-multiple-definition -shared `ls c/*.o` newl_link.o newlib.def -L. -lnewlmcrt -o libnewlib.dll
戻る
このHPの内容に問題等
ありましたらsけいし(skeishi@yahoo.co.jp)までメールを下さい。
