From: Hongli Lai Date: 2008-03-07T06:21:30+09:00 Subject: [Patch] Improved documentation for mkmf This is a multi-part message in MIME format. --------------000105000206020905010701 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi. Documentation about mkmf is currently a bit lacking (almost nonexistant). The attached patch contains documentation improvements. It wraps the mkmf code into an 'MKMF' module, so that ri and RDoc can correctly display its documentation. Full compatibility is preserved. I've made no real changes to the code. Regards, Hongli Lai --------------000105000206020905010701 Content-Type: text/x-patch; name="mkmf-doc.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mkmf-doc.diff" diff --git a/lib/mkmf.rb b/lib/mkmf.rb index 6a3e9d1..44182aa 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -1,176 +1,8 @@ -# module to create Makefile for extension modules -# invoke like: ruby -r mkmf extconf.rb - require 'rbconfig' require 'fileutils' require 'shellwords' -CONFIG = RbConfig::MAKEFILE_CONFIG -ORIG_LIBPATH = ENV['LIB'] - -CXX_EXT = %w[cc cxx cpp] -if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os'] - CXX_EXT.concat(%w[C]) -end -SRC_EXT = %w[c m] << CXX_EXT -$static = $config_h = nil -$default_static = $static - -unless defined? $configure_args - $configure_args = {} - args = CONFIG["configure_args"] - if ENV["CONFIGURE_ARGS"] - args << " " << ENV["CONFIGURE_ARGS"] - end - for arg in Shellwords::shellwords(args) - arg, val = arg.split('=', 2) - next unless arg - arg.tr!('_', '-') - if arg.sub!(/^(?!--)/, '--') - val or next - arg.downcase! - end - next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg - $configure_args[arg] = val || true - end - for arg in ARGV - arg, val = arg.split('=', 2) - next unless arg - arg.tr!('_', '-') - if arg.sub!(/^(?!--)/, '--') - val or next - arg.downcase! - end - $configure_args[arg] = val || true - end -end - -$libdir = CONFIG["libdir"] -$rubylibdir = CONFIG["rubylibdir"] -$archdir = CONFIG["archdir"] -$sitedir = CONFIG["sitedir"] -$sitelibdir = CONFIG["sitelibdir"] -$sitearchdir = CONFIG["sitearchdir"] -$vendordir = CONFIG["vendordir"] -$vendorlibdir = CONFIG["vendorlibdir"] -$vendorarchdir = CONFIG["vendorarchdir"] - -$mswin = /mswin/ =~ RUBY_PLATFORM -$bccwin = /bccwin/ =~ RUBY_PLATFORM -$mingw = /mingw/ =~ RUBY_PLATFORM -$cygwin = /cygwin/ =~ RUBY_PLATFORM -$human = /human/ =~ RUBY_PLATFORM -$netbsd = /netbsd/ =~ RUBY_PLATFORM -$os2 = /os2/ =~ RUBY_PLATFORM -$beos = /beos/ =~ RUBY_PLATFORM -$solaris = /solaris/ =~ RUBY_PLATFORM -$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/) - -def config_string(key, config = CONFIG) - s = config[key] and !s.empty? and block_given? ? yield(s) : s -end - -def dir_re(dir) - Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?') -end - -def relative_from(path, base) - dir = File.join(path, "") - if File.expand_path(dir) == File.expand_path(dir, base) - path - else - File.join(base, path) - end -end - -INSTALL_DIRS = [ - [dir_re('commondir'), "$(RUBYCOMMONDIR)"], - [dir_re('sitedir'), "$(RUBYCOMMONDIR)"], - [dir_re('vendordir'), "$(RUBYCOMMONDIR)"], - [dir_re('rubylibdir'), "$(RUBYLIBDIR)"], - [dir_re('archdir'), "$(RUBYARCHDIR)"], - [dir_re('sitelibdir'), "$(RUBYLIBDIR)"], - [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"], - [dir_re('sitearchdir'), "$(RUBYARCHDIR)"], - [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"], - [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"], - [dir_re('sitehdrdir'), "$(SITEHDRDIR)"], - [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"], - [dir_re('bindir'), "$(BINDIR)"], -] - -def install_dirs(target_prefix = nil) - if $extout - dirs = [ - ['BINDIR', '$(extout)/bin'], - ['RUBYCOMMONDIR', '$(extout)/common'], - ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'], - ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'], - ['HDRDIR', '$(extout)/include/ruby$(target_prefix)'], - ['ARCHHDRDIR', '$(extout)/include/$(arch)/ruby$(target_prefix)'], - ['extout', "#$extout"], - ['extout_prefix', "#$extout_prefix"], - ] - elsif $extmk - dirs = [ - ['BINDIR', '$(bindir)'], - ['RUBYCOMMONDIR', '$(rubylibdir)'], - ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'], - ['RUBYARCHDIR', '$(archdir)$(target_prefix)'], - ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], - ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], - ] - elsif $configure_args.has_key?('--vendor') - dirs = [ - ['BINDIR', '$(bindir)'], - ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'], - ['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'], - ['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'], - ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], - ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], - ] - else - dirs = [ - ['BINDIR', '$(bindir)'], - ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'], - ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'], - ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'], - ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], - ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], - ] - end - dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")] - dirs -end - -def map_dir(dir, map = nil) - map ||= INSTALL_DIRS - map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)} -end - -topdir = File.dirname(libdir = File.dirname(__FILE__)) -extdir = File.expand_path("ext", topdir) -path = File.expand_path($0) -$extmk = path[0, topdir.size+1] == topdir+"/" && %r"\A(ext|enc|tool)\z" =~ File.dirname(path[topdir.size+1..-1]) -if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h") - $topdir = $hdrdir - $top_srcdir = $hdrdir - $arch_hdrdir = $hdrdir + "/$(arch)" -elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include") + "/ruby.h") and - File.exist?("#{CONFIG["EXTOUT"]}/include/#{CONFIG["arch"]}/ruby/config.h") - $topdir ||= RbConfig::CONFIG["topdir"] - $arch_hdrdir = "$(extout)/include/$(arch)" -else - abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h" -end - -OUTFLAG = CONFIG['OUTFLAG'] -COUTFLAG = CONFIG['COUTFLAG'] -CPPOUTFILE = CONFIG['CPPOUTFILE'] - -CONFTEST_C = "conftest.c".freeze - -class String +class String # :nodoc: all def quote /\s/ =~ self ? "\"#{self}\"" : "#{self}" end @@ -178,1590 +10,1788 @@ class String strip.upcase.tr_s("^A-Z0-9_", "_") end end -class Array + +class Array # :nodoc: all def quote map {|s| s.quote} end end -def rm_f(*files) - FileUtils.rm_f(Dir[*files]) -end - -def modified?(target, times) - (t = File.mtime(target)) rescue return nil - Array === times or times = [times] - t if times.all? {|n| n <= t} -end - -def merge_libs(*libs) - libs.inject([]) do |x, y| - xy = x & y - xn = yn = 0 - y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e} - y.each_with_index do |v, yi| - if xy.include?(v) - xi = [x.index(v), xn].max() - x[xi, 1] = y[yn..yi] - xn, yn = xi + (yi - yn + 1), yi + 1 +# This module allows one to create Makefiles for Ruby C extension modules. +# Suppose that you have multiple .c files in the current working directory. Then create +# a file 'extconf.rb', containing: +# +# require 'mkmf' +# create_makefile('hello') +# +# If you run this script, then it will generate a Makefile for an extension module called +# 'hello': +# +# ruby extconf.rb +# make +# +# The 'make' command generates "hello.so" on Unix, "hello.bundle" on OS X, and "hello.dll" +# Windows. +# +# Notes: +# - Methods in this module are automatically available in extconf.rb. There is no need for +# an 'include MKMF' call. +# - If there are multiple .c files, then all of them will be included for building. +module MKMF + CONFIG = RbConfig::MAKEFILE_CONFIG + ORIG_LIBPATH = ENV['LIB'] + + CXX_EXT = %w[cc cxx cpp] + if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os'] + CXX_EXT.concat(%w[C]) + end + SRC_EXT = %w[c m] << CXX_EXT + $static = $config_h = nil + $default_static = $static + + unless defined? $configure_args + $configure_args = {} + args = CONFIG["configure_args"] + if ENV["CONFIGURE_ARGS"] + args << " " << ENV["CONFIGURE_ARGS"] + end + for arg in Shellwords::shellwords(args) + arg, val = arg.split('=', 2) + next unless arg + arg.tr!('_', '-') + if arg.sub!(/^(?!--)/, '--') + val or next + arg.downcase! end + next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg + $configure_args[arg] = val || true + end + for arg in ARGV + arg, val = arg.split('=', 2) + next unless arg + arg.tr!('_', '-') + if arg.sub!(/^(?!--)/, '--') + val or next + arg.downcase! + end + $configure_args[arg] = val || true end - x.concat(y[yn..-1] || []) end -end -module Logging - @log = nil - @logfile = 'mkmf.log' - @orgerr = $stderr.dup - @orgout = $stdout.dup - @postpone = 0 - @quiet = $extmk - - def self::open - @log ||= File::open(@logfile, 'w') - @log.sync = true - $stderr.reopen(@log) - $stdout.reopen(@log) - yield - ensure - $stderr.reopen(@orgerr) - $stdout.reopen(@orgout) + $libdir = CONFIG["libdir"] + $rubylibdir = CONFIG["rubylibdir"] + $archdir = CONFIG["archdir"] + $sitedir = CONFIG["sitedir"] + $sitelibdir = CONFIG["sitelibdir"] + $sitearchdir = CONFIG["sitearchdir"] + $vendordir = CONFIG["vendordir"] + $vendorlibdir = CONFIG["vendorlibdir"] + $vendorarchdir = CONFIG["vendorarchdir"] + + $mswin = /mswin/ =~ RUBY_PLATFORM + $bccwin = /bccwin/ =~ RUBY_PLATFORM + $mingw = /mingw/ =~ RUBY_PLATFORM + $cygwin = /cygwin/ =~ RUBY_PLATFORM + $human = /human/ =~ RUBY_PLATFORM + $netbsd = /netbsd/ =~ RUBY_PLATFORM + $os2 = /os2/ =~ RUBY_PLATFORM + $beos = /beos/ =~ RUBY_PLATFORM + $solaris = /solaris/ =~ RUBY_PLATFORM + $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/) + + def self.config_string(key, config = CONFIG) + s = config[key] and !s.empty? and block_given? ? yield(s) : s end - def self::message(*s) - @log ||= File::open(@logfile, 'w') - @log.sync = true - @log.printf(*s) + def self.dir_re(dir) + Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?') end - def self::logfile file - @logfile = file - if @log and not @log.closed? - @log.flush - @log.close - @log = nil + def self.relative_from(path, base) + dir = File.join(path, "") + if File.expand_path(dir) == File.expand_path(dir, base) + path + else + File.join(base, path) end end - - def self::postpone - tmplog = "mkmftmp#{@postpone += 1}.log" - open do - log, *save = @log, @logfile, @orgout, @orgerr - @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log - begin - log.print(open {yield}) - @log.close - File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} - ensure - @log, @logfile, @orgout, @orgerr = log, *save - @postpone -= 1 - rm_f tmplog - end + + INSTALL_DIRS = [ + [dir_re('commondir'), "$(RUBYCOMMONDIR)"], + [dir_re('sitedir'), "$(RUBYCOMMONDIR)"], + [dir_re('vendordir'), "$(RUBYCOMMONDIR)"], + [dir_re('rubylibdir'), "$(RUBYLIBDIR)"], + [dir_re('archdir'), "$(RUBYARCHDIR)"], + [dir_re('sitelibdir'), "$(RUBYLIBDIR)"], + [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"], + [dir_re('sitearchdir'), "$(RUBYARCHDIR)"], + [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"], + [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"], + [dir_re('sitehdrdir'), "$(SITEHDRDIR)"], + [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"], + [dir_re('bindir'), "$(BINDIR)"], + ] + + def self.install_dirs(target_prefix = nil) + if $extout + dirs = [ + ['BINDIR', '$(extout)/bin'], + ['RUBYCOMMONDIR', '$(extout)/common'], + ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'], + ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'], + ['HDRDIR', '$(extout)/include/ruby$(target_prefix)'], + ['ARCHHDRDIR', '$(extout)/include/$(arch)/ruby$(target_prefix)'], + ['extout', "#$extout"], + ['extout_prefix', "#$extout_prefix"], + ] + elsif $extmk + dirs = [ + ['BINDIR', '$(bindir)'], + ['RUBYCOMMONDIR', '$(rubylibdir)'], + ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'], + ['RUBYARCHDIR', '$(archdir)$(target_prefix)'], + ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], + ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], + ] + elsif $configure_args.has_key?('--vendor') + dirs = [ + ['BINDIR', '$(bindir)'], + ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'], + ['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'], + ['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'], + ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], + ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], + ] + else + dirs = [ + ['BINDIR', '$(bindir)'], + ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'], + ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'], + ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'], + ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], + ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], + ] end + dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")] + dirs + end + + def self.map_dir(dir, map = nil) + map ||= INSTALL_DIRS + map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)} + end + + topdir = File.dirname(libdir = File.dirname(__FILE__)) + extdir = File.expand_path("ext", topdir) + path = File.expand_path($0) + $extmk = path[0, topdir.size+1] == topdir+"/" && %r"\A(ext|enc|tool)\z" =~ File.dirname(path[topdir.size+1..-1]) + if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h") + $topdir = $hdrdir + $top_srcdir = $hdrdir + $arch_hdrdir = $hdrdir + "/$(arch)" + elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include") + "/ruby.h") and + File.exist?("#{CONFIG["EXTOUT"]}/include/#{CONFIG["arch"]}/ruby/config.h") + $topdir ||= RbConfig::CONFIG["topdir"] + $arch_hdrdir = "$(extout)/include/$(arch)" + else + abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h" end - class << self - attr_accessor :quiet - end -end + OUTFLAG = CONFIG['OUTFLAG'] + COUTFLAG = CONFIG['COUTFLAG'] + CPPOUTFILE = CONFIG['CPPOUTFILE'] + + CONFTEST_C = "conftest.c".freeze -def xsystem command - varpat = /\$\((\w+)\)|\$\{(\w+)\}/ - if varpat =~ command - vars = Hash.new {|h, k| h[k] = ''; ENV[k]} - command = command.dup - nil while command.gsub!(varpat) {vars[$1||$2]} + def self.rm_f(*files) + FileUtils.rm_f(Dir[*files]) end - Logging::open do - puts command.quote - system(command) + + def self.modified?(target, times) + (t = File.mtime(target)) rescue return nil + Array === times or times = [times] + t if times.all? {|n| n <= t} end -end -def xpopen command, *mode, &block - Logging::open do - case mode[0] - when nil, /^r/ - puts "#{command} |" - else - puts "| #{command}" + def self.merge_libs(*libs) + libs.inject([]) do |x, y| + xy = x & y + xn = yn = 0 + y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e} + y.each_with_index do |v, yi| + if xy.include?(v) + xi = [x.index(v), xn].max() + x[xi, 1] = y[yn..yi] + xn, yn = xi + (yi - yn + 1), yi + 1 + end + end + x.concat(y[yn..-1] || []) end - IO.popen(command, *mode, &block) end -end -def log_src(src) - src = src.split(/^/) - fmt = "%#{src.size.to_s.size}d: %s" - Logging::message <<"EOM" -checked program was: -/* begin */ -EOM - src.each_with_index {|line, no| Logging::message fmt, no+1, line} - Logging::message <<"EOM" -/* end */ + module Logging # :nodoc: all + @log = nil + @logfile = 'mkmf.log' + @orgerr = $stderr.dup + @orgout = $stdout.dup + @postpone = 0 + @quiet = $extmk + + def self::open + @log ||= File::open(@logfile, 'w') + @log.sync = true + $stderr.reopen(@log) + $stdout.reopen(@log) + yield + ensure + $stderr.reopen(@orgerr) + $stdout.reopen(@orgout) + end -EOM -end + def self::message(*s) + @log ||= File::open(@logfile, 'w') + @log.sync = true + @log.printf(*s) + end -def create_tmpsrc(src) - src = yield(src) if block_given? - src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n") - count = 0 - begin - open(CONFTEST_C, "wb") do |cfile| - cfile.print src + def self::logfile file + @logfile = file + if @log and not @log.closed? + @log.flush + @log.close + @log = nil + end end - rescue Errno::EACCES - if (count += 1) < 5 - sleep 0.2 - retry + + def self::postpone + tmplog = "mkmftmp#{@postpone += 1}.log" + open do + log, *save = @log, @logfile, @orgout, @orgerr + @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log + begin + log.print(open {yield}) + @log.close + File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} + ensure + @log, @logfile, @orgout, @orgerr = log, *save + @postpone -= 1 + rm_f tmplog + end + end + end + + class << self + attr_accessor :quiet end end - src -end -def try_do(src, command, &b) - src = create_tmpsrc(src, &b) - xsystem(command) -ensure - log_src(src) -end + def self.xsystem command + varpat = /\$\((\w+)\)|\$\{(\w+)\}/ + if varpat =~ command + vars = Hash.new {|h, k| h[k] = ''; ENV[k]} + command = command.dup + nil while command.gsub!(varpat) {vars[$1||$2]} + end + Logging::open do + puts command.quote + system(command) + end + end -def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH) - conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, - 'src' => CONFTEST_C, - 'arch_hdrdir' => "#$arch_hdrdir", - 'top_srcdir' => $top_srcdir.quote, - 'INCFLAGS' => "#$INCFLAGS", - 'CPPFLAGS' => "#$CPPFLAGS", - 'CFLAGS' => "#$CFLAGS", - 'ARCH_FLAG' => "#$ARCH_FLAG", - 'LDFLAGS' => "#$LDFLAGS #{ldflags}", - 'LIBPATH' => libpathflag(libpath), - 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs", - 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS") - RbConfig::expand(TRY_LINK.dup, conf) -end + def self.xpopen command, *mode, &block + Logging::open do + case mode[0] + when nil, /^r/ + puts "#{command} |" + else + puts "| #{command}" + end + IO.popen(command, *mode, &block) + end + end -def cc_command(opt="") - conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote, - 'arch_hdrdir' => "#$arch_hdrdir", - 'top_srcdir' => $top_srcdir.quote) - RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", - conf) -end + def self.log_src(src) + src = src.split(/^/) + fmt = "%#{src.size.to_s.size}d: %s" + Logging::message <<"EOM" + checked program was: + /* begin */ +EOM + src.each_with_index {|line, no| Logging::message fmt, no+1, line} + Logging::message <<"EOM" + /* end */ -def cpp_command(outfile, opt="") - conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote, - 'arch_hdrdir' => "#$arch_hdrdir", - 'top_srcdir' => $top_srcdir.quote) - RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}", - conf) -end +EOM + end -def libpathflag(libpath=$DEFLIBPATH|$LIBPATH) - libpath.map{|x| - case x - when "$(topdir)", /\A\./ - LIBPATHFLAG - else - LIBPATHFLAG+RPATHFLAG - end % x.quote - }.join -end + def self.create_tmpsrc(src) + src = yield(src) if block_given? + src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n") + count = 0 + begin + open(CONFTEST_C, "wb") do |cfile| + cfile.print src + end + rescue Errno::EACCES + if (count += 1) < 5 + sleep 0.2 + retry + end + end + src + end -def try_link0(src, opt="", &b) - try_do(src, link_command("", opt), &b) -end + def self.try_do(src, command, &b) + src = create_tmpsrc(src, &b) + xsystem(command) + ensure + log_src(src) + end + + def self.link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH) + conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, + 'src' => CONFTEST_C, + 'arch_hdrdir' => "#$arch_hdrdir", + 'top_srcdir' => $top_srcdir.quote, + 'INCFLAGS' => "#$INCFLAGS", + 'CPPFLAGS' => "#$CPPFLAGS", + 'CFLAGS' => "#$CFLAGS", + 'ARCH_FLAG' => "#$ARCH_FLAG", + 'LDFLAGS' => "#$LDFLAGS #{ldflags}", + 'LIBPATH' => libpathflag(libpath), + 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs", + 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS") + RbConfig::expand(TRY_LINK.dup, conf) + end + + def self.cc_command(opt="") + conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote, + 'arch_hdrdir' => "#$arch_hdrdir", + 'top_srcdir' => $top_srcdir.quote) + RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", + conf) + end + + def self.cpp_command(outfile, opt="") + conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote, + 'arch_hdrdir' => "#$arch_hdrdir", + 'top_srcdir' => $top_srcdir.quote) + RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}", + conf) + end + + def self.libpathflag(libpath=$DEFLIBPATH|$LIBPATH) + libpath.map{|x| + case x + when "$(topdir)", /\A\./ + LIBPATHFLAG + else + LIBPATHFLAG+RPATHFLAG + end % x.quote + }.join + end -def try_link(src, opt="", &b) - try_link0(src, opt, &b) -ensure - rm_f "conftest*", "c0x32*" -end + def self.try_link0(src, opt="", &b) + try_do(src, link_command("", opt), &b) + end -def try_compile(src, opt="", &b) - try_do(src, cc_command(opt), &b) -ensure - rm_f "conftest*" -end + def self.try_link(src, opt="", &b) + try_link0(src, opt, &b) + ensure + rm_f "conftest*", "c0x32*" + end -def try_cpp(src, opt="", &b) - try_do(src, cpp_command(CPPOUTFILE, opt), &b) -ensure - rm_f "conftest*" -end + def self.try_compile(src, opt="", &b) + try_do(src, cc_command(opt), &b) + ensure + rm_f "conftest*" + end -def cpp_include(header) - if header - header = [header] unless header.kind_of? Array - header.map {|h| "#include <#{h}>\n"}.join - else - "" + def self.try_cpp(src, opt="", &b) + try_do(src, cpp_command(CPPOUTFILE, opt), &b) + ensure + rm_f "conftest*" end -end -def with_cppflags(flags) - cppflags = $CPPFLAGS - $CPPFLAGS = flags - ret = yield -ensure - $CPPFLAGS = cppflags unless ret -end + def self.cpp_include(header) + if header + header = [header] unless header.kind_of? Array + header.map {|h| "#include <#{h}>\n"}.join + else + "" + end + end -def with_cflags(flags) - cflags = $CFLAGS - $CFLAGS = flags - ret = yield -ensure - $CFLAGS = cflags unless ret -end + def self.with_cppflags(flags) + cppflags = $CPPFLAGS + $CPPFLAGS = flags + ret = yield + ensure + $CPPFLAGS = cppflags unless ret + end -def with_ldflags(flags) - ldflags = $LDFLAGS - $LDFLAGS = flags - ret = yield -ensure - $LDFLAGS = ldflags unless ret -end + def self.with_cflags(flags) + cflags = $CFLAGS + $CFLAGS = flags + ret = yield + ensure + $CFLAGS = cflags unless ret + end -def try_static_assert(expr, headers = nil, opt = "", &b) - headers = cpp_include(headers) - try_compile(< 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 - lower = 0 - until try_static_assert("#{const} <= #{upper}", headers, opt) - lower = upper - upper <<= 1 - end - return nil unless lower - while upper > lower + 1 - mid = (upper + lower) / 2 - if try_static_assert("#{const} > #{mid}", headers, opt) - lower = mid + def self.try_constant(const, headers = nil, opt = "", &b) + includes = cpp_include(headers) + if CROSS_COMPILING + 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 - upper = mid + # not a constant + return nil end - end - upper = -upper if neg - return upper - else - src = %{#{COMMON_HEADERS} -#{includes} -#include -/*top*/ -int conftest_const = (int)(#{const}); -int main() {printf("%d\\n", conftest_const); return 0;} -} - if try_link0(src, opt, &b) - xpopen("./conftest") do |f| - return Integer(f.gets) + upper = 1 + lower = 0 + until try_static_assert("#{const} <= #{upper}", headers, opt) + lower = upper + upper <<= 1 + end + return nil unless lower + while upper > lower + 1 + mid = (upper + lower) / 2 + if try_static_assert("#{const} > #{mid}", headers, opt) + lower = mid + else + upper = mid + end + end + upper = -upper if neg + return upper + else + src = %{#{COMMON_HEADERS} + #{includes} + #include + /*top*/ + int conftest_const = (int)(#{const}); + int main() {printf("%d\\n", conftest_const); return 0;} + } + if try_link0(src, opt, &b) + xpopen("./conftest") do |f| + return Integer(f.gets) + end end end + nil end - nil -end -def try_func(func, libs, headers = nil, &b) - headers = cpp_include(headers) - try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b) -#{COMMON_HEADERS} -#{headers} -/*top*/ -int main() { return 0; } -int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; } + def self.try_func(func, libs, headers = nil, &b) + headers = cpp_include(headers) + try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b) + #{COMMON_HEADERS} + #{headers} + /*top*/ + int main() { return 0; } + int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; } SRC -#{headers} -/*top*/ -int main() { return 0; } -int t() { #{func}(); return 0; } + #{headers} + /*top*/ + int main() { return 0; } + int t() { #{func}(); return 0; } SRC -end + 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() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; } + def self.try_var(var, headers = nil, &b) + headers = cpp_include(headers) + try_compile(<<"SRC", &b) + #{COMMON_HEADERS} + #{headers} + /*top*/ + int main() { return 0; } + int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; } SRC -end + end -def egrep_cpp(pat, src, opt = "", &b) - src = create_tmpsrc(src, &b) - xpopen(cpp_command('', opt)) do |f| - if Regexp === pat - puts(" ruby -ne 'print if #{pat.inspect}'") - f.grep(pat) {|l| - puts "#{f.lineno}: #{l}" - return true - } - false - else - puts(" egrep '#{pat}'") - begin - stdin = $stdin.dup - $stdin.reopen(f) - system("egrep", pat) - ensure - $stdin.reopen(stdin) + def self.egrep_cpp(pat, src, opt = "", &b) + src = create_tmpsrc(src, &b) + xpopen(cpp_command('', opt)) do |f| + if Regexp === pat + puts(" ruby -ne 'print if #{pat.inspect}'") + f.grep(pat) {|l| + puts "#{f.lineno}: #{l}" + return true + } + false + else + puts(" egrep '#{pat}'") + begin + stdin = $stdin.dup + $stdin.reopen(f) + system("egrep", pat) + ensure + $stdin.reopen(stdin) + end end end - end -ensure - rm_f "conftest*" - log_src(src) -end - -def macro_defined?(macro, src, opt = "", &b) - src = src.sub(/[^\n]\z/, "\\&\n") - try_compile(src + <<"SRC", opt, &b) -/*top*/ -#ifndef #{macro} -# error ->>>>>> #{macro} undefined <<<<<< -#endif + ensure + rm_f "conftest*" + log_src(src) + end + + def self.macro_defined?(macro, src, opt = "", &b) + src = src.sub(/[^\n]\z/, "\\&\n") + try_compile(src + <<"SRC", opt, &b) + /*top*/ + #ifndef #{macro} + # error + >>>>>> #{macro} undefined <<<<<< + #endif SRC -end - -def try_run(src, opt = "", &b) - if try_link0(src, opt, &b) - xsystem("./conftest") - else - nil end -ensure - rm_f "conftest*" -end -def install_files(mfile, ifiles, map = nil, srcprefix = nil) - ifiles or return - ifiles.empty? and return - srcprefix ||= '$(srcdir)' - RbConfig::expand(srcdir = srcprefix.dup) - dirs = [] - path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]} - ifiles.each do |files, dir, prefix| - dir = map_dir(dir, map) - prefix &&= %r|\A#{Regexp.quote(prefix)}/?| - if /\A\.\// =~ files - # install files which are in current working directory. - files = files[2..-1] - len = nil + def self.try_run(src, opt = "", &b) + if try_link0(src, opt, &b) + xsystem("./conftest") else - # install files which are under the $(srcdir). - files = File.join(srcdir, files) - len = srcdir.size - end - f = nil - Dir.glob(files) do |fx| - f = fx - f[0..len] = "" if len - case File.basename(f) - when *$NONINSTALLFILES - next - end - d = File.dirname(f) - d.sub!(prefix, "") if prefix - d = (d.empty? || d == ".") ? dir : File.join(dir, d) - f = File.join(srcprefix, f) if len - path[d] << f + nil end - unless len or f - d = File.dirname(files) - d.sub!(prefix, "") if prefix - d = (d.empty? || d == ".") ? dir : File.join(dir, d) - path[d] << files + ensure + rm_f "conftest*" + end + + def self.install_files(mfile, ifiles, map = nil, srcprefix = nil) + ifiles or return + ifiles.empty? and return + srcprefix ||= '$(srcdir)' + RbConfig::expand(srcdir = srcprefix.dup) + dirs = [] + path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]} + ifiles.each do |files, dir, prefix| + dir = map_dir(dir, map) + prefix &&= %r|\A#{Regexp.quote(prefix)}/?| + if /\A\.\// =~ files + # install files which are in current working directory. + files = files[2..-1] + len = nil + else + # install files which are under the $(srcdir). + files = File.join(srcdir, files) + len = srcdir.size + end + f = nil + Dir.glob(files) do |fx| + f = fx + f[0..len] = "" if len + case File.basename(f) + when *$NONINSTALLFILES + next + end + d = File.dirname(f) + d.sub!(prefix, "") if prefix + d = (d.empty? || d == ".") ? dir : File.join(dir, d) + f = File.join(srcprefix, f) if len + path[d] << f + end + unless len or f + d = File.dirname(files) + d.sub!(prefix, "") if prefix + d = (d.empty? || d == ".") ? dir : File.join(dir, d) + path[d] << files + end end + dirs end - dirs -end -def install_rb(mfile, dest, srcdir = nil) - install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir) -end + def self.install_rb(mfile, dest, srcdir = nil) + install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir) + end -def append_library(libs, lib) - format(LIBARG, lib) + " " + libs -end + def self.append_library(libs, lib) + format(LIBARG, lib) + " " + libs + end -def message(*s) - unless Logging.quiet and not $VERBOSE - printf(*s) - $stdout.flush + def self.message(*s) + unless Logging.quiet and not $VERBOSE + printf(*s) + $stdout.flush + end end -end -def checking_for(m, fmt = nil) - f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim #' - m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... " - message "%s", m - a = r = nil - Logging::postpone do - r = yield - a = (fmt ? fmt % r : r ? "yes" : "no") << "\n" - "#{f}#{m}-------------------- #{a}\n" - end - message(a) - Logging::message "--------------------\n\n" - r -end + def self.checking_for(m, fmt = nil) + f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim #' + m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... " + message "%s", m + a = r = nil + Logging::postpone do + r = yield + a = (fmt ? fmt % r : r ? "yes" : "no") << "\n" + "#{f}#{m}-------------------- #{a}\n" + end + message(a) + Logging::message "--------------------\n\n" + r + end -def checking_message(target, place = nil, opt = nil) - [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)| - if noun - [[:to_str], [:join, ","], [:to_s]].each do |meth, *args| - if noun.respond_to?(meth) - break noun = noun.send(meth, *args) + def self.checking_message(target, place = nil, opt = nil) + [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)| + if noun + [[:to_str], [:join, ","], [:to_s]].each do |meth, *args| + if noun.respond_to?(meth) + break noun = noun.send(meth, *args) + end end + msg << " #{pre} #{noun}" unless noun.empty? end - msg << " #{pre} #{noun}" unless noun.empty? + msg end - msg end -end -# Returns whether or not +macro+ is defined either in the common header -# files or within any +headers+ you provide. -# -# Any options you pass to +opt+ are passed along to the compiler. -# -def have_macro(macro, headers = nil, opt = "", &b) - checking_for checking_message(macro, headers, opt) do - macro_defined?(macro, cpp_include(headers), opt, &b) + # Returns whether or not +macro+ is defined either in the common header + # files or within any +headers+ you provide. + # + # Any options you pass to +opt+ are passed along to the compiler. + # + def self.have_macro(macro, headers = nil, opt = "", &b) + checking_for checking_message(macro, headers, opt) do + macro_defined?(macro, cpp_include(headers), opt, &b) + end end -end -# Returns whether or not the given entry point +func+ can be found within -# +lib+. If +func+ is nil, the 'main()' entry point is used by default. -# If found, it adds the library to list of libraries to be used when linking -# your extension. -# -# If +headers+ are provided, it will include those header files as the -# header files it looks in when searching for +func+. -# -# Real name of the library to be linked can be altered by -# '--with-FOOlib' configuration option. -# -def have_library(lib, func = nil, headers = nil, &b) - func = "main" if !func or func.empty? - lib = with_config(lib+'lib', lib) - checking_for checking_message("#{func}()", LIBARG%lib) do - if COMMON_LIBS.include?(lib) - true - else - libs = append_library($libs, lib) - if try_func(func, libs, headers, &b) - $libs = libs + # Returns whether or not the given entry point +func+ can be found within + # +lib+. If +func+ is nil, the 'main()' entry point is used by default. + # If found, it adds the library to list of libraries to be used when linking + # your extension. + # + # If +headers+ are provided, it will include those header files as the + # header files it looks in when searching for +func+. + # + # Real name of the library to be linked can be altered by + # '--with-FOOlib' configuration option. + # + def self.have_library(lib, func = nil, headers = nil, &b) + func = "main" if !func or func.empty? + lib = with_config(lib+'lib', lib) + checking_for checking_message("#{func}()", LIBARG%lib) do + if COMMON_LIBS.include?(lib) true else - false + libs = append_library($libs, lib) + if try_func(func, libs, headers, &b) + $libs = libs + true + else + false + end end end end -end -# Returns whether or not the entry point +func+ can be found within the library -# +lib+ in one of the +paths+ specified, where +paths+ is an array of strings. -# If +func+ is nil , then the main() function is used as the entry point. -# -# If +lib+ is found, then the path it was found on is added to the list of -# library paths searched and linked against. -# -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) - begin - until r = try_func(func, libs, &b) or paths.empty? - $LIBPATH = libpath | [paths.shift] - end - if r - $libs = libs - libpath = nil + # Returns whether or not the entry point +func+ can be found within the library + # +lib+ in one of the +paths+ specified, where +paths+ is an array of strings. + # If +func+ is nil , then the main() function is used as the entry point. + # + # If +lib+ is found, then the path it was found on is added to the list of + # library paths searched and linked against. + # + def self.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) + begin + until r = try_func(func, libs, &b) or paths.empty? + $LIBPATH = libpath | [paths.shift] + end + if r + $libs = libs + libpath = nil + end + ensure + $LIBPATH = libpath if libpath end - ensure - $LIBPATH = libpath if libpath + r end - r end -end -# Returns whether or not the function +func+ can be found in the common -# header files, or within any +headers+ that you provide. If found, a -# macro is passed as a preprocessor constant to the compiler using the -# function name, in uppercase, prepended with 'HAVE_'. -# -# For example, if have_func('foo') returned true, then the HAVE_FOO -# preprocessor macro would be passed to the compiler. -# -def have_func(func, headers = nil, &b) - checking_for checking_message("#{func}()", headers) do - if try_func(func, $libs, headers, &b) - $defs.push(format("-DHAVE_%s", func.tr_cpp)) - true - else - false + # Returns whether or not the function +func+ can be found in the common + # header files, or within any +headers+ that you provide. If found, a + # macro is passed as a preprocessor constant to the compiler using the + # function name, in uppercase, prepended with 'HAVE_'. + # + # For example, if have_func('foo') returned true, then the HAVE_FOO + # preprocessor macro would be passed to the compiler. + # + def self.have_func(func, headers = nil, &b) + checking_for checking_message("#{func}()", headers) do + if try_func(func, $libs, headers, &b) + $defs.push(format("-DHAVE_%s", func.tr_cpp)) + true + else + false + end end end -end -# Returns whether or not the variable +var+ can be found in the common -# header files, or within any +headers+ that you provide. If found, a -# macro is passed as a preprocessor constant to the compiler using the -# variable name, in uppercase, prepended with 'HAVE_'. -# -# For example, if have_var('foo') returned true, then the HAVE_FOO -# preprocessor macro would be passed to the compiler. -# -def have_var(var, headers = nil, &b) - checking_for checking_message(var, headers) do - if try_var(var, headers, &b) - $defs.push(format("-DHAVE_%s", var.tr_cpp)) - true - else - false + # Returns whether or not the variable +var+ can be found in the common + # header files, or within any +headers+ that you provide. If found, a + # macro is passed as a preprocessor constant to the compiler using the + # variable name, in uppercase, prepended with 'HAVE_'. + # + # For example, if have_var('foo') returned true, then the HAVE_FOO + # preprocessor macro would be passed to the compiler. + # + def self.have_var(var, headers = nil, &b) + checking_for checking_message(var, headers) do + if try_var(var, headers, &b) + $defs.push(format("-DHAVE_%s", var.tr_cpp)) + true + else + false + end end end -end -# Returns whether or not the given +header+ file can be found on your system. -# If found, a macro is passed as a preprocessor constant to the compiler using -# the header file name, in uppercase, prepended with 'HAVE_'. -# -# For example, if have_header('foo.h') returned true, then the HAVE_FOO_H -# preprocessor macro would be passed to the compiler. -# -def have_header(header, &b) - checking_for header do - if try_cpp(cpp_include(header), &b) - $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___"))) - true - else - false + # Returns whether or not the given +header+ file can be found on your system. + # If found, a macro is passed as a preprocessor constant to the compiler using + # the header file name, in uppercase, prepended with 'HAVE_'. + # + # For example, if have_header('foo.h') returned true, then the HAVE_FOO_H + # preprocessor macro would be passed to the compiler. + # + def self.have_header(header, &b) + checking_for header do + if try_cpp(cpp_include(header), &b) + $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___"))) + true + else + false + end 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. -# -# If the header is found then the path it was found on is added to the list -# of included directories that are sent to the compiler (via the -I switch). -# -def find_header(header, *paths) - message = checking_message(header, paths) - header = cpp_include(header) - checking_for message do - if try_cpp(header) - true - else - found = false - paths.each do |dir| - opt = "-I#{dir}".quote - if try_cpp(header, opt) - $INCFLAGS << " " << opt - found = true - break + # 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. + # + # If the header is found then the path it was found on is added to the list + # of included directories that are sent to the compiler (via the -I switch). + # + def self.find_header(header, *paths) + message = checking_message(header, paths) + header = cpp_include(header) + checking_for message do + if try_cpp(header) + true + else + found = false + paths.each do |dir| + opt = "-I#{dir}".quote + if try_cpp(header, opt) + $INCFLAGS << " " << opt + found = true + break + end end + found 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 -# (in addition to the common header files). -# -# If found, a macro is passed as a preprocessor constant to the compiler using -# the type name and the member name, in uppercase, prepended with 'HAVE_'. -# -# For example, if have_struct_member('struct foo', 'bar') returned true, then the -# HAVE_STRUCT_FOO_BAR preprocessor macro would be passed to the compiler. -# -# HAVE_ST_BAR is also defined for backward compatibility. -# -def have_struct_member(type, member, headers = nil, &b) - checking_for checking_message("#{type}.#{member}", headers) do - if try_compile(<<"SRC", &b) -#{COMMON_HEADERS} -#{cpp_include(headers)} -/*top*/ -int main() { return 0; } -int s = (char *)&((#{type}*)0)->#{member} - (char *)0; + # 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 + # (in addition to the common header files). + # + # If found, a macro is passed as a preprocessor constant to the compiler using + # the type name and the member name, in uppercase, prepended with 'HAVE_'. + # + # For example, if have_struct_member('struct foo', 'bar') returned true, then the + # HAVE_STRUCT_FOO_BAR preprocessor macro would be passed to the compiler. + # + # HAVE_ST_BAR is also defined for backward compatibility. + # + def self.have_struct_member(type, member, headers = nil, &b) + checking_for checking_message("#{type}.#{member}", headers) do + if try_compile(<<"SRC", &b) + #{COMMON_HEADERS} + #{cpp_include(headers)} + /*top*/ + int main() { return 0; } + int s = (char *)&((#{type}*)0)->#{member} - (char *)0; SRC - $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp)) - $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility - true - else - false + $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp)) + $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility + true + else + false + end end end -end -def try_type(type, headers = nil, opt = "", &b) - if try_compile(<<"SRC", opt, &b) -#{COMMON_HEADERS} -#{cpp_include(headers)} -/*top*/ -typedef #{type} conftest_type; -int conftestval[sizeof(conftest_type)?1:-1]; + def self.try_type(type, headers = nil, opt = "", &b) + if try_compile(<<"SRC", opt, &b) + #{COMMON_HEADERS} + #{cpp_include(headers)} + /*top*/ + typedef #{type} conftest_type; + int conftestval[sizeof(conftest_type)?1:-1]; SRC - $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp)) - true - else - false + $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp)) + true + else + false + end end -end -# Returns whether or not the static type +type+ is defined. You may -# optionally pass additional +headers+ to check against in addition to the -# common header files. -# -# You may also pass additional flags to +opt+ which are then passed along to -# the compiler. -# -# If found, a macro is passed as a preprocessor constant to the compiler using -# the type name, in uppercase, prepended with 'HAVE_TYPE_'. -# -# For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO -# preprocessor macro would be passed to the compiler. -# -def have_type(type, headers = nil, opt = "", &b) - checking_for checking_message(type, headers, opt) do - try_type(type, headers, opt, &b) + # Returns whether or not the static type +type+ is defined. You may + # optionally pass additional +headers+ to check against in addition to the + # common header files. + # + # You may also pass additional flags to +opt+ which are then passed along to + # the compiler. + # + # If found, a macro is passed as a preprocessor constant to the compiler using + # the type name, in uppercase, prepended with 'HAVE_TYPE_'. + # + # For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO + # preprocessor macro would be passed to the compiler. + # + def self.have_type(type, headers = nil, opt = "", &b) + checking_for checking_message(type, headers, opt) do + try_type(type, headers, opt, &b) + end end -end -# Returns where the static type +type+ is defined. -# -# You may also pass additional flags to +opt+ which are then passed along to -# the compiler. -# -# See also +have_type+. -# -def find_type(type, opt, *headers, &b) - opt ||= "" - fmt = "not found" - def fmt.%(x) - x ? x.respond_to?(:join) ? x.join(",") : x : self - end - checking_for checking_message(type, nil, opt), fmt do - headers.find do |h| - try_type(type, h, opt, &b) + # Returns where the static type +type+ is defined. + # + # You may also pass additional flags to +opt+ which are then passed along to + # the compiler. + # + # See also +have_type+. + # + def self.find_type(type, opt, *headers, &b) + opt ||= "" + fmt = "not found" + def fmt.%(x) + x ? x.respond_to?(:join) ? x.join(",") : x : self + end + checking_for checking_message(type, nil, opt), fmt do + headers.find do |h| + try_type(type, h, opt, &b) + end end end -end -def try_const(const, headers = nil, opt = "", &b) - const, type = *const - if try_compile(<<"SRC", opt, &b) -#{COMMON_HEADERS} -#{cpp_include(headers)} -/*top*/ -typedef #{type || 'int'} conftest_type; -conftest_type conftestval = #{type ? '' : '(int)'}#{const}; + def self.try_const(const, headers = nil, opt = "", &b) + const, type = *const + if try_compile(<<"SRC", opt, &b) + #{COMMON_HEADERS} + #{cpp_include(headers)} + /*top*/ + typedef #{type || 'int'} conftest_type; + conftest_type conftestval = #{type ? '' : '(int)'}#{const}; SRC - $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp)) - true - else - false + $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp)) + true + else + false + end end -end -# Returns whether or not the constant +const+ is defined. You may -# optionally pass the +type+ of +const+ as [const, type], -# like as: -# -# have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h") -# -# You may also pass additional +headers+ to check against in addition -# to the common header files, and additional flags to +opt+ which are -# then passed along to the compiler. -# -# If found, a macro is passed as a preprocessor constant to the compiler using -# the type name, in uppercase, prepended with 'HAVE_CONST_'. -# -# For example, if have_const('foo') returned true, then the HAVE_CONST_FOO -# preprocessor macro would be passed to the compiler. -# -def have_const(const, headers = nil, opt = "", &b) - checking_for checking_message([*const].compact.join(' '), headers, opt) do - try_const(const, headers, opt, &b) + # Returns whether or not the constant +const+ is defined. You may + # optionally pass the +type+ of +const+ as [const, type], + # like as: + # + # have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h") + # + # You may also pass additional +headers+ to check against in addition + # to the common header files, and additional flags to +opt+ which are + # then passed along to the compiler. + # + # If found, a macro is passed as a preprocessor constant to the compiler using + # the type name, in uppercase, prepended with 'HAVE_CONST_'. + # + # For example, if have_const('foo') returned true, then the HAVE_CONST_FOO + # preprocessor macro would be passed to the compiler. + # + def self.have_const(const, headers = nil, opt = "", &b) + checking_for checking_message([*const].compact.join(' '), headers, opt) do + try_const(const, headers, opt, &b) + end end -end -# Returns the size of the given +type+. You may optionally specify additional -# +headers+ to search in for the +type+. -# -# If found, a macro is passed as a preprocessor constant to the compiler using -# the type name, in uppercase, prepended with 'SIZEOF_', followed by the type -# name, followed by '=X' where 'X' is the actual size. -# -# For example, if check_sizeof('mystruct') returned 12, then the -# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler. -# -def check_sizeof(type, headers = nil, &b) - expr = "sizeof(#{type})" - fmt = "%d" - def fmt.%(x) - x ? super : "failed" - end - checking_for checking_message("size of #{type}", headers), fmt do - if size = try_constant(expr, headers, &b) - $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size)) - size + # Returns the size of the given +type+. You may optionally specify additional + # +headers+ to search in for the +type+. + # + # If found, a macro is passed as a preprocessor constant to the compiler using + # the type name, in uppercase, prepended with 'SIZEOF_', followed by the type + # name, followed by '=X' where 'X' is the actual size. + # + # For example, if check_sizeof('mystruct') returned 12, then the + # SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler. + # + def self.check_sizeof(type, headers = nil, &b) + expr = "sizeof(#{type})" + fmt = "%d" + def fmt.%(x) + x ? super : "failed" + end + checking_for checking_message("size of #{type}", headers), fmt do + if size = try_constant(expr, headers, &b) + $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size)) + size + end end end -end -def scalar_ptr_type?(type, member = nil, headers = nil, &b) - try_compile(<<"SRC", &b) # pointer -#{COMMON_HEADERS} -#{cpp_include(headers)} -/*top*/ -volatile #{type} conftestval; -int main() { return 0; } -int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));} + def self.scalar_ptr_type?(type, member = nil, headers = nil, &b) + try_compile(<<"SRC", &b) # pointer + #{COMMON_HEADERS} + #{cpp_include(headers)} + /*top*/ + volatile #{type} conftestval; + int main() { return 0; } + int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));} SRC -end + end -def scalar_type?(type, member = nil, headers = nil, &b) - try_compile(<<"SRC", &b) # pointer -#{COMMON_HEADERS} -#{cpp_include(headers)} -/*top*/ -volatile #{type} conftestval; -int main() { return 0; } -int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));} + def self.scalar_type?(type, member = nil, headers = nil, &b) + try_compile(<<"SRC", &b) # pointer + #{COMMON_HEADERS} + #{cpp_include(headers)} + /*top*/ + volatile #{type} conftestval; + int main() { return 0; } + int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));} SRC -end + end -def what_type?(type, member = nil, headers = nil, &b) - m = "#{type}" - name = type - if member - m << "." << member - name = "(((#{type} *)0)->#{member})" - end - fmt = "seems %s" - def fmt.%(x) - x ? super : "unknown" - end - checking_for checking_message(m, headers), fmt do - if scalar_ptr_type?(type, member, headers, &b) - if try_static_assert("sizeof(*#{name}) == 1", headers) - "string" - end - elsif scalar_type?(type, member, headers, &b) - if try_static_assert("sizeof(#{name}) > sizeof(long)", headers) - "long long" - elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers) - "long" - elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers) - "int" - elsif try_static_assert("sizeof(#{name}) > 1", headers) - "short" - else - "char" + def self.what_type?(type, member = nil, headers = nil, &b) + m = "#{type}" + name = type + if member + m << "." << member + name = "(((#{type} *)0)->#{member})" + end + fmt = "seems %s" + def fmt.%(x) + x ? super : "unknown" + end + checking_for checking_message(m, headers), fmt do + if scalar_ptr_type?(type, member, headers, &b) + if try_static_assert("sizeof(*#{name}) == 1", headers) + "string" + end + elsif scalar_type?(type, member, headers, &b) + if try_static_assert("sizeof(#{name}) > sizeof(long)", headers) + "long long" + elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers) + "long" + elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers) + "int" + elsif try_static_assert("sizeof(#{name}) > 1", headers) + "short" + else + "char" + end end end end -end -def find_executable0(bin, path = nil) - ext = config_string('EXEEXT') - if File.expand_path(bin) == bin - return bin if File.executable?(bin) - ext and File.executable?(file = bin + ext) and return file - return nil - end - if path ||= ENV['PATH'] - path = path.split(File::PATH_SEPARATOR) - else - path = %w[/usr/local/bin /usr/ucb /usr/bin /bin] + def self.find_executable0(bin, path = nil) + ext = config_string('EXEEXT') + if File.expand_path(bin) == bin + return bin if File.executable?(bin) + ext and File.executable?(file = bin + ext) and return file + return nil + end + if path ||= ENV['PATH'] + path = path.split(File::PATH_SEPARATOR) + else + path = %w[/usr/local/bin /usr/ucb /usr/bin /bin] + end + file = nil + path.each do |dir| + return file if File.executable?(file = File.join(dir, bin)) + return file if ext and File.executable?(file << ext) + end + nil end - file = nil - path.each do |dir| - return file if File.executable?(file = File.join(dir, bin)) - return file if ext and File.executable?(file << ext) + + def self.find_executable(bin, path = nil) + checking_for checking_message(bin, path) do + find_executable0(bin, path) + end end - nil -end -def find_executable(bin, path = nil) - checking_for checking_message(bin, path) do - find_executable0(bin, path) + def self.arg_config(config, default=nil, &block) + $arg_config << [config, default] + defaults = [] + if default + defaults << default + elsif !block + defaults << nil + end + $configure_args.fetch(config.tr('_', '-'), *defaults, &block) end -end -def arg_config(config, default=nil, &block) - $arg_config << [config, default] - defaults = [] - if default - defaults << default - elsif !block - defaults << nil + def self.with_config(config, default=nil) + config = config.sub(/^--with[-_]/, '') + val = arg_config("--with-"+config) do + if arg_config("--without-"+config) + false + elsif block_given? + yield(config, default) + else + break default + end + end + case val + when "yes" + true + when "no" + false + else + val + end end - $configure_args.fetch(config.tr('_', '-'), *defaults, &block) -end -def with_config(config, default=nil) - config = config.sub(/^--with[-_]/, '') - val = arg_config("--with-"+config) do - if arg_config("--without-"+config) + def self.enable_config(config, default=nil) + if arg_config("--enable-"+config) + true + elsif arg_config("--disable-"+config) false elsif block_given? yield(config, default) else - break default + return default end end - case val - when "yes" - true - when "no" - false - else - val - end -end - -def enable_config(config, default=nil) - if arg_config("--enable-"+config) - true - elsif arg_config("--disable-"+config) - false - elsif block_given? - yield(config, default) - else - return default - end -end -def create_header(header = "extconf.h") - message "creating %s\n", header - sym = header.tr("a-z./\055", "A-Z___") - hdr = ["#ifndef #{sym}\n#define #{sym}\n"] - for line in $defs - case line - when /^-D([^=]+)(?:=(.*))?/ - hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n" - when /^-U(.*)/ - hdr << "#undef #$1\n" - end + def self.create_header(header = "extconf.h") + message "creating %s\n", header + sym = header.tr("a-z./\055", "A-Z___") + hdr = ["#ifndef #{sym}\n#define #{sym}\n"] + for line in $defs + case line + when /^-D([^=]+)(?:=(.*))?/ + hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n" + when /^-U(.*)/ + hdr << "#undef #$1\n" + end + end + hdr << "#endif\n" + hdr = hdr.join + unless (IO.read(header) == hdr rescue false) + open(header, "w") do |hfile| + hfile.write(hdr) end - hdr << "#endif\n" - hdr = hdr.join - unless (IO.read(header) == hdr rescue false) - open(header, "w") do |hfile| - hfile.write(hdr) end - end - $extconf_h = header -end - -# Sets a +target+ name that the user can then use to configure various 'with' -# options with on the command line by using that name. For example, if the -# target is set to "foo", then the user could use the --with-foo-dir command -# line option. -# -# You may pass along additional 'include' or 'lib' defaults via the +idefault+ -# and +ldefault+ parameters, respectively. -# -# Note that dir_config only adds to the list of places to search for libraries -# and include files. It does not link the libraries into your application. -# -def dir_config(target, idefault=nil, ldefault=nil) - if dir = with_config(target + "-dir", (idefault unless ldefault)) - defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR) - idefault = ldefault = nil - end + $extconf_h = header + end + + # Sets a +target+ name that the user can then use to configure various 'with' + # options with on the command line by using that name. For example, if the + # target is set to "foo", then the user could use the --with-foo-dir command + # line option. + # + # You may pass along additional 'include' or 'lib' defaults via the +idefault+ + # and +ldefault+ parameters, respectively. + # + # Note that dir_config only adds to the list of places to search for libraries + # and include files. It does not link the libraries into your application. + # + def self.dir_config(target, idefault=nil, ldefault=nil) + if dir = with_config(target + "-dir", (idefault unless ldefault)) + 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" + 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 ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : [] - if defaults - idirs.concat(defaults.collect {|d| d + "/include"}) - idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR) - end - unless idirs.empty? - idirs.collect! {|d| "-I" + d} - idirs -= Shellwords.shellwords($CPPFLAGS) + idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : [] + if defaults + idirs.concat(defaults.collect {|d| d + "/include"}) + idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR) + end unless idirs.empty? - $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ") + idirs.collect! {|d| "-I" + d} + idirs -= Shellwords.shellwords($CPPFLAGS) + unless idirs.empty? + $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ") + end end - end - ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : [] - if defaults - ldirs.concat(defaults.collect {|d| d + "/lib"}) - ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR) + ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : [] + if defaults + ldirs.concat(defaults.collect {|d| d + "/lib"}) + ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR) + end + $LIBPATH = ldirs | $LIBPATH + + [idir, ldir] + end + + def self.pkg_config(pkg) + if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig) + # iff package specific config command is given + get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} + elsif ($PKGCONFIG ||= + (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) && + find_executable0(pkgconfig) && pkgconfig) and + system("#{$PKGCONFIG} --exists #{pkg}") + # default to pkg-config command + get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp} + elsif find_executable0(pkgconfig = "#{pkg}-config") + # default to package specific config command, as a last resort. + get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} + end + if get + cflags = get['cflags'] + ldflags = get['libs'] + libs = get['libs-only-l'] + ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") + $CFLAGS += " " << cflags + $LDFLAGS += " " << ldflags + $libs += " " << libs + Logging::message "package configuration for %s\n", pkg + Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", + cflags, ldflags, libs + [cflags, ldflags, libs] + else + Logging::message "package configuration for %s is not found\n", pkg + nil + end end - $LIBPATH = ldirs | $LIBPATH - - [idir, ldir] -end -def pkg_config(pkg) - if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig) - # iff package specific config command is given - get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} - elsif ($PKGCONFIG ||= - (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) && - find_executable0(pkgconfig) && pkgconfig) and - system("#{$PKGCONFIG} --exists #{pkg}") - # default to pkg-config command - get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp} - elsif find_executable0(pkgconfig = "#{pkg}-config") - # default to package specific config command, as a last resort. - get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} - end - if get - cflags = get['cflags'] - ldflags = get['libs'] - libs = get['libs-only-l'] - ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") - $CFLAGS += " " << cflags - $LDFLAGS += " " << ldflags - $libs += " " << libs - Logging::message "package configuration for %s\n", pkg - Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", - cflags, ldflags, libs - [cflags, ldflags, libs] - else - Logging::message "package configuration for %s is not found\n", pkg - nil + def self.with_destdir(dir) + dir = dir.sub($dest_prefix_pattern, '') + /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir end -end - -def with_destdir(dir) - dir = dir.sub($dest_prefix_pattern, '') - /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir -end -def winsep(s) - s.tr('/', '\\') -end + def self.winsep(s) + s.tr('/', '\\') + end -def configuration(srcdir) - mk = [] - vpath = $VPATH.dup - if !CROSS_COMPILING - case CONFIG['build_os'] - when 'cygwin' - if CONFIG['target_os'] != 'cygwin' - vpath = vpath.map {|p| p.sub(/.*/, '$(shell cygpath -u \&)')} + def self.configuration(srcdir) + mk = [] + vpath = $VPATH.dup + if !CROSS_COMPILING + case CONFIG['build_os'] + when 'cygwin' + if CONFIG['target_os'] != 'cygwin' + vpath = vpath.map {|p| p.sub(/.*/, '$(shell cygpath -u \&)')} + end + when 'msdosdjgpp', 'mingw32' + CONFIG['PATH_SEPARATOR'] = ';' end - when 'msdosdjgpp', 'mingw32' - CONFIG['PATH_SEPARATOR'] = ';' end - end - CONFIG["hdrdir"] ||= $hdrdir - mk << %{ -SHELL = /bin/sh + CONFIG["hdrdir"] ||= $hdrdir + mk << %{ + SHELL = /bin/sh -#### Start of system configuration section. #### -#{ -if $extmk - "top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") -end -} -srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {CONFIG[$1||$2]}.quote} -topdir = #{($extmk ? CONFIG["topdir"] : $topdir).quote} -hdrdir = #{CONFIG["hdrdir"].quote} -arch_hdrdir = #{$arch_hdrdir} -VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])} -} + #### Start of system configuration section. #### + #{ if $extmk - mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n" - end - if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1] - mk << "\nDESTDIR = #{destdir}\n" - end - CONFIG.each do |key, var| - next unless /prefix$/ =~ key - mk << "#{key} = #{with_destdir(var)}\n" - end - CONFIG.each do |key, var| - next if /^abs_/ =~ key - next if /^(?:src|top|hdr)dir$/ =~ key - next unless /dir$/ =~ key - mk << "#{key} = #{with_destdir(var)}\n" - end - if !$extmk and !$configure_args.has_key?('--ruby') and - sep = config_string('BUILD_FILE_SEPARATOR') - sep = ":/=#{sep}" - else - sep = "" - end - extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" " - mk << %{ -CC = #{CONFIG['CC']} -CXX = #{CONFIG['CXX']} -LIBRUBY = #{CONFIG['LIBRUBY']} -LIBRUBY_A = #{CONFIG['LIBRUBY_A']} -LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED -LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC -OUTFLAG = #{OUTFLAG} -COUTFLAG = #{COUTFLAG} - -RUBY_EXTCONF_H = #{$extconf_h} -CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG -INCFLAGS = -I. #$INCFLAGS -DEFS = #{CONFIG['DEFS']} -CPPFLAGS = #{extconf_h}#{$CPPFLAGS} -CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']} -ldflags = #{$LDFLAGS} -dldflags = #{$DLDFLAGS} -archflag = #{$ARCH_FLAG} -DLDFLAGS = $(ldflags) $(dldflags) $(archflag) -LDSHARED = #{CONFIG['LDSHARED']} -LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'} -AR = #{CONFIG['AR']} -EXEEXT = #{CONFIG['EXEEXT']} - -RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']} -RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']} -arch = #{CONFIG['arch']} -sitearch = #{CONFIG['sitearch']} -ruby_version = #{RbConfig::CONFIG['ruby_version']} -ruby = #{$ruby} -RUBY = $(ruby#{sep}) -RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'} -MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'} -INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'} -INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'} -INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'} -COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'} - -#### End of system configuration section. #### - -preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''} -} - if $nmake == ?b - mk.each do |x| - x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do - "!ifndef " + $1 + "\n" + - $& + - "!endif\n" + "top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") + end + } + srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {CONFIG[$1||$2]}.quote} + topdir = #{($extmk ? CONFIG["topdir"] : $topdir).quote} + hdrdir = #{CONFIG["hdrdir"].quote} + arch_hdrdir = #{$arch_hdrdir} + VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])} + } + if $extmk + mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n" + end + if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1] + mk << "\nDESTDIR = #{destdir}\n" + end + CONFIG.each do |key, var| + next unless /prefix$/ =~ key + mk << "#{key} = #{with_destdir(var)}\n" + end + CONFIG.each do |key, var| + next if /^abs_/ =~ key + next if /^(?:src|top|hdr)dir$/ =~ key + next unless /dir$/ =~ key + mk << "#{key} = #{with_destdir(var)}\n" + end + if !$extmk and !$configure_args.has_key?('--ruby') and + sep = config_string('BUILD_FILE_SEPARATOR') + sep = ":/=#{sep}" + else + sep = "" + end + extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" " + mk << %{ + CC = #{CONFIG['CC']} + CXX = #{CONFIG['CXX']} + LIBRUBY = #{CONFIG['LIBRUBY']} + LIBRUBY_A = #{CONFIG['LIBRUBY_A']} + LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED + LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC + OUTFLAG = #{OUTFLAG} + COUTFLAG = #{COUTFLAG} + + RUBY_EXTCONF_H = #{$extconf_h} + CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG + INCFLAGS = -I. #$INCFLAGS + DEFS = #{CONFIG['DEFS']} + CPPFLAGS = #{extconf_h}#{$CPPFLAGS} + CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']} + ldflags = #{$LDFLAGS} + dldflags = #{$DLDFLAGS} + archflag = #{$ARCH_FLAG} + DLDFLAGS = $(ldflags) $(dldflags) $(archflag) + LDSHARED = #{CONFIG['LDSHARED']} + LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'} + AR = #{CONFIG['AR']} + EXEEXT = #{CONFIG['EXEEXT']} + + RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']} + RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']} + arch = #{CONFIG['arch']} + sitearch = #{CONFIG['sitearch']} + ruby_version = #{RbConfig::CONFIG['ruby_version']} + ruby = #{$ruby} + RUBY = $(ruby#{sep}) + RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'} + MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'} + INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'} + INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'} + INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'} + COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'} + + #### End of system configuration section. #### + + preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''} + } + if $nmake == ?b + mk.each do |x| + x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do + "!ifndef " + $1 + "\n" + + $& + + "!endif\n" + end end end + mk end - mk -end -def dummy_makefile(srcdir) - configuration(srcdir) << <>$(INSTALLED_LIST)\n" + end + origdef ||= '' + + if $extmk and not $extconf_h + create_header + end + + libpath = libpathflag(libpath) + + dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : "" + staticlib = target ? "$(TARGET).#$LIBEXT" : "" + mfile = open("Makefile", "wb") + mfile.print(*configuration(srcprefix)) + mfile.print " + libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")} + LIBPATH = #{libpath} + DEFFILE = #{deffile} + + CLEANFILES = #{$cleanfiles.join(' ')} + DISTCLEANFILES = #{$distcleanfiles.join(' ')} + + extout = #{$extout} + extout_prefix = #{$extout_prefix} + 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} + EXTSTATIC = #{$static || ""} + STATIC_LIB = #{staticlib unless $static.nil?} + #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""} + " #" + # TODO: fixme + install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]} + n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).' + mfile.print " + TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB) + CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map + CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak + + all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"} + static: $(STATIC_LIB)#{$extout ? " install-rb" : ""} + " + mfile.print CLEANINGS + dirs = [] + mfile.print "install: install-so install-rb\n\n" + sodir = (dir = "$(RUBYARCHDIR)").dup + mfile.print("install-so: ") + if target + f = "$(DLLIB)" + dest = "#{dir}/#{f}" + mfile.puts dir, "install-so: #{dest}" + unless $extout + mfile.print "#{dest}: #{f}\n" + if (sep = config_string('BUILD_FILE_SEPARATOR')) + f.gsub!("/", sep) + dir.gsub!("/", sep) + sep = ":/="+sep + f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2} + f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2} + dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2} + dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2} + end + mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n" + if defined?($installed_list) + mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n" + end end + else + mfile.puts "Makefile" end - else - mfile.puts "Makefile" - end - mfile.print("install-rb: pre-install-rb install-rb-default\n") - mfile.print("install-rb-default: pre-install-rb-default\n") - mfile.print("pre-install-rb: Makefile\n") - mfile.print("pre-install-rb-default: Makefile\n") - for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]] - files = install_files(mfile, i, nil, srcprefix) or next - for dir, *files in files - unless dirs.include?(dir) - dirs << dir - mfile.print "pre-install-rb#{sfx}: #{dir}\n" - end if $nmake - for f in files - dest = "#{dir}/#{File.basename(f)}" - mfile.print("install-rb#{sfx}: #{dest}\n") - mfile.print("#{dest}: #{f}\n") - mfile.print("\t$(MAKEDIRS) $(@D)\n") unless $nmake - mfile.print("\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ") - sep = config_string('BUILD_FILE_SEPARATOR') - if sep - f = f.gsub("/", sep) - sep = ":/="+sep - f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2} - f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2} - else - sep = "" - end - mfile.print("#{f} $(@D#{sep})\n") - if defined?($installed_list) and !$extout - mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n") - end + mfile.print("install-rb: pre-install-rb install-rb-default\n") + mfile.print("install-rb-default: pre-install-rb-default\n") + mfile.print("pre-install-rb: Makefile\n") + mfile.print("pre-install-rb-default: Makefile\n") + for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]] + files = install_files(mfile, i, nil, srcprefix) or next + for dir, *files in files + unless dirs.include?(dir) + dirs << dir + mfile.print "pre-install-rb#{sfx}: #{dir}\n" + end if $nmake + for f in files + dest = "#{dir}/#{File.basename(f)}" + mfile.print("install-rb#{sfx}: #{dest}\n") + mfile.print("#{dest}: #{f}\n") + mfile.print("\t$(MAKEDIRS) $(@D)\n") unless $nmake + mfile.print("\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ") + sep = config_string('BUILD_FILE_SEPARATOR') + if sep + f = f.gsub("/", sep) + sep = ":/="+sep + f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2} + f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2} + else + sep = "" + end + mfile.print("#{f} $(@D#{sep})\n") + if defined?($installed_list) and !$extout + mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n") + end + end end end - end - dirs.unshift(sodir) if target and !dirs.include?(sodir) - dirs.each {|d| mfile.print "#{d}:\n\t$(MAKEDIRS) $@\n" if $nmake || d == sodir} + dirs.unshift(sodir) if target and !dirs.include?(sodir) + dirs.each {|d| mfile.print "#{d}:\n\t$(MAKEDIRS) $@\n" if $nmake || d == sodir} - mfile.print <<-SITEINSTALL + mfile.print <<-SITEINSTALL -site-install: site-install-so site-install-rb -site-install-so: install-so -site-install-rb: install-rb + site-install: site-install-so site-install-rb + site-install-so: install-so + site-install-rb: install-rb - SITEINSTALL + SITEINSTALL - return unless target + return unless target - mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b - mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n" - mfile.print "\n" + mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b + mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n" + mfile.print "\n" - CXX_EXT.each do |ext| - COMPILE_RULES.each do |rule| - mfile.printf(rule, ext, $OBJEXT) - mfile.printf("\n\t%s\n\n", COMPILE_CXX) + CXX_EXT.each do |ext| + COMPILE_RULES.each do |rule| + mfile.printf(rule, ext, $OBJEXT) + mfile.printf("\n\t%s\n\n", COMPILE_CXX) + end end - end - %w[c].each do |ext| - COMPILE_RULES.each do |rule| - mfile.printf(rule, ext, $OBJEXT) - mfile.printf("\n\t%s\n\n", COMPILE_C) + %w[c].each do |ext| + COMPILE_RULES.each do |rule| + mfile.printf(rule, ext, $OBJEXT) + mfile.printf("\n\t%s\n\n", COMPILE_C) + end end - end - sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || "" - mfile.print "$(RUBYARCHDIR)/" if $extout - mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n" - mfile.print "\t@-$(RM) $(@#{sep})\n" - mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout - link_so = LINK_SO.gsub(/^/, "\t") - if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===)) - link_so = link_so.sub(/\bLDSHARED\b/, '\&XX') - end - mfile.print link_so, "\n\n" - unless $static.nil? - mfile.print "$(STATIC_LIB): $(OBJS)\n\t@-$(RM) $(@#{sep})\n\t" - mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)" - config_string('RANLIB') do |ranlib| - mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true" + sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || "" + mfile.print "$(RUBYARCHDIR)/" if $extout + mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n" + mfile.print "\t@-$(RM) $(@#{sep})\n" + mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout + link_so = LINK_SO.gsub(/^/, "\t") + if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===)) + link_so = link_so.sub(/\bLDSHARED\b/, '\&XX') + end + mfile.print link_so, "\n\n" + unless $static.nil? + mfile.print "$(STATIC_LIB): $(OBJS)\n\t@-$(RM) $(@#{sep})\n\t" + mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)" + config_string('RANLIB') do |ranlib| + mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true" + end + end + mfile.print "\n\n" + if makedef + mfile.print "$(DEFFILE): #{origdef}\n" + mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n" end - end - mfile.print "\n\n" - if makedef - mfile.print "$(DEFFILE): #{origdef}\n" - mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n" - end - depend = File.join(srcdir, "depend") - if File.exist?(depend) - mfile.print("###\n", *depend_rules(File.read(depend))) - else - headers = %w[ruby.h defines.h] - if RULE_SUBST - headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))} + depend = File.join(srcdir, "depend") + if File.exist?(depend) + mfile.print("###\n", *depend_rules(File.read(depend))) + else + headers = %w[ruby.h defines.h] + if RULE_SUBST + headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))} + end + headers << $config_h if $config_h + headers << '$(RUBY_EXTCONF_H)' if $extconf_h + mfile.print "$(OBJS): ", headers.join(' '), "\n" end - headers << $config_h if $config_h - headers << '$(RUBY_EXTCONF_H)' if $extconf_h - mfile.print "$(OBJS): ", headers.join(' '), "\n" - end - $makefile_created = true -ensure - mfile.close if mfile -end + $makefile_created = true + ensure + mfile.close if mfile + end + + def self.init_mkmf(config = CONFIG) # :nodoc: + $makefile_created = false + $arg_config = [] + $enable_shared = config['ENABLE_SHARED'] == 'yes' + $defs = [] + $extconf_h = nil + $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup + $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup + $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup + $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup + $INCFLAGS = "-I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir)" + $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup + $LIBEXT = config['LIBEXT'].dup + $OBJEXT = config["OBJEXT"].dup + $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}" + $LIBRUBYARG = "" + $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC'] + $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED'] + $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"] + $DEFLIBPATH.unshift(".") + $LIBPATH = [] + $INSTALLFILES = [] + $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/] + $VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby] + + $objs = nil + $srcs = nil + $libs = "" + if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup) + $LIBRUBYARG = config['LIBRUBYARG'] + end -def init_mkmf(config = CONFIG) - $makefile_created = false - $arg_config = [] - $enable_shared = config['ENABLE_SHARED'] == 'yes' - $defs = [] - $extconf_h = nil - $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup - $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup - $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup - $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup - $INCFLAGS = "-I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir)" - $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup - $LIBEXT = config['LIBEXT'].dup - $OBJEXT = config["OBJEXT"].dup - $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}" - $LIBRUBYARG = "" - $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC'] - $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED'] - $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"] - $DEFLIBPATH.unshift(".") - $LIBPATH = [] - $INSTALLFILES = [] - $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/] - $VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby] - - $objs = nil - $srcs = nil - $libs = "" - if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup) - $LIBRUBYARG = config['LIBRUBYARG'] - end - - $LOCAL_LIBS = "" - - $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || [] - $cleanfiles << "mkmf.log" - $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || [] - - $extout ||= nil - $extout_prefix ||= nil - - $arg_config.clear - dir_config("opt") -end + $LOCAL_LIBS = "" -FailedMessage = <"} -end -COMMON_HEADERS = hdr.join("\n") -COMMON_LIBS = config_string('COMMON_LIBS', &split) || [] - -COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:] -RULE_SUBST = config_string('RULE_SUBST') -COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<' -COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<' -TRY_LINK = config_string('TRY_LINK') || - "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \ - "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)" -LINK_SO = config_string('LINK_SO') || - if CONFIG["DLEXT"] == $OBJEXT - "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n" + + RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] = + $srcdir = arg_config("--srcdir", File.dirname($0)) + $configure_args["--topsrcdir"] ||= $srcdir + if $curdir = arg_config("--curdir") + RbConfig.expand(curdir = $curdir.dup) else - "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \ - "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)" + curdir = $curdir = "." + end + unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir) + CONFIG["topdir"] = $curdir + RbConfig::CONFIG["topdir"] = curdir + end + $configure_args["--topdir"] ||= $curdir + $ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"])) + + split = Shellwords.method(:shellwords).to_proc + + EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip} + + hdr = [] + config_string('COMMON_MACROS') do |s| + Shellwords.shellwords(s).each do |w| + hdr << "#define " + w.split(/=/, 2).join(" ") + end end -LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"' -RPATHFLAG = config_string('RPATHFLAG') || '' -LIBARG = config_string('LIBARG') || '-l%s' + config_string('COMMON_HEADERS') do |s| + Shellwords.shellwords(s).each {|w| hdr << "#include <#{w}>"} + end + COMMON_HEADERS = hdr.join("\n") + COMMON_LIBS = config_string('COMMON_LIBS', &split) || [] + + COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:] + RULE_SUBST = config_string('RULE_SUBST') + COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<' + COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<' + TRY_LINK = config_string('TRY_LINK') || + "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \ + "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)" + LINK_SO = config_string('LINK_SO') || + if CONFIG["DLEXT"] == $OBJEXT + "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n" + else + "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \ + "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)" + end + LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"' + RPATHFLAG = config_string('RPATHFLAG') || '' + LIBARG = config_string('LIBARG') || '-l%s' -sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if sep != "/"} || "" -CLEANINGS = " -clean: - @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) + sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if sep != "/"} || "" + CLEANINGS = " + clean: + @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) -distclean: clean - @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log - @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep}) + distclean: clean + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep}) -realclean: distclean -" + realclean: distclean + " -if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0) - END {mkmf_failed($0)} + if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0) + END {mkmf_failed($0)} + end end + +include MKMF + + --------------000105000206020905010701--