diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | ext/socket/extconf.rb | 204 | ||||
-rw-r--r-- | lib/mkmf.rb | 174 |
3 files changed, 203 insertions, 202 deletions
@@ -1,3 +1,24 @@ +Sun Feb 6 23:50:36 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/socket/extconf.rb: check if getaddrinfo() works fine only when + wide-getaddrinfo option is not given. fixed: [ruby-dev:25422] + + * lib/mkmf.rb ($extmk): check if under ext directory. + + * lib/mkmf.rb (Logging.postpone): allow recursive operation. + + * lib/mkmf.rb (try_constant): make sure if really a constant, reduce + the number of times of compile. + + * lib/mkmf.rb (have_macro, have_var, byte_order): new functions. + + * lib/mkmf.rb (find_library): allow directory list with separators. + + * lib/mkmf.rb (arg_config): manage provided configuration options. + + * lib/mkmf.rb (dir_config): accept arrays of directory names as + default values. + Sun Feb 6 19:23:01 2005 NAKAMURA Usaku <usa@ruby-lang.org> * eval.c (stack_extend): add prototype because VC++8 doesn't @@ -21,10 +42,10 @@ Sun Feb 6 12:20:11 2005 Akinori MUSHA <knu@iDaemons.org> Sun Feb 6 03:24:20 2005 Tanaka Akira <akr@m17n.org> - * lib/resolv.rb (Resolv::DNS::Resource::TXT): multiple strings was not - handled. + * lib/resolv.rb (Resolv::DNS::Resource::TXT): multiple strings was not + handled. (Resolv::DNS::Resource::TXT#strings): new method to return all - strings. + strings. (Resolv::DNS::Message::MessageEncoder#put_string_list): new method. (Resolv::DNS::Message::MessageDecoder#get_string_list): ditto. based on [ruby-talk:129732] by Sam Roberts. diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 4f7b49407f..66d7462cbf 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -24,10 +24,18 @@ else have_library("socket", "socket") end +unless $mswin or $bccwin or $mingw + headers = %w<sys/types.h netdb.h string.h sys/socket.h netinet/in.h> +end +if /solaris/ =~ RUBY_PLATFORM and !try_compile("") + # bug of gcc 3.0 on Solaris 8 ? + headers << "sys/feature_tests.h" +end + $ipv6 = false default_ipv6 = /cygwin/ !~ RUBY_PLATFORM if enable_config("ipv6", default_ipv6) - if try_link(<<EOF) + if checking_for("ipv6") {try_link(<<EOF)} #include <sys/types.h> #include <sys/socket.h> main() @@ -105,90 +113,26 @@ EOS end end - if try_link(<<EOF) -#ifdef _WIN32 -# include <windows.h> -# include <winsock.h> -#else -# include <sys/types.h> -# include <netdb.h> -# include <string.h> -# include <sys/socket.h> -# include <netinet/in.h> -#endif -int -main() -{ - struct sockaddr_in sin; - - sin.sin_len; - return 0; -} -EOF - $CFLAGS="-DHAVE_SIN_LEN "+$CFLAGS +if have_struct_member("struct sockaddr_in", "sin_len", headers) + $defs[-1] = "-DHAVE_SIN_LEN" end - if try_link(<<EOF) -#ifdef _WIN32 -# include <windows.h> -# include <winsock.h> -#else -# include <sys/types.h> -# include <netdb.h> -# include <string.h> -# include <sys/socket.h> -#endif -int -main() -{ - struct sockaddr_storage ss; - - ss.ss_family; - return 0; -} -EOF - $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS -else # doug's fix, NOW add -Dss_family... only if required! -$CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len" - if try_link(<<EOF) -#ifdef _WIN32 -# include <windows.h> -# include <winsock.h> -#else -# include <sys/types.h> -# include <netdb.h> -# include <string.h> -# include <sys/socket.h> -#endif -int -main() -{ - struct sockaddr_storage ss; - - ss.ss_family; - return 0; -} -EOF - $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS -end +# doug's fix, NOW add -Dss_family... only if required! +[nil, " -Dss_family=__ss_family -Dss_len=__ss_len"].each do |flags| + if flags + cppflags = $CPPFLAGS + $CPPFLAGS += flags + end + if have_struct_member("struct sockaddr_storage", "ss_family", headers) + $defs[-1] = "-DHAVE_SOCKADDR_STORAGE" + break + elsif flags + $CPPFLAGS = cppflags + end end - if try_link(<<EOF) -#include <sys/types.h> -#include <netdb.h> -#include <string.h> -#include <sys/socket.h> -#include <netinet/in.h> -int -main() -{ - struct sockaddr sa; - - sa.sa_len; - return 0; -} -EOF - $CFLAGS="-DHAVE_SA_LEN "+$CFLAGS +if have_struct_member("struct sockaddr", "sa_len", headers) + $defs[-1] = "-DHAVE_SA_LEN " end have_header("netinet/tcp.h") if not /cygwin/ =~ RUBY_PLATFORM # for cygwin 1.1.5 @@ -199,13 +143,17 @@ if have_func("sendmsg") | have_func("recvmsg") have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h']) end -$getaddr_info_ok = false -if !enable_config("wide-getaddrinfo", false) and try_run(<<EOF) -#include <sys/types.h> -#include <netdb.h> -#include <string.h> -#include <sys/socket.h> -#include <netinet/in.h> +getaddr_info_ok = enable_config("wide-getaddrinfo") do + checking_for("wide getaddrinfo") {try_run(<<EOF)} +#{cpp_include(headers)} +#include <stdlib.h> + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX @@ -281,79 +229,46 @@ main() if (aitop) freeaddrinfo(aitop); - exit(0); + exit(EXIT_SUCCESS); bad: if (aitop) freeaddrinfo(aitop); - exit(1); + exit(EXIT_FAILURE); } EOF - $getaddr_info_ok = true end -if $ipv6 and not $getaddr_info_ok - print <<EOS +if $ipv6 and not getaddr_info_ok + abort <<EOS Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature. But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry, you cannot compile IPv6 socket classes with broken these functions. You can try --enable-wide-getaddrinfo. EOS - exit end - + case with_config("lookup-order-hack", "UNSPEC") when "INET" - $CFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CFLAGS + $defs << "-DLOOKUP_ORDER_HACK_INET" when "INET6" - $CFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CFLAGS + $defs << "-DLOOKUP_ORDER_HACK_INET6" when "UNSPEC" # nothing special else - print <<EOS + abort <<EOS Fatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC) EOS - exit end $objs = ["socket.#{$OBJEXT}"] - -if $getaddr_info_ok and have_func("getaddrinfo", "netdb.h") and have_func("getnameinfo", "netdb.h") - have_getaddrinfo = true -else - if try_link(<<EOF) -#ifndef _WIN32 -# include <sys/types.h> -# include <netdb.h> -# include <string.h> -# include <sys/socket.h> -# include <netinet/in.h> -#else -# include <windows.h> -# ifdef _WIN32_WCE -# include <winsock.h> -# else -# include <winsock.h> -# endif -#endif -int -main() -{ - struct in6_addr addr; - unsigned char c; - c = addr.s6_addr8; - return 0; -} -EOF - $CFLAGS="-DHAVE_ADDR8 "+$CFLAGS - end -end -if have_getaddrinfo - $CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS -else - $CFLAGS="-I. "+$CFLAGS +unless getaddr_info_ok and have_func("getnameinfo", "netdb.h") and have_func("getaddrinfo", "netdb.h") + if have_struct_member("struct in6_addr", "s6_addr8", headers) + $defs[-1] = "-DHAVE_ADDR8" + end + $CPPFLAGS="-I. "+$CPPFLAGS $objs += ["getaddrinfo.#{$OBJEXT}"] $objs += ["getnameinfo.#{$OBJEXT}"] have_func("inet_ntop") or have_func("inet_ntoa") @@ -364,20 +279,8 @@ else have_header("resolv.h") end -if !try_link(<<EOF) -#include <sys/types.h> -#include <netdb.h> -#include <string.h> -#include <sys/socket.h> -#include <netinet/in.h> -int -main() -{ - socklen_t len; - return 0; -} -EOF - $CFLAGS="-Dsocklen_t=int "+$CFLAGS +unless have_type("socklen_t", headers) + $defs << "-Dsocklen_t=int" end have_header("sys/un.h") @@ -386,14 +289,15 @@ have_header("sys/uio.h") if have_func(test_func) have_func("hsterror") have_func("getipnodebyname") or have_func("gethostbyname2") + have_func("socketpair") unless have_func("gethostname") have_func("uname") end if enable_config("socks", ENV["SOCKS_SERVER"]) if have_library("socks5", "SOCKSinit") - $CFLAGS+=" -DSOCKS5 -DSOCKS" + $defs << "-DSOCKS5" << "-DSOCKS" elsif have_library("socks", "Rconnect") - $CFLAGS+=" -DSOCKS" + $defs << "-DSOCKS" end end create_makefile("socket") diff --git a/lib/mkmf.rb b/lib/mkmf.rb index 494838e63b..cf78a0f5c9 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -40,7 +40,7 @@ unless defined? $configure_args end end -$srcdir = CONFIG["srcdir"] +$srcdir = nil $libdir = CONFIG["libdir"] $rubylibdir = CONFIG["rubylibdir"] $archdir = CONFIG["archdir"] @@ -78,13 +78,14 @@ def map_dir(dir, map = nil) map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)} end -libdir = File.dirname(__FILE__) -$extmk = libdir != Config::CONFIG["rubylibdir"] -if not $extmk and File.exist? Config::CONFIG["archdir"] + "/ruby.h" +topdir = File.dirname(libdir = File.dirname(__FILE__)) +extdir = File.expand_path("ext", topdir) +$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/" +if not $extmk and File.exist?(Config::CONFIG["archdir"] + "/ruby.h") $hdrdir = $topdir = Config::CONFIG["archdir"] -elsif File.exist? $srcdir + "/ruby.h" - $topdir = Config::CONFIG["compile_dir"] - $hdrdir = $srcdir +elsif File.exist?(($top_srcdir ||= topdir) + "/ruby.h") and + File.exist?(($topdir ||= Config::CONFIG["topdir"]) + "/config.h") + $hdrdir = $top_srcdir else abort "can't find header files for ruby." end @@ -136,6 +137,7 @@ module Logging @logfile = 'mkmf.log' @orgerr = $stderr.dup @orgout = $stdout.dup + @postpone = 0 def self::open @log ||= File::open(@logfile, 'w') @@ -164,7 +166,7 @@ module Logging end def self::postpone - tmplog = "mkmftmp.log" + tmplog = "mkmftmp#{@postpone += 1}.log" open do log, *save = @log, @logfile, @orgout, @orgerr @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log @@ -174,6 +176,7 @@ module Logging File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} ensure @log, @logfile, @orgout, @orgerr = log, *save + @postpone -= 1 rm_f tmplog end end @@ -293,48 +296,52 @@ def try_static_assert(expr, headers = nil, opt = "", &b) #{COMMON_HEADERS} #{headers} /*top*/ -int tmp[(#{expr}) ? 1 : -1]; +int conftest_const[(#{expr}) ? 1 : -1]; SRC end def try_constant(const, headers = nil, opt = "", &b) - headers = cpp_include(headers) + includes = cpp_include(headers) if CROSS_COMPILING - unless try_compile(<<"SRC", opt, &b) -#{COMMON_HEADERS} -#{headers} -/*top*/ -int tmp = #{const}; -SRC - return nil - end - if try_static_assert("#{const} < 0", headers, opt) + if try_static_assert("#{const} > 0", headers, opt) + # positive constant + elsif try_static_assert("#{const} < 0", headers, opt) neg = true const = "-(#{const})" elsif try_static_assert("#{const} == 0", headers, opt) return 0 + else + # not a constant + return nil end upper = 1 - until try_static_assert("#{const} < #{upper}", headers, opt) + until try_static_assert("#{const} <= #{upper}", headers, opt) lower = upper upper <<= 1 end return nil unless lower - until try_static_assert("#{const} == #{upper}", headers, opt) - if try_static_assert("#{const} > #{(upper+lower)/2}", headers, opt) - lower = (upper+lower)/2 + while upper > lower + 1 + mid = (upper + lower) / 2 + if try_static_assert("#{const} > #{mid}", headers, opt) + lower = mid else - upper = (upper+lower)/2 + upper = mid + end + end + unless upper == lower + if try_static_assert("#{const} == #{lower}", headers, opt) + upper = lower end end upper = -upper if neg return upper else src = %{#{COMMON_HEADERS} -#{headers} +#{includes} #include <stdio.h> /*top*/ -int main() {printf("%d\\n", (int)(#{const})); return 0;} +int conftest_const = (int)(#{const}); +int main() {printf("%d\\n", conftest_const); return 0;} } if try_link0(src, opt, &b) xpopen("./conftest") do |f| @@ -361,6 +368,17 @@ int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; } SRC end +def try_var(var, headers = nil, &b) + headers = cpp_include(headers) + try_compile(<<"SRC", &b) +#{COMMON_HEADERS} +#{headers} +/*top*/ +int main() { return 0; } +int t() { void *volatile p; p = (void *)&#{var}; return 0; } +SRC +end + def egrep_cpp(pat, src, opt = "", &b) src = create_tmpsrc(src, &b) xpopen(cpp_command('', opt)) do |f| @@ -459,14 +477,14 @@ def message(*s) end end -def checking_for(m) +def checking_for(m, fmt = nil) f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim m = "checking for #{m}... " message "%s", m a = r = nil Logging::postpone do r = yield - a = r ? "yes\n" : "no\n" + a = (fmt ? fmt % r : r ? "yes" : "no") << "\n" "#{f}#{m}-------------------- #{a}\n" end message(a) @@ -474,6 +492,14 @@ def checking_for(m) r end +def have_macro(macro, headers = nil, opt = "", &b) + m = "#{macro}" + m << " in #{headers.inspect}" if headers + checking_for m do + macro_defined?(macro, cpp_include(headers), opt, &b) + end +end + def have_library(lib, func = nil, header=nil, &b) func = "main" if !func or func.empty? lib = with_config(lib+'lib', lib) @@ -495,6 +521,7 @@ end def find_library(lib, func, *paths, &b) func = "main" if !func or func.empty? lib = with_config(lib+'lib', lib) + paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten checking_for "#{func}() in #{LIBARG%lib}" do libpath = $LIBPATH libs = append_library($libs, lib) @@ -524,6 +551,19 @@ def have_func(func, headers = nil, &b) end end +def have_var(var, headers = nil, &b) + checking_for "#{var}" do + libs = append_library($libs, libs) + if try_var(var, headers, &b) + $libs = libs + $defs.push(format("-DHAVE_%s", var.upcase)) + true + else + false + end + end +end + def have_header(header, &b) checking_for header do if try_cpp(cpp_include(header), &b) @@ -604,24 +644,28 @@ def find_executable(bin, path = nil) end end -def arg_config(config, default=nil) - $configure_args.fetch(config.tr('_', '-'), default) +def arg_config(config, *defaults, &block) + $arg_config << [config, *defaults] + defaults << nil if !block and defaults.empty? + $configure_args.fetch(config.tr('_', '-'), *defaults, &block) end -def with_config(config, default=nil) +def with_config(config, *defaults, &block) unless /^--with[-_]/ =~ config config = '--with-' + config end - arg_config(config, default) + arg_config(config, *defaults, &block) end -def enable_config(config, default=nil) +def enable_config(config, *defaults) if arg_config("--enable-"+config) true elsif arg_config("--disable-"+config) false + elsif block_given? + yield(config, *defaults) else - default + return *defaults end end @@ -646,15 +690,16 @@ end def dir_config(target, idefault=nil, ldefault=nil) if dir = with_config(target + "-dir", (idefault unless ldefault)) - defaults = dir.split(File::PATH_SEPARATOR) + defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR) idefault = ldefault = nil end idir = with_config(target + "-include", idefault) + $arg_config.last[1] ||= "${#{target}-dir}/include" ldir = with_config(target + "-lib", ldefault) + $arg_config.last[1] ||= "${#{target}-dir}/lib" -# idirs = idir ? idir.split(File::PATH_SEPARATOR) : [] - idirs = idir.split(File::PATH_SEPARATOR) rescue [] + idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : [] if defaults idirs.concat(defaults.collect {|dir| dir + "/include"}) idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR) @@ -667,7 +712,7 @@ def dir_config(target, idefault=nil, ldefault=nil) end end - ldirs = ldir ? ldir.split(File::PATH_SEPARATOR) : [] + ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : [] if defaults ldirs.concat(defaults.collect {|dir| dir + "/lib"}) ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR) @@ -800,15 +845,18 @@ def create_makefile(target, srcprefix = nil) srcprefix ||= '$(srcdir)' Config::expand(srcdir = srcprefix.dup) - unless $objs then + if not $objs $objs = [] - for f in Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] - $objs.push(File.basename(f, ".*") << "." << $OBJEXT) - end - else - for i in $objs - i.sub!(/\.o\z/, ".#{$OBJEXT}") + srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] + for f in srcs + obj = File.basename(f, ".*") << ".o" + $objs.push(obj) unless $objs.index(obj) end + elsif !(srcs = $srcs) + srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')} + end + for i in $objs + i.sub!(/\.o\z/, ".#{$OBJEXT}") end $objs = $objs.join(" ") @@ -846,6 +894,7 @@ DISTCLEANFILES = #{$distcleanfiles.join(' ')} target_prefix = #{target_prefix} LOCAL_LIBS = #{$LOCAL_LIBS} LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS} +SRCS = #{srcs.collect(&File.method(:basename)).join(' ')} OBJS = #{$objs} TARGET = #{target} DLLIB = #{dllib} @@ -946,17 +995,23 @@ static: $(STATIC_LIB) mfile.printf "###\n" while line = dfile.gets() line.gsub!(/\.o\b/, ".#{$OBJEXT}") - line.gsub!(/(\s)([^\s\/]+\.[ch])/, '\1{$(srcdir)}\2') if $nmake + if $nmake + line.gsub!(%r"(\s)([^\s\/]+\.(?:#{SRC_EXT.join('|')})(?=\s|\z)", '\1{.;$(VPATH)}\2') + end line.gsub!(/\$\(hdrdir\)\/config.h/, $config_h) if $config_h mfile.print line end end end + + $makefile_created = true ensure mfile.close if mfile end def init_mkmf(config = CONFIG) + $makefile_created = false + $arg_config = [] $enable_shared = config['ENABLE_SHARED'] == 'yes' $defs = [] $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup @@ -985,9 +1040,25 @@ def init_mkmf(config = CONFIG) $cleanfiles = [] $distcleanfiles = [] + $arg_config.clear dir_config("opt") end +FailedMassage = <<MESSAGE +Could not create Makefile due to some reason, probably lack of +necessary libraries and/or headers. Check the mkmf.log file for more +details. You may need configuration options. + +Provided configuration options: +MESSAGE + +def mkmf_failed(path) + unless $makefile_created + opts = $arg_config.collect {|t, n| "\t#{t}#{"=#{n}" if n}\n"} + abort "*** #{path} failed ***\n" + FailedMassage + opts.join + end +end + init_mkmf $make = with_config("make-prog", ENV["MAKE"] || "make") @@ -1042,13 +1113,18 @@ LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"' RPATHFLAG = config_string('RPATHFLAG') || '' LIBARG = config_string('LIBARG') || '-l%s' +sep = File::ALT_SEPARATOR ? ":/=#{File::ALT_SEPARATOR}" : '' CLEANINGS = " clean: - @$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) + @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) distclean: clean - @$(RM) Makefile extconf.h conftest.* mkmf.log - @$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + @-$(RM) Makefile extconf.h conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep}) realclean: distclean " + +if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0) + END {mkmf_failed($0)} +end |