From: "KISHIMOTO, Makoto" Date: 2009-02-19T18:55:32+09:00 Subject: [ruby-dev:38052] mkmf.rb の C++ 対応 きしもとです C++ のヘッダだと、現在の (have|find)_header ではうまく判定できない ことがあるので( cc -E だとたとえば #include とかでうまくない) (have|find)_cxx_header というコマンドを追加してみました。 C++ のプリプロセッサのための config がうまくわからなかったので、 C++ コンパイラにかけてチェックしています。Boost の巨大なヘッダとかで チェックだけなのに無茶苦茶時間をかけてしまうという問題が出るかも しれません。 Index: lib/mkmf.rb =================================================================== --- lib/mkmf.rb (revision 22439) +++ lib/mkmf.rb (working copy) @@ -400,6 +400,14 @@ conf) end +def cxx_command(opt="") + conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote, + 'arch_hdrdir' => "#$arch_hdrdir", + 'top_srcdir' => $top_srcdir.quote) + RbConfig::expand("$(CXX) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", + conf) +end + def libpathflag(libpath=$DEFLIBPATH|$LIBPATH) libpath.map{|x| case x @@ -437,6 +445,12 @@ alias_method :try_header, (config_string('try_header') || :try_cpp) end +def try_cxx(src, opt="", &b) + try_do(src, cxx_command(opt), &b) +ensure + rm_f "conftest*" +end + def cpp_include(header) if header header = [header] unless header.kind_of? Array @@ -819,6 +833,17 @@ end end +def have_cxx_header(header, preheaders = nil, &b) + checking_for header do + if try_cxx(cpp_include(preheaders)+cpp_include(header), &b) + $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___"))) + true + else + false + end + end +end + # Instructs mkmf to search for the given +header+ in any of the +paths+ # provided, and returns whether or not it was found in those paths. # @@ -846,6 +871,27 @@ end end +def find_cxx_header(header, *paths) + message = checking_message(header, paths) + header = cpp_include(header) + checking_for message do + if try_cxx(header) + true + else + found = false + paths.each do |dir| + opt = "-I#{dir}".quote + if try_cxx(header, opt) + $INCFLAGS << " " << opt + found = true + break + end + end + found + end + end +end + # Returns whether or not the struct of type +type+ contains +member+. If # it does not, or the struct type can't be found, then false is returned. You # may optionally specify additional +headers+ in which to look for the struct