undefined reference to `sync_file_range'

CentOS 5.6 でのお話です。たぶん、CentOS 5系であれば、同じ結果になるのではないかな思います。
node.jsのv0.5.1を本家からダウンロード(http://nodejs.org/dist/v0.5.1/node-v0.5.1.tar.gz)して、makeをすると、


/usr/local/src/node-v0.5.1/build/default/deps/uv/src/eio/eio.c:923: undefined reference to `sync_file_range'
collect2: ld はステータス 1 で終了しました
Waf: Leaving directory `/usr/local/src/node-v0.5.1/build'
Build failed: -> task failed (err #1):
{task: cxx_link node_main_5.o,node_5.o,node_buffer_5.o,node_javascript_5.o,
node_extensions_5.o,node_http_parser_5.o,node_constants_5.o,node_events_5.o,
node_file_5.o,node_script_5.o,node_os_5.o,node_dtrace_5.o,node_string_5.o,
timer_wrap_5.o,tcp_wrap_5.o,cares_wrap_5.o,node_cares_5.o,node_net_5.o,
node_signal_watcher_5.o,node_stat_watcher_5.o,node_io_watcher_5.o,node_stdio_5.o,
node_child_process_5.o,node_timer_5.o,platform_linux_5.o,node_crypto_5.o,
http_parser_3.o -> node}

make: *** [program] エラー 1

と、いわれて*1コンパイルエラーになります。:P

あれ?と、思って少し調べてみると、undefined reference to `sync_file_range'は、RHEL5のBugのバグのようです。
518581 – [RHEL5] glibc misses sync_file_range syscall interface


この問題、glibc を2.6にするという対処方もあるようですが、明らかにめんどくさいので根本的な原因をつかんで、対象してみました。
結論としては、sync_file_rangeの使用判断をしているファイル、

deps/uv/src/eio/config_linux.h

を書き換えてしまえばOKです。マクロ HAVE_SYNC_FILE_RANGE でsync_file_rangeの使用可能判断をしていますので、これをちょこっと変えてあげればコンパイルできます。

変更方法は、

#define HAVE_SYNC_FILE_RANGE LINUX_VERSION_AT_LEAST(2, 6, 17)

となっている部分をコメントアウトしてしまってもいいのですが、汎用的に変更する方法がFix to check glibc version for HAVE_SYNC_FILE_RANGE by shigeki · Pull Request #1338 · nodejs/node-v0.x-archive · GitHubに載っています。「glibcを使用している場合は、version2.6以降でないと、sync_file_rangeは、使用しませんよ。」という変更を加えるだけです。簡単ですね。:)

なお、v0.4.xだと、./configureの際、sync_file_rangeが使用できない事を確認します*2が、v.0.5.x系の場合は、headerファイルのマクロ内でkernelバージョンだけで判断しているということが影響しているようです。

*1:見難いので手動で改行入れています。

*2:詳しい確認はしていません