いがらしです。
去年のメイルですがreplyがつかなかったので……ruby-devに振ります。

At Thu, 02 Dec 1999 15:06:43 +0900,
in [ruby-ext:00646] have_func in extconf.rb,
Hiroshi IGARASHI <igarashi / ueda.info.waseda.ac.jp> wrote:

> mkmf.rbあるいはextmk.rbが提供しているhave_funcメソッドで
> 特定の関数の存在をチェックできるはずですが……
> もし関数と思っていたものがマクロで定義されているとしたら、
> 見つからないことになりますよね。
> 
> mkmf.rbなどでは
> 
> /* #include <iconv.h> */
> int main() { return 0; }
> int t() { #{func}(); return 0; }
> 
> というプログラムをコンパイルすることによって調べているようですが、
> 上のコメントのようにincludeするヘッダファイルも指定できるといいなと
> 思います。例えばhave_func("iconv", "iconv.h")とか。

この通りhave_funcにheaderを指定できるようにしたら、
今度はマクロ定義だけでなくprototype宣言も与えられたため、
単に無引数で呼び出しても引数の検査でコンパイルエラーに
なってしまいます。

[ruby-dev:9974]で、/mswin32|mingw/ =~ RUBY_PLATFORM な環境では
関数呼出と関数ポインタの参照の両方でチェックする必要がある
とのことですが、他の環境でも両方チェックするようにすれば
とりあえず引数検査でのエラーは避けられます。

というわけでパッチをつけておきます。

> iconv()のwrapperを、glibcじゃない怪しげなiconv実装と一緒に
> コンパイルしようとした時にはまりました。

今回は[ruby-list:23353]で紹介されていたiconv実装で試したのですが、
こちらもライブラリにはlibiconv()があって、
iconv.hでは #define iconv libiconv してます。

--
五十嵐  宏  (Hiroshi IGARASHI)

Mon Jun 19 22:21:31 2000 Hiroshi IGARASHI <iga / ruby-lang.org> * ext/extmk.rb.in: have_func() takes 2nd argument to specify a header file and do tests twice in all platforms. * lib/mkmf.rb: ditto.
Index: ext/extmk.rb.in =================================================================== RCS file: /home/cvs/ruby/ext/extmk.rb.in,v retrieving revision 1.16 diff -u -r1.16 extmk.rb.in --- ext/extmk.rb.in 2000/06/12 07:48:25 1.16 +++ ext/extmk.rb.in 2000/06/19 14:04:11 @@ -218,28 +218,30 @@ return true end -def have_func(func) +def have_func(func, header=nil) libs = $libs - - if /mswin32|mingw/ =~ RUBY_PLATFORM - r = try_link(<<"SRC", libs) + src = + if /mswin32|mingw/ =~ RUBY_PLATFORM + r = <<"SRC" #include <windows.h> #include <winsock.h> +SRC + else + "" + end + unless header.nil? + src << <<"SRC" +#include <#{header}> +SRC + end + r = try_link(src + <<"SRC", libs) int main() { return 0; } int t() { #{func}(); return 0; } SRC - unless r - r = try_link(<<"SRC", libs) -#include <windows.h> -#include <winsock.h> + unless r + r = try_link(src + <<"SRC", libs) int main() { return 0; } int t() { void ((*p)()); p = (void ((*)()))#{func}; return 0; } -SRC - end - else - r = try_link(<<"SRC", libs) -int main() { return 0; } -int t() { #{func}(); return 0; } SRC end unless r Index: lib/mkmf.rb =================================================================== RCS file: /home/cvs/ruby/lib/mkmf.rb,v retrieving revision 1.18 diff -u -r1.18 mkmf.rb --- lib/mkmf.rb 2000/06/19 03:37:55 1.18 +++ lib/mkmf.rb 2000/06/19 14:04:12 @@ -210,31 +210,33 @@ return true end -def have_func(func) +def have_func(func, header=nil) printf "checking for %s()... ", func STDOUT.flush libs = $libs - - if /mswin32|mingw/ =~ RUBY_PLATFORM - r = try_link(<<"SRC", libs) + src = + if /mswin32|mingw/ =~ RUBY_PLATFORM + r = <<"SRC" #include <windows.h> #include <winsock.h> +SRC + else + "" + end + unless header.nil? + src << <<"SRC" +#include <#{header}> +SRC + end + r = try_link(src + <<"SRC", libs) int main() { return 0; } int t() { #{func}(); return 0; } SRC - unless r - r = try_link(<<"SRC", libs) -#include <windows.h> -#include <winsock.h> + unless r + r = try_link(src + <<"SRC", libs) int main() { return 0; } int t() { void ((*p)()); p = (void ((*)()))#{func}; return 0; } -SRC - end - else - r = try_link(<<"SRC", libs) -int main() { return 0; } -int t() { #{func}(); return 0; } SRC end unless r