May 22, 2014

Amazon Linux AMI 2014.03.1 (64bit) への checkinstall 導入

Amazon AWS の EC2 インスタンスで動作している Amazon Linux AMI 2014.03.1 (Linux ****** 3.10.40-50.136.amzn1.x86_64 #1 SMP Tue May 13 21:35:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux) への checkinstall の導入時にエラーとなった場合の対処方法。

Amazon AWS の EC2 インスタンスに checkinstall コマンドを導入しようとして、 ネットなどの情報に基づいて以下のコマンドを実行した所コンパイルエラーが発生した。

$ git clone http://checkinstall.izto.org/checkinstall.git
$ cd checkinstall
$ vi Makefile checkinstall checkinstallrc-dist installwatch/Makefile
$ make
    :
    :
make -C installwatch
make[1]: ディレクトリ `/home/mitz/checkinstall/installwatch' に入ります
gcc -Wall -c -D_GNU_SOURCE -DPIC -fPIC -D_REENTRANT -DVERSION=\"0.7.0beta7\" installwatch.c
installwatch.c:2960:5: error: conflicting types for ‘readlink’
 int readlink(const char *path,char *buf,size_t bufsiz) {
     ^
In file included from installwatch.c:41:0:
/usr/include/unistd.h:831:16: note: previous declaration of ‘readlink’ was here
 extern ssize_t readlink (const char *__restrict __path,
                ^
installwatch.c:3098:5: error: conflicting types for ‘scandir’
 int scandir( const char *dir,struct dirent ***namelist,
     ^
In file included from installwatch.c:49:0:
/usr/include/dirent.h:255:12: note: previous declaration of ‘scandir’ was here
 extern int scandir (const char *__restrict __dir,
            ^
installwatch.c:3714:5: error: conflicting types for ‘scandir64’
 int scandir64( const char *dir,struct dirent64 ***namelist,
     ^
In file included from installwatch.c:49:0:
/usr/include/dirent.h:278:12: note: previous declaration of ‘scandir64’ was here
 extern int scandir64 (const char *__restrict __dir,
            ^
make[1]: *** [installwatch.o] エラー 1
make[1]: ディレクトリ `/home/mitz/checkinstall/installwatch' から出ます
make: *** [all] エラー 2
$
    
ざっと調べてみると glibc のバージョン情報を格納していると思われるマクロ GLIBC_MINOR の値が不正で readlink()、 及び内部で定義している scandir()scandir64() のプロトタイプ宣言が正しく展開されていない様だったので、 他にもいくつか発生したコンパイルエラーを修正して 取りあえずコンパイルしてインストール可能なパッチを作成した。
本来は Amazon LINUX 上でも glibc のバージョンを正しく取得できる様にするべきなのだが、 諸処の事情でそこまで修正する余裕がないので暫定的な対策のみとなっている。

  1diff -rc checkinstall/installwatch/installwatch.c checkinstall~/installwatch/installwatch.c
  2*** checkinstall/installwatch/installwatch.c    2014-05-21 12:41:51.659879736 +0900
  3--- checkinstall~/installwatch/installwatch.c   2014-05-21 12:41:16.107577033 +0900
  4***************
  5*** 99,105 ****
  6  static int (*true_xstat)(int,const char *,struct stat *);
  7  static int (*true_lxstat)(int,const char *,struct stat *);
  8  
  9! #if(GLIBC_MINOR >= 10)
 10  
 11  static int (*true_scandir)(   const char *,struct dirent ***,
 12                int (*)(const struct dirent *),
 13--- 99,105 ----
 14  static int (*true_xstat)(int,const char *,struct stat *);
 15  static int (*true_lxstat)(int,const char *,struct stat *);
 16  
 17! #if 1
 18  
 19  static int (*true_scandir)(   const char *,struct dirent ***,
 20                int (*)(const struct dirent *),
 21***************
 22*** 130,136 ****
 23  static int (*true_open64)(const char *, int, ...);
 24  static struct dirent64 *(*true_readdir64)(DIR *dir);
 25  
 26! #if(GLIBC_MINOR >= 10)
 27  static int (*true_scandir64)( const char *,struct dirent64 ***,
 28                int (*)(const struct dirent64 *),
 29                int (*)(const struct dirent64 **,const struct dirent64 **));
 30--- 130,136 ----
 31  static int (*true_open64)(const char *, int, ...);
 32  static struct dirent64 *(*true_readdir64)(DIR *dir);
 33  
 34! #if 1
 35  static int (*true_scandir64)( const char *,struct dirent64 ***,
 36                int (*)(const struct dirent64 *),
 37                int (*)(const struct dirent64 **,const struct dirent64 **));
 38***************
 39*** 2545,2551 ****
 40  }
 41  
 42  FILE *fopen(const char *pathname, const char *mode) {
 43!   FILE *result;
 44    instw_t instw;
 45    int status=0;
 46  
 47--- 2545,2551 ----
 48  }
 49  
 50  FILE *fopen(const char *pathname, const char *mode) {
 51!   FILE *result = NULL;
 52    instw_t instw;
 53    int status=0;
 54  
 55***************
 56*** 2956,2962 ****
 57    return result;
 58  }
 59  
 60! #if (GLIBC_MINOR <= 4)
 61  int readlink(const char *path,char *buf,size_t bufsiz) {
 62    int result;
 63  #else
 64--- 2956,2962 ----
 65    return result;
 66  }
 67  
 68! #if 0
 69  int readlink(const char *path,char *buf,size_t bufsiz) {
 70    int result;
 71  #else
 72***************
 73*** 3096,3103 ****
 74  }
 75  
 76  int scandir(  const char *dir,struct dirent ***namelist,
 77!       int (*select)(const struct dirent *),
 78! #if (GLIBC_MINOR >= 10)
 79        int (*compar)(const struct dirent **,const struct dirent **)    ) {
 80  #else
 81        int (*compar)(const void *,const void *)    ) {
 82--- 3096,3103 ----
 83  }
 84  
 85  int scandir(  const char *dir,struct dirent ***namelist,
 86!       int (*filter)(const struct dirent *),
 87! #if 1
 88        int (*compar)(const struct dirent **,const struct dirent **)    ) {
 89  #else
 90        int (*compar)(const void *,const void *)    ) {
 91***************
 92*** 3114,3124 ****
 93      /* We were asked to work in "real" mode */
 94    if( !(__instw.gstatus & INSTW_INITIALIZED) ||
 95        !(__instw.gstatus & INSTW_OKWRAP) ) {
 96!       result=true_scandir(dir,namelist,select,compar);
 97        return result;
 98    }
 99  
100!   result=true_scandir(dir,namelist,select,compar);
101  
102    return result;
103  }     
104--- 3114,3124 ----
105      /* We were asked to work in "real" mode */
106    if( !(__instw.gstatus & INSTW_INITIALIZED) ||
107        !(__instw.gstatus & INSTW_OKWRAP) ) {
108!       result=true_scandir(dir,namelist,filter,compar);
109        return result;
110    }
111  
112!   result=true_scandir(dir,namelist,filter,compar);
113  
114    return result;
115  }     
116***************
117*** 3712,3719 ****
118  }
119  
120  int scandir64(    const char *dir,struct dirent64 ***namelist,
121!       int (*select)(const struct dirent64 *),
122! #if (GLIBC_MINOR >= 10)
123        int (*compar)(const struct dirent64 **,const struct dirent64 **)    ) {
124  #else
125        int (*compar)(const void *,const void *)    ) {
126--- 3712,3719 ----
127  }
128  
129  int scandir64(    const char *dir,struct dirent64 ***namelist,
130!       int (*filter)(const struct dirent64 *),
131! #if 1
132        int (*compar)(const struct dirent64 **,const struct dirent64 **)    ) {
133  #else
134        int (*compar)(const void *,const void *)    ) {
135***************
136*** 3730,3740 ****
137      /* We were asked to work in "real" mode */
138    if( !(__instw.gstatus & INSTW_INITIALIZED) ||
139        !(__instw.gstatus & INSTW_OKWRAP) ) {
140!       result=true_scandir64(dir,namelist,select,compar);
141        return result;
142    }
143  
144!   result=true_scandir64(dir,namelist,select,compar);
145  
146    return result;
147  }     
148--- 3730,3740 ----
149      /* We were asked to work in "real" mode */
150    if( !(__instw.gstatus & INSTW_INITIALIZED) ||
151        !(__instw.gstatus & INSTW_OKWRAP) ) {
152!       result=true_scandir64(dir,namelist,filter,compar);
153        return result;
154    }
155  
156!   result=true_scandir64(dir,namelist,filter,compar);
157  
158    return result;
159  }     
    
2014/05/22 に git clone した checkinstall のソースに このパッチを適用してコンパイル、動作する事は確認できている。
Amazon Linux で checkinstall の導入に困っている方の参考になればと思い公開してみる。

Edit this entry...

wikieditish message: Ready to edit this entry.
















A quick preview will be rendered here when you click "Preview" button.