socklen_t の有無を判別する。

[戻る]

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
  :
といった感じで記載しておけば、コンパイルしてエラーが出たら ヘッダファイルの _NOSOCKLEN をコメントアウトするという手があります。

しかしこの方法はどうも美しくなく、特に配布する際に 「エラーが出たらコメントアウトしてね」と言うのは気がひけます。 なんとかならんかな〜と色々調べた結果、どうもオープンソースのメイクで よくやる ./configure を作らないといけないことが分かりました。

やり方ですが

  1. ソース中の socklen_t か int か不定な所を SOCKLEN と記述します。

      struct sockaddr_in fsin;
      SOCKLEN fromlen=sizeof(fsin);
      :
    

    先ほどの例のように、#ifdef で場合分けしてもいいのですが、 ここでは SOCKLEN の定義を socklen_t か int か状況に応じて変えて見ます。

  2. 普通に 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
    
  3. 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
    
  4. configure.in というファイルを作り、以下のように書きます。 なお、一行目の括弧内は適当でいいです。 適当なファイル名を入れておけばいいでしょう。

    AC_INIT(foo.c++)
    AC_PROG_CXX
    AC_MSG_CHECKING(for socklen_t)
    AC_EGREP_CPP(socklen_t, [#include ],
    [
    AC_DEFINE(SOCKLEN, socklen_t)
    AC_MSG_RESULT(yes)
    ],
    [
    AC_DEFINE(SOCKLEN, int)
    AC_MSG_RESULT(no)
    ]
    )
    AC_OUTPUT(Makefile)
    
  5. 後は autoconf というコマンドを叩くと configure というファイルが作成されます。 こいつを実行すると動作環境に応じた Makefile が自動生成されます。 なお、配布には最低ソースの他、Makefile.in と configure が必要です。

なお、上記例は c++ コンパイラの例でしたが、 c コンパイラの場合

ようにすれば大丈夫です。 もっとも gcc やら g++ でやることが分かり切ってる場合、 Makefile.in の CC の定義に直接 gcc やら g++ と書いちゃってもいい気がします。


2004.6