snapshot の更新はあんまりされないため、思い切って svn repository からビルドしようかと思い、wiki を覗いてみた。
すると何時の間にか依存リストの先頭が Eet から Eina に変わっていた。
Now, let's proceed and install the core libraries. There are six and should be installed in this order:
そもそも Eet 自体が EFL 内の階層の最もプリミティブなライブラリだと思っていたのだが、さらにその下に Eina というライブラリが出現したわけでその spec ファイルにも
Summary: Data Type Library
%description
Eina is a data type library.
というそっけない説明しかなく、さっぱりだが、まあよりプリミティブなライブラリなのかなと納得しておくことにする。
とりあえず svn checkout して、ビルドしてみるわけだが、相変わらず開発者の方々は Linux (と *BSD) 以外はあんまり考慮されていないみたいである。*1
/cygdrive/b/eina/src/lib/eina_file.c: In function `eina_file_dir_list': /cygdrive/b/eina/src/lib/eina_file.c:142: error: structure has no member named `d_type' /cygdrive/b/eina/src/lib/eina_file.c:142: error: `DT_UNKNOWN' undeclared (first use in this function) /cygdrive/b/eina/src/lib/eina_file.c:142: error: (Each undeclared identifier is reported only once /cygdrive/b/eina/src/lib/eina_file.c:142: error: for each function it appears in.) /cygdrive/b/eina/src/lib/eina_file.c:150: error: structure has no member named `d_type' /cygdrive/b/eina/src/lib/eina_file.c:150: error: `DT_DIR' undeclared (first use in this function)
118 struct dirent *de; 119 DIR *d; 120 121 if (!cb) return EINA_FALSE; 122 123 d = opendir(dir); 124 if (!d) return EINA_FALSE; 125 126 while ((de = readdir(d))) 127 { 128 if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) 129 continue; 130 131 cb(de->d_name, dir, data); 132 /* d_type is only available on linux and bsd (_BSD_SOURCE) */ 133 134 if (recursive == EINA_TRUE) { 135 char *path; 136 137 path = alloca(strlen(dir) + strlen(de->d_name) + 2); 138 strcpy(path, dir); 139 strcat(path, "/"); 140 strcat(path, de->d_name); 141 142 if (de->d_type == DT_UNKNOWN) { 143 struct stat st; 144 145 if (stat(path, &st)) 146 continue ; 147 148 if (!S_ISDIR(st.st_mode)) 149 continue ; 150 } else if (de->d_type != DT_DIR) { 151 continue ; 152 } 153 154 eina_file_dir_list(path, recursive, cb, data); 155 } 156 }
手元の cygwin の /usr/include/sys/dirent.h を見ると、たしかに struct dirent に d_type というメンバはない。
#if defined(__INSIDE_CYGWIN__) || defined (__CYGWIN_USE_BIG_TYPES__) struct dirent { long __d_version; /* Used internally */ __ino64_t d_ino; __uint32_t __d_unused1; __uint32_t __d_internal1; char d_name[256]; /* FIXME: use NAME_MAX? */ }; #else struct dirent { long d_version; long d_reserved[2]; long d_fd; ino_t d_ino; char d_name[256]; }; #endif
おまけに DT_* マクロは無効化までされている始末。
#if 0 /* these make no sense in the absence of d_type */ /* File types for `d_type'. */ enum { DT_UNKNOWN = 0, # define DT_UNKNOWN DT_UNKNOWN DT_FIFO = 1, # define DT_FIFO DT_FIFO DT_CHR = 2, # define DT_CHR DT_CHR DT_DIR = 4, # define DT_DIR DT_DIR DT_BLK = 6, # define DT_BLK DT_BLK DT_REG = 8, # define DT_REG DT_REG DT_LNK = 10, # define DT_LNK DT_LNK DT_SOCK = 12, # define DT_SOCK DT_SOCK DT_WHT = 14 # define DT_WHT DT_WHT }; /* Convert between stat structure types and directory types. */ # define IFTODT(mode) (((mode) & 0170000) >> 12) # define DTTOIF(dirtype) ((dirtype) << 12) #endif /* #if 0 */
ところが cvs を見ると、最新の 1.20 で追加されているみたい。もうちょっと早く対応してくれれば、良かったのに。><
そもそも無理に dirent の d_type を見なくても、全部 stat を S_ISDIR でチェックするというコードにすれば良い気がするのだけど、どういう意図があるのだろうか?