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)までメールを下さい。

sけいし発HP


[PR]I肢ŎdӒ:lCI肢wق̊فx