# module to create Makefile for extension modules # invoke like: ruby -r mkmf extconf.rb require 'rbconfig' require 'find' CONFIG = Config::MAKEFILE_CONFIG SRC_EXT = ["c", "cc", "m", "cxx", "cpp", "C"] $config_cache = CONFIG["compile_dir"]+"/ext/config.cache" $srcdir = CONFIG["srcdir"] $libdir = CONFIG["libdir"]+"/ruby/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"] $archdir = $libdir+"/"+CONFIG["arch"] $sitelibdir = CONFIG["sitedir"]+"/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"] $sitearchdir = $sitelibdir+"/"+CONFIG["arch"] if File.exist? $archdir + "/ruby.h" $hdrdir = $archdir elsif File.exist? $srcdir + "/ruby.h" $hdrdir = $srcdir else STDERR.print "can't find header files for ruby.\n" exit 1 end $topdir = $hdrdir $hdrdir.gsub!('/', '\\') if RUBY_PLATFORM =~ /mswin32/ CFLAGS = CONFIG["CFLAGS"] if RUBY_PLATFORM == "m68k-human" CFLAGS.gsub!(/-c..-stack=[0-9]+ */, '') elsif RUBY_PLATFORM =~ /-nextstep|-rhapsody/ CFLAGS.gsub!( /-arch\s\w*/, '' ) end if FileTest.readable? 'nul' $null = open('nul', 'w') elsif FileTest.readable? '/dev/null' $null = open('/dev/null', 'w') else $null = open('test.log', 'w') end LINK = "#{CONFIG['CC']} -o conftest -I#{$hdrdir} #{CFLAGS} -I#{CONFIG['includedir']} %s #{CONFIG['LDFLAGS']} %s conftest.c %s %s #{CONFIG['LIBS']}" CPP = "#{CONFIG['CPP']} -E -I#{$hdrdir} #{CFLAGS} -I#{CONFIG['includedir']} %s %s conftest.c" def rm_f(*files) targets = [] for file in files targets.concat Dir[file] end if not targets.empty? File::chmod 0777, *targets File::unlink *targets end end $orgerr = $stderr.dup $orgout = $stdout.dup def xsystem command if $DEBUG print command, "\n" return system(command) end $stderr.reopen($null) $stdout.reopen($null) r = system(command) $stderr.reopen($orgerr) $stdout.reopen($orgout) return r end def try_link0(src, opt="") cfile = open("conftest.c", "w") cfile.print src cfile.close xsystem(format(LINK, $CFLAGS, $LDFLAGS, opt, $LOCAL_LIBS)) end def try_link(src, opt="") begin try_link0(src, opt) ensure rm_f "conftest*" end end def try_cpp(src, opt="") cfile = open("conftest.c", "w") cfile.print src cfile.close begin xsystem(format(CPP, $CFLAGS, opt)) ensure rm_f "conftest*" end end def egrep_cpp(pat, src, opt="") cfile = open("conftest.c", "w") cfile.print src cfile.close begin xsystem(format(CPP+"|egrep #{pat}", $CFLAGS, opt)) ensure rm_f "conftest*" end end def try_run(src, opt="") begin if try_link0(src, opt) if xsystem("./conftest") true else false end else nil end ensure rm_f "conftest*" end end def install_rb(mfile, dest, srcdir = nil) libdir = "lib" libdir = srcdir + "/" + libdir if srcdir path = [] dir = [] Find.find(libdir) do |f| next unless /\.rb$/ =~ f f = f[libdir.length+1..-1] path.push f dir |= File.dirname(f) end for f in dir next if f == "." mfile.printf "\t@$(RUBY) -r ftools -e 'File::makedirs(*ARGV)' %s/%s\n", dest, f end for f in path mfile.printf "\t@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)' lib/%s %s/%s\n", f, dest, f end end def append_library(libs, lib) if /mswin32/ =~ RUBY_PLATFORM lib + ".lib " + libs else "-l" + lib + " " + libs end end def have_library(lib, func="main") printf "checking for %s() in -l%s... ", func, lib STDOUT.flush if func && func != "" libs = append_library($libs, lib) if /mswin32|mingw/ =~ RUBY_PLATFORM r = try_link(<<"SRC", libs) #include #include int main() { return 0; } int t() { #{func}(); return 0; } SRC unless r r = try_link(<<"SRC", libs) #include #include 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 print "no\n" return false end else libs = append_library($libs, lib) end $libs = libs print "yes\n" return true end def find_library(lib, func, *paths) printf "checking for %s() in -l%s... ", func, lib STDOUT.flush ldflags = $LDFLAGS libs = append_library($libs, lib) until try_link(<<"SRC", libs) int main() { return 0; } int t() { #{func}(); return 0; } SRC if paths.size == 0 $LDFLAGS = ldflags print "no\n" return false end $LDFLAGS = ldflags + " -L"+paths.shift end $libs = libs print "yes\n" return true end def have_func(func, header=nil) printf "checking for %s()... ", func STDOUT.flush libs = $libs src = if /mswin32|mingw/ =~ RUBY_PLATFORM r = <<"SRC" #include #include 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 + <<"SRC", libs) int main() { return 0; } int t() { void ((*p)()); p = (void ((*)()))#{func}; return 0; } SRC end unless r print "no\n" return false end $defs.push(format("-DHAVE_%s", func.upcase)) print "yes\n" return true end def have_header(header) printf "checking for %s... ", header STDOUT.flush unless try_cpp(<<"SRC") #include <#{header}> SRC print "no\n" return false end header.tr!("a-z\055./", "A-Z___") $defs.push(format("-DHAVE_%s", header)) print "yes\n" return true end def arg_config(config, default=nil) unless defined? $configure_args $configure_args = {} for arg in CONFIG["configure_args"].split + ARGV next unless /^--/ =~ arg if /=/ =~ arg $configure_args[$`] = $' else $configure_args[arg] = true end end end $configure_args.fetch(config, default) end def with_config(config, default=nil) unless /^--with-/ =~ config config = '--with-' + config end arg_config(config, default) end def enable_config(config, default=nil) if arg_config("--enable-"+config, default) true elsif arg_config("--disable-"+config, false) false else default end end def create_header() print "creating extconf.h\n" STDOUT.flush if $defs.length > 0 hfile = open("extconf.h", "w") for line in $defs line =~ /^-D(.*)/ hfile.printf "#define %s 1\n", $1 end hfile.close end end def dir_config(target, idefault=nil, ldefault=nil) if idefault && ldefault == nil default = idefault idefault = default + "/include" ldefault = default + "/lib" end dir = with_config("%s-dir"%target, default) if dir idir = " -I"+dir+"/include" ldir = " -L"+dir+"/lib" end unless idir dir = with_config("%s-include"%target, idefault) idir = " -I"+dir if dir end unless ldir dir = with_config("%s-lib"%target, ldefault) ldir = " -L"+dir if dir end $CFLAGS += idir if idir $LDFLAGS += ldir if ldir end def create_makefile(target) print "creating Makefile\n" rm_f "conftest*" STDOUT.flush if CONFIG["DLEXT"] == $OBJEXT libs = $libs.split for lib in libs lib.sub!(/-l(.*)/, '"lib\1.a"') end $defs.push(format("-DEXTLIB='%s'", libs.join(","))) end $DLDFLAGS = CONFIG["DLDFLAGS"] if $configure_args['--enable-shared'] or /cygwin|mingw/ == RUBY_PLATFORM $libs = CONFIG["LIBRUBYARG"] + " " + $libs $DLDFLAGS += " -L" + CONFIG["libdir"] end defflag = '' if RUBY_PLATFORM =~ /cygwin|mingw/ open(target + '.def', 'wb') do |f| f.print "EXPORTS\n", "Init_", target, "\n" end defflag = "--def=" + target + ".def" end unless $objs then $objs = [] for f in Dir["*.{#{SRC_EXT.join(%q{,})}}"] f = File.basename(f) f.sub!(/(#{SRC_EXT.join(%q{|})})$/, $OBJEXT) $objs.push f end else for i in $objs i.sub!(/\.o\z/, ".#{$OBJEXT}") end end $objs = $objs.join(" ") mfile = open("Makefile", "w") mfile.binmode if /mingw/ =~ RUBY_PLATFORM mfile.print <