Home > プログラムについて | メモ | 研究について > Linuxにlibuvをインストールした時にハマった所

Linuxにlibuvをインストールした時にハマった所


最近はnode.jsに興味を持ち出しています。

そうなると、やっぱり内部のアーキテクチャが気になってしまって、jsを弄るのと並行してlibuvを使ってCでコード書いたりしています。例えば、Apache2.4系のmpmはLoadableなので、libuvでmpm書いちゃったらApacheも高速だろうなーとかも考えてます。

しかし、Windowsはいっぱいあるんだけど、意外とLinuxにlibuvをインストールする記事やドキュメントが無くて、微妙にハマったのでlibuvをLinuxにインストールする方法をまとめておきます。Makefileやconfig-unix.mkをチラチラ見ながらなんとかしました。

Linuxにlibuvをインストール

OSはCentOS5系でわけあって32bitのPAEカーネルの環境にインストールしました。

uname -a
Linux example.com 2.6.18-308.11.1.el5PAE #1 SMP Tue Jul 10 09:29:33 EDT 2012 i686 i686 i386 GNU/Linux

まずは、libuvをGitHubからとってきます。

git clone git://github.com/joyent/libuv.git

そして、libuvディレクトリに移動しmakeします。

すると、上記の32bit環境では下記のようなエラーがでました。64bit環境ではふつうに通ります。

cc --std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter -D_GNU_SOURCE -Iinclude -Iinclude/uv-private -Isrc -Isrc/unix/ev -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -g -c src/unix/async.c -o src/unix/async.o
In file included from src/unix/internal.h:40,
                 from src/unix/async.c:22:
src/unix/linux/syscalls.h:74: error: expected specifier-qualifier-list before ‘__u64’
make: *** [src/unix/async.o] Error 1

おや、__u64がなんか怪しいんでは?と言われている様子。ということで、/usr/include/linux/types.hをみてみると、以下のようになっていました。

 95 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 96 typedef     __u64       uint64_t;
 97 typedef     __u64       u_int64_t;
 98 typedef     __s64       int64_t;
 99 #endif

ここで安直に、-U__STRIC_ANSI__したらいいんじゃないの?と思い、MakefileのCPPFLAGSに追加するも、以下のようにうまくいきませんでした。

src/unix/signal.c:119: error: expected ‘=,,,;, ‘asm’ or ‘__attribute__’ before ‘static
src/unix/signal.c: In function ‘uv__signal_handler’:
src/unix/signal.c:144: warning: implicit declaration of function ‘uv__signal_first_handle’
src/unix/signal.c:144: warning: assignment makes pointer from integer without a cast
src/unix/signal.c: In function ‘uv_signal_start’:
src/unix/signal.c:310: warning: comparison between pointer and integer
src/unix/signal.c: In function ‘uv__signal_stop’:
src/unix/signal.c:446: warning: comparison between pointer and integer
make: *** [src/unix/signal.o] Error 1

うーん、これはなんかいつもの良くない方向にハマっていってるなぁと思ったので、とりあえず__u64をunsigned long longに変える以下のようなpatchを作って当てました。これだとansi、c89の環境なのでもちろんWarningが発生しますが一応コンパイルは通ります。もっと良い案があれば教えて欲しいです。というか__u64と書かれていたのは一か所だけでした。

--- src/unix/linux/syscalls.h.orig      2012-11-10 00:24:57.000000000 +0900
+++ src/unix/linux/syscalls.h   2012-11-10 00:44:41.000000000 +0900
@@ -71,7 +71,7 @@

 struct uv__epoll_event {
   __u32 events;
-  __u64 data;
+  unsigned long long data;
 } __attribute__((packed));

 struct uv__inotify_event {

そして、再度makeするとうまく通って、libuv.aがカレントディレクトリに生成されました。そして、ヘッダファイルとライブラリを以下のようにコピーしました。

sudo cp -r include/{uv.h,uv-private} /usr/include/.
sudo cp livuv.a /usr/lib/.

そこで、以下のようなlibuvのサンプルコードを書いて、

#include <stdio.h>
#include <uv.h>

int main() {
    uv_loop_t *loop = uv_loop_new();

    printf("Now quitting.¥n");
    uv_run(loop);

    return 0;
}

以下のようにコンパイルしました。

gcc sample.c -O3 -g -fPIC -pthread -ldl -lrt -lm -luv

そして、バイナリa.outを実行すると、

./a.out
Now quitting.

と、無事libuvを使ったコードを実行する事ができました。

めでたしめでたし。

というわけで、今後はlibuvを使って非同期通信を色々やってみたいと思います。

コメント:0

コメントフォーム
Remember personal info

CAPTCHA


トラックバック:0

このエントリーのトラックバックURL
http://blog.matsumoto-r.jp/wp-trackback.php?p=3016
Listed below are links to weblogs that reference
Linuxにlibuvをインストールした時にハマった所 from 人間とウェブの未来

Home > プログラムについて | メモ | 研究について > Linuxにlibuvをインストールした時にハマった所

検索
フィード
メタ情報

Return to page top