はじめに
mfiler4というファイラーがあります。
http://sourceforge.jp/projects/mfiler4/
mfiler4 1.1.1をUbuntu 12.04LTSの環境でコンパイルしようとしたときに、以下のようなコンパイルエラーに遭遇しました。
git HEADでも状況は同様でした。
-[3527]% LANG=C make gcc -DSYSCONFDIR="\"/home/kenhys/etc/mfiler4/\"" -DDATAROOTDIR="\"/home/kenhys/share/doc/mfiler4/\"" -DSYSTEM_MIGEMODIR="\"/usr/share/cmigemo\"" -Isrc/ -I/home/kenhys/include -L/home/kenhys/lib -I . -I/usr/local/include -L/usr/local/lib -Werror -c -o src/filer.o src/filer.c src/filer.c: In function 'make_file_stat': src/filer.c:1441:9: error: format '%d' expects argument of type 'int', but argument 4 has type '__nlink_t' [-Werror=format] src/filer.c:1441:9: error: format '%d' expects argument of type 'int', but argument 4 has type '__nlink_t' [-Werror=format] src/filer.c: In function 'cmdline_view_filer': src/filer.c:2530:13: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format] src/filer.c:2530:13: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format] src/filer.c:2549:12: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format] src/filer.c:2549:12: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format] cc1: all warnings being treated as errors make: *** [src/filer.o] Error 1
問題点とパッチ
64bit環境と、それ以外では型修飾子に指定すべきものが違う、というのが肝です。
そこで以下のようにしてみました。longかそうでないかで分岐します。
diff --git a/src/common.h b/src/common.h index b724127..1b65350 100644 --- a/src/common.h +++ b/src/common.h @@ -38,6 +38,12 @@ #define S_IXUGO (S_IXOTH | S_IXGRP | S_IXUSR) +#if defined(__x86_64__) + #define FORMAT_HARDLINK "%3ld" +#else + #define FORMAT_HARDLINK "%3d" +#endif + ////////////////////////////////////////////// // main.c /////////////////////////////////////////////// diff --git a/src/filer.c b/src/filer.c index 2d03879..d52eaa8 100644 --- a/src/filer.c +++ b/src/filer.c @@ -1436,7 +1436,7 @@ static void make_file_stat(sFile* file, char* buf, int buf_size) char* env_nlink = getenv("VIEW_NLINK"); if(env_nlink && strcmp(env_nlink, "1") == 0) { - snprintf(buf + strlen(buf), buf_size -strlen(buf), " %3d", file->mStat.st_nlink); + snprintf(buf + strlen(buf), buf_size -strlen(buf), " "FORMAT_HARDLINK, file->mStat.st_nlink); } char* env_owner = getenv("VIEW_OWNER"); @@ -2516,7 +2516,7 @@ void cmdline_view_filer() while(year > 100) year-=100; snprintf(buf2, 1024, - "%s %3d %-8s %-7s%s %02d-%02d-%02d %02d:%02d %s" + "%s "FORMAT_HARDLINK" %-8s %-7s%s %02d-%02d-%02d %02d:%02d %s" //, "%s %3d %-8s %-7s%10lld %02d-%02d-%02d %02d:%02d %s" , permission, file->mLStat.st_nlink , owner, group @@ -2534,7 +2534,7 @@ void cmdline_view_filer() } else { snprintf(buf, 1024, - "%s %3d %s%s%s %02d-%02d-%02d %02d:%02d %s -> %s" + "%s "FORMAT_HARDLINK" %s%s%s %02d-%02d-%02d %02d:%02d %s -> %s" //, "%s %3d %s%s%10lld %02d-%02d-%02d %02d:%02d %s -> %s" , permission, file->mLStat.st_nlink , owner, group
これともうひとつcursesがらみでもエラーになる部分がありました。
そちらはA_*がunsigned longとして定義されていることに由来するものです。
-[3508]% grep A_REVERSE /usr/include/**/*.h /usr/include/curses.h:#define WA_REVERSE A_REVERSE /usr/include/curses.h:#define A_REVERSE NCURSES_BITS(1UL,10) /usr/include/ncurses.h:#define WA_REVERSE A_REVERSE /usr/include/ncurses.h:#define A_REVERSE NCURSES_BITS(1UL,10) /usr/include/ncursesw/curses.h:#define WA_REVERSE A_REVERSE /usr/include/ncursesw/curses.h:#define A_REVERSE NCURSES_BITS(1UL,10) /usr/include/ncursesw/ncurses.h:#define WA_REVERSE A_REVERSE /usr/include/ncursesw/ncurses.h:#define A_REVERSE NCURSES_BITS(1UL,10)
こちらについても、パッチは似たような感じになります。
diff --git a/src/main.c b/src/main.c index 8ebe03c..e95ac19 100644 --- a/src/main.c +++ b/src/main.c @@ -541,11 +541,11 @@ static void set_mfenv() setenv("nometa", buf, 1); snprintf(buf,128, "%d", 1); setenv("meta", buf, 1); - snprintf(buf,128, "%d", A_REVERSE); + snprintf(buf,128, "%ld", A_REVERSE); setenv("ma_reverse", buf, 1); - snprintf(buf,128, "%d", A_BOLD); + snprintf(buf,128, "%ld", A_BOLD); setenv("ma_bold", buf, 1); - snprintf(buf,128, "%d", A_UNDERLINE); + snprintf(buf,128, "%ld", A_UNDERLINE); setenv("ma_underline", buf, 1); snprintf(buf,128, "%d", COLOR_PAIR(1)); setenv("ma_white", buf, 1);
まとめ
mfiler4を64bit環境でコンパイルするための方法を紹介しました。
それでは良いmfiler4ライフを。