Linux 等でネットワークプログラムを書くと、 gcc のバージョンか何かで accept や recvform の引数が、 あるものは socklen_t で別のものは int だったりしてコンパイルがすんなり通りません。
まぁ自分で作る分にはその場で書き換えたり、適当なヘッダファイルに
#define _NOSOCKLEN |
struct sockaddr_in fsin; #ifndef _NOSOCKLEN socklen_t fromlen=sizeof(fsin); #else int fromlen=sizeof(fsin); #endif : |
しかしこの方法はどうも美しくなく、特に配布する際に 「エラーが出たらコメントアウトしてね」と言うのは気がひけます。 なんとかならんかな〜と色々調べた結果、どうもオープンソースのメイクで よくやる ./configure を作らないといけないことが分かりました。
やり方ですが
ソース中の socklen_t か int か不定な所を SOCKLEN と記述します。
struct sockaddr_in fsin; SOCKLEN fromlen=sizeof(fsin); : |
先ほどの例のように、#ifdef で場合分けしてもいいのですが、 ここでは SOCKLEN の定義を socklen_t か int か状況に応じて変えて見ます。
普通に Makefile を作ります。二行目の SOCKLEN の定義は環境に応じ、 必要なら int に書き換えます。
CC = g++ DEFS = -DSOCKLEN=socklen_t FLG = -Wall LIBS = foo: foo.o bar.o $(CC) -o foo foo.o bar.o $(LIBS) foo.o: foo.c++ foo.h bar.h $(CC) $(FLG) -o foo.o -c foo.c++ bar.o: bar.c++ bar.h $(CC) $(FLG) -o bar.o -c bar.c++ clean: rm -f *.o foo core |
Makefile を Makefile.in にコピーし、次のように CC と LIBS と DEFS の行を書き換え、さらに $(CC) $(FLG) の後に $(DEFS) を加えます。
CC = @CXX@ DEFS = @DEFS@ FLG = -Wall LIBS = @LIBS@ foo: foo.o bar.o $(CC) -o foo foo.o bar.o $(LIBS) foo.o: foo.c++ foo.h bar.h $(CC) $(FLG) $(DEFS) -o foo.o -c foo.c++ bar.o: bar.c++ bar.h $(CC) $(FLG) $(DEFS) -o bar.o -c bar.c++ clean: rm -f *.o foo core |
configure.in というファイルを作り、以下のように書きます。 なお、一行目の括弧内は適当でいいです。 適当なファイル名を入れておけばいいでしょう。
AC_INIT(foo.c++) AC_PROG_CXX AC_MSG_CHECKING(for socklen_t) AC_EGREP_CPP(socklen_t, [#include |
後は autoconf というコマンドを叩くと configure というファイルが作成されます。 こいつを実行すると動作環境に応じた Makefile が自動生成されます。 なお、配布には最低ソースの他、Makefile.in と configure が必要です。
なお、上記例は c++ コンパイラの例でしたが、 c コンパイラの場合