Feature #5658 » mkmf.rb.in_a_module.patch
lib/mkmf.rb (working copy) | ||
---|---|---|
require 'fileutils'
|
||
require 'shellwords'
|
||
CONFIG = RbConfig::MAKEFILE_CONFIG
|
||
ORIG_LIBPATH = ENV['LIB']
|
||
C_EXT = %w[c m]
|
||
CXX_EXT = %w[cc mm cxx cpp]
|
||
if File::FNM_SYSCASE.zero?
|
||
CXX_EXT.concat(%w[C])
|
||
end
|
||
SRC_EXT = C_EXT + CXX_EXT
|
||
$static = nil
|
||
$config_h = '$(arch_hdrdir)/ruby/config.h'
|
||
$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
|
||
$netbsd = /netbsd/ =~ RUBY_PLATFORM
|
||
$os2 = /os2/ =~ RUBY_PLATFORM
|
||
$beos = /beos/ =~ RUBY_PLATFORM
|
||
$haiku = /haiku/ =~ RUBY_PLATFORM
|
||
$solaris = /solaris/ =~ RUBY_PLATFORM
|
||
$universal = /universal/ =~ RUBY_PLATFORM
|
||
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
|
||
# :stopdoc:
|
||
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(File.dirname(__FILE__))
|
||
path = File.expand_path($0)
|
||
$extmk = path[0, topdir.size+1] == topdir+"/"
|
||
$extmk &&= %r"\A(?:ext|enc|tool|test(?:/.+)?)\z" =~ File.dirname(path[topdir.size+1..-1])
|
||
$extmk &&= true
|
||
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")
|
||
$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
|
||
# Wraps a string in escaped quotes if it contains whitespace.
|
||
def quote
|
||
... | ... | |
self[/\A[^()]+/]
|
||
end
|
||
end
|
||
class Array
|
||
# Wraps all strings in escaped quotes if they contain whitespace.
|
||
def quote
|
||
map {|s| s.quote}
|
||
end
|
||
end
|
||
# :startdoc:
|
||
def rm_f(*files)
|
||
opt = (Hash === files.last ? [files.pop] : [])
|
||
FileUtils.rm_f(Dir[*files.flatten], *opt)
|
||
end
|
||
module MakeMakefile
|
||
def rm_rf(*files)
|
||
opt = (Hash === files.last ? [files.pop] : [])
|
||
FileUtils.rm_rf(Dir[*files.flatten], *opt)
|
||
end
|
||
CONFIG = RbConfig::MAKEFILE_CONFIG
|
||
ORIG_LIBPATH = ENV['LIB']
|
||
# Returns time stamp of the +target+ file if it exists and is newer
|
||
# than or equal to all of +times+.
|
||
def modified?(target, times)
|
||
(t = File.mtime(target)) rescue return nil
|
||
Array === times or times = [times]
|
||
t if times.all? {|n| n <= t}
|
||
end
|
||
C_EXT = %w[c m]
|
||
CXX_EXT = %w[cc mm cxx cpp]
|
||
if File::FNM_SYSCASE.zero?
|
||
CXX_EXT.concat(%w[C])
|
||
end
|
||
SRC_EXT = C_EXT + CXX_EXT
|
||
$static = nil
|
||
$config_h = '$(arch_hdrdir)/ruby/config.h'
|
||
$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
|
||
$netbsd = /netbsd/ =~ RUBY_PLATFORM
|
||
$os2 = /os2/ =~ RUBY_PLATFORM
|
||
$beos = /beos/ =~ RUBY_PLATFORM
|
||
$haiku = /haiku/ =~ RUBY_PLATFORM
|
||
$solaris = /solaris/ =~ RUBY_PLATFORM
|
||
$universal = /universal/ =~ RUBY_PLATFORM
|
||
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
|
||
# :stopdoc:
|
||
def config_string(key, config = CONFIG)
|
||
s = config[key] and !s.empty? and block_given? ? yield(s) : s
|
||
end
|
||
module_function :config_string
|
||
def dir_re(dir)
|
||
Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
|
||
end
|
||
module_function :dir_re
|
||
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
|
||
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
|
||
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(File.dirname(__FILE__))
|
||
path = File.expand_path($0)
|
||
$extmk = path[0, topdir.size+1] == topdir+"/"
|
||
$extmk &&= %r"\A(?:ext|enc|tool|test(?:/.+)?)\z" =~ File.dirname(path[topdir.size+1..-1])
|
||
$extmk &&= true
|
||
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")
|
||
$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
|
||
def rm_f(*files)
|
||
opt = (Hash === files.last ? [files.pop] : [])
|
||
FileUtils.rm_f(Dir[*files.flatten], *opt)
|
||
end
|
||
def rm_rf(*files)
|
||
opt = (Hash === files.last ? [files.pop] : [])
|
||
FileUtils.rm_rf(Dir[*files.flatten], *opt)
|
||
end
|
||
# Returns time stamp of the +target+ file if it exists and is newer
|
||
# than or equal to all of +times+.
|
||
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
|
||
end
|
||
end
|
||
x.concat(y[yn..-1] || [])
|
||
end
|
||
x.concat(y[yn..-1] || [])
|
||
end
|
||
end
|
||
# This is a custom logging module. It generates an mkmf.log file when you
|
||
# run your extconf.rb script. This can be useful for debugging unexpected
|
||
# failures.
|
||
#
|
||
# This module and its associated methods are meant for internal use only.
|
||
#
|
||
module Logging
|
||
@log = nil
|
||
@logfile = 'mkmf.log'
|
||
@orgerr = $stderr.dup
|
||
@orgout = $stdout.dup
|
||
@postpone = 0
|
||
@quiet = $extmk
|
||
def self::log_open
|
||
@log ||= File::open(@logfile, 'wb')
|
||
@log.sync = true
|
||
end
|
||
def self::open
|
||
log_open
|
||
$stderr.reopen(@log)
|
||
$stdout.reopen(@log)
|
||
yield
|
||
ensure
|
||
$stderr.reopen(@orgerr)
|
||
$stdout.reopen(@orgout)
|
||
end
|
||
# This is a custom logging module. It generates an mkmf.log file when you
|
||
# run your extconf.rb script. This can be useful for debugging unexpected
|
||
# failures.
|
||
#
|
||
# This module and its associated methods are meant for internal use only.
|
||
#
|
||
module Logging
|
||
@log = nil
|
||
@logfile = 'mkmf.log'
|
||
@orgerr = $stderr.dup
|
||
@orgout = $stdout.dup
|
||
@postpone = 0
|
||
@quiet = $extmk
|
||
def self::log_open
|
||
@log ||= File::open(@logfile, 'wb')
|
||
@log.sync = true
|
||
end
|
||
def self::open
|
||
log_open
|
||
$stderr.reopen(@log)
|
||
$stdout.reopen(@log)
|
||
yield
|
||
ensure
|
||
$stderr.reopen(@orgerr)
|
||
$stdout.reopen(@orgout)
|
||
end
|
||
def self::message(*s)
|
||
log_open
|
||
@log.printf(*s)
|
||
end
|
||
def self::message(*s)
|
||
log_open
|
||
@log.printf(*s)
|
||
end
|
||
def self::logfile file
|
||
@logfile = file
|
||
log_close
|
||
end
|
||
def self::logfile file
|
||
@logfile = file
|
||
log_close
|
||
end
|
||
def self::log_close
|
||
if @log and not @log.closed?
|
||
@log.flush
|
||
@log.close
|
||
@log = nil
|
||
def self::log_close
|
||
if @log and not @log.closed?
|
||
@log.flush
|
||
@log.close
|
||
@log = nil
|
||
end
|
||
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})
|
||
ensure
|
||
@log.close if @log and not @log.closed?
|
||
File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
|
||
@log, @logfile, @orgout, @orgerr = log, *save
|
||
@postpone -= 1
|
||
rm_f tmplog
|
||
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})
|
||
ensure
|
||
@log.close if @log and not @log.closed?
|
||
File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
|
||
@log, @logfile, @orgout, @orgerr = log, *save
|
||
@postpone -= 1
|
||
rm_f tmplog
|
||
end
|
||
end
|
||
end
|
||
end
|
||
class << self
|
||
attr_accessor :quiet
|
||
class << self
|
||
attr_accessor :quiet
|
||
end
|
||
end
|
||
end
|
||
def xsystem command, opts = nil
|
||
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
|
||
if opts and opts[:werror]
|
||
result = nil
|
||
Logging.postpone do |log|
|
||
result = (system(command) and File.zero?(log.path))
|
||
""
|
||
def xsystem command, opts = nil
|
||
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
|
||
if opts and opts[:werror]
|
||
result = nil
|
||
Logging.postpone do |log|
|
||
result = (system(command) and File.zero?(log.path))
|
||
""
|
||
end
|
||
result
|
||
else
|
||
system(command)
|
||
end
|
||
result
|
||
else
|
||
system(command)
|
||
end
|
||
end
|
||
end
|
||
def xpopen command, *mode, &block
|
||
Logging::open do
|
||
case mode[0]
|
||
when nil, /^r/
|
||
puts "#{command} |"
|
||
else
|
||
puts "| #{command}"
|
||
def 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
|
||
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"
|
||
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"
|
||
src.each_with_index {|line, no| Logging::message fmt, no+1, line}
|
||
Logging::message <<"EOM"
|
||
/* end */
|
||
EOM
|
||
end
|
||
end
|
||
def create_tmpsrc(src)
|
||
src = "#{COMMON_HEADERS}\n#{src}"
|
||
src = yield(src) if block_given?
|
||
src.gsub!(/[ \t]+$/, '')
|
||
src.gsub!(/\A\n+|^\n+$/, '')
|
||
src.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
|
||
def create_tmpsrc(src)
|
||
src = "#{COMMON_HEADERS}\n#{src}"
|
||
src = yield(src) if block_given?
|
||
src.gsub!(/[ \t]+$/, '')
|
||
src.gsub!(/\A\n+|^\n+$/, '')
|
||
src.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
|
||
src
|
||
end
|
||
def have_devel?
|
||
unless defined? $have_devel
|
||
$have_devel = true
|
||
$have_devel = try_link(MAIN_DOES_NOTHING)
|
||
def have_devel?
|
||
unless defined? $have_devel
|
||
$have_devel = true
|
||
$have_devel = try_link(MAIN_DOES_NOTHING)
|
||
end
|
||
$have_devel
|
||
end
|
||
$have_devel
|
||
end
|
||
def try_do(src, command, *opts, &b)
|
||
unless have_devel?
|
||
raise <<MSG
|
||
def try_do(src, command, *opts, &b)
|
||
unless have_devel?
|
||
raise <<MSG
|
||
The compiler failed to generate an executable file.
|
||
You have to install development tools first.
|
||
MSG
|
||
end
|
||
begin
|
||
src = create_tmpsrc(src, &b)
|
||
xsystem(command, *opts)
|
||
ensure
|
||
log_src(src)
|
||
rm_rf 'conftest.dSYM'
|
||
end
|
||
end
|
||
begin
|
||
src = create_tmpsrc(src, &b)
|
||
xsystem(command, *opts)
|
||
ensure
|
||
log_src(src)
|
||
rm_rf 'conftest.dSYM'
|
||
end
|
||
end
|
||
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
|
||
librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
|
||
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
|
||
'src' => "#{CONFTEST_C}",
|
||
'arch_hdrdir' => $arch_hdrdir.quote,
|
||
'top_srcdir' => $top_srcdir.quote,
|
||
'INCFLAGS' => "#$INCFLAGS",
|
||
'CPPFLAGS' => "#$CPPFLAGS",
|
||
'CFLAGS' => "#$CFLAGS",
|
||
'ARCH_FLAG' => "#$ARCH_FLAG",
|
||
'LDFLAGS' => "#$LDFLAGS #{ldflags}",
|
||
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
|
||
'LIBS' => "#{librubyarg} #{opt} #$LIBS")
|
||
conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
|
||
RbConfig::expand(TRY_LINK.dup, conf)
|
||
end
|
||
def cc_command(opt="")
|
||
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
||
'arch_hdrdir' => $arch_hdrdir.quote,
|
||
'top_srcdir' => $top_srcdir.quote)
|
||
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
||
conf)
|
||
end
|
||
def cpp_command(outfile, opt="")
|
||
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
||
'arch_hdrdir' => $arch_hdrdir.quote,
|
||
'top_srcdir' => $top_srcdir.quote)
|
||
if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
|
||
conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
|
||
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
|
||
librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
|
||
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
|
||
'src' => "#{CONFTEST_C}",
|
||
'arch_hdrdir' => $arch_hdrdir.quote,
|
||
'top_srcdir' => $top_srcdir.quote,
|
||
'INCFLAGS' => "#$INCFLAGS",
|
||
'CPPFLAGS' => "#$CPPFLAGS",
|
||
'CFLAGS' => "#$CFLAGS",
|
||
'ARCH_FLAG' => "#$ARCH_FLAG",
|
||
'LDFLAGS' => "#$LDFLAGS #{ldflags}",
|
||
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
|
||
'LIBS' => "#{librubyarg} #{opt} #$LIBS")
|
||
conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
|
||
RbConfig::expand(TRY_LINK.dup, conf)
|
||
end
|
||
def cc_command(opt="")
|
||
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
||
'arch_hdrdir' => $arch_hdrdir.quote,
|
||
'top_srcdir' => $top_srcdir.quote)
|
||
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
||
conf)
|
||
end
|
||
def cpp_command(outfile, opt="")
|
||
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
|
||
'arch_hdrdir' => $arch_hdrdir.quote,
|
||
'top_srcdir' => $top_srcdir.quote)
|
||
if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
|
||
conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
|
||
end
|
||
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
||
conf)
|
||
end
|
||
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
||
libpath.map{|x|
|
||
case x
|
||
when "$(topdir)", /\A\./
|
||
LIBPATHFLAG
|
||
else
|
||
LIBPATHFLAG+RPATHFLAG
|
||
end % x.quote
|
||
}.join
|
||
end
|
||
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
||
conf)
|
||
end
|
||
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
||
libpath.map{|x|
|
||
case x
|
||
when "$(topdir)", /\A\./
|
||
LIBPATHFLAG
|
||
else
|
||
LIBPATHFLAG+RPATHFLAG
|
||
end % x.quote
|
||
}.join
|
||
end
|
||
def with_werror(opt, opts = nil)
|
||
if opts
|
||
if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
|
||
(opts = opts.dup).delete(:werror)
|
||
def with_werror(opt, opts = nil)
|
||
if opts
|
||
if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
|
||
(opts = opts.dup).delete(:werror)
|
||
end
|
||
yield(opt, opts)
|
||
else
|
||
yield(opt)
|
||
end
|
||
yield(opt, opts)
|
||
else
|
||
yield(opt)
|
||
end
|
||
end
|
||
# :nodoc:
|
||
def try_link0(src, opt="", *opts, &b)
|
||
cmd = link_command("", opt)
|
||
if $universal
|
||
require 'tmpdir'
|
||
Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
|
||
begin
|
||
ENV["TMPDIR"] = tmpdir
|
||
try_do(src, cmd, *opts, &b)
|
||
ensure
|
||
ENV["TMPDIR"] = oldtmpdir
|
||
# :nodoc:
|
||
def try_link0(src, opt="", *opts, &b)
|
||
cmd = link_command("", opt)
|
||
if $universal
|
||
require 'tmpdir'
|
||
Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
|
||
begin
|
||
ENV["TMPDIR"] = tmpdir
|
||
try_do(src, cmd, *opts, &b)
|
||
ensure
|
||
ENV["TMPDIR"] = oldtmpdir
|
||
end
|
||
end
|
||
else
|
||
try_do(src, cmd, *opts, &b)
|
||
end
|
||
else
|
||
try_do(src, cmd, *opts, &b)
|
||
end
|
||
end
|
||
# Returns whether or not the +src+ can be compiled as a C source and
|
||
# linked with its depending libraries successfully.
|
||
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
|
||
# are also passed to the linker.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains linker options
|
||
def try_link(src, opt="", *opts, &b)
|
||
try_link0(src, opt, *opts, &b)
|
||
ensure
|
||
rm_f "conftest*", "c0x32*"
|
||
end
|
||
# Returns whether or not the +src+ can be compiled as a C source.
|
||
# +opt+ is passed to the C compiler as options. Note that +$CFLAGS+ is
|
||
# also passed to the compiler.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains compiler options
|
||
def try_compile(src, opt="", *opts, &b)
|
||
with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)}
|
||
ensure
|
||
rm_f "conftest*"
|
||
end
|
||
# Returns whether or not the +src+ can be compiled as a C source and
|
||
# linked with its depending libraries successfully.
|
||
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
|
||
# are also passed to the linker.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains linker options
|
||
def try_link(src, opt="", *opts, &b)
|
||
try_link0(src, opt, *opts, &b)
|
||
ensure
|
||
rm_f "conftest*", "c0x32*"
|
||
end
|
||
# Returns whether or not the +src+ can be preprocessed with the C preprocessor.
|
||
# +opt+ is passed to the preprocessor as options. Note that +$CFLAGS+ is
|
||
# also passed to the preprocessor.
|
||
#
|
||
# If a block given, it is called with the source before preprocessing. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains preprocessor options
|
||
def try_cpp(src, opt="", *opts, &b)
|
||
try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b)
|
||
ensure
|
||
rm_f "conftest*"
|
||
end
|
||
# Returns whether or not the +src+ can be compiled as a C source.
|
||
# +opt+ is passed to the C compiler as options. Note that +$CFLAGS+ is
|
||
# also passed to the compiler.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains compiler options
|
||
def try_compile(src, opt="", *opts, &b)
|
||
with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)}
|
||
ensure
|
||
rm_f "conftest*"
|
||
end
|
||
class Object
|
||
alias_method :try_header, (config_string('try_header') || :try_cpp)
|
||
end
|
||
# Returns whether or not the +src+ can be preprocessed with the C preprocessor.
|
||
# +opt+ is passed to the preprocessor as options. Note that +$CFLAGS+ is
|
||
# also passed to the preprocessor.
|
||
#
|
||
# If a block given, it is called with the source before preprocessing. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains preprocessor options
|
||
def try_cpp(src, opt="", *opts, &b)
|
||
try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b)
|
||
ensure
|
||
rm_f "conftest*"
|
||
end
|
||
def cpp_include(header)
|
||
if header
|
||
header = [header] unless header.kind_of? Array
|
||
header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
|
||
else
|
||
""
|
||
def cpp_include(header)
|
||
if header
|
||
header = [header] unless header.kind_of? Array
|
||
header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
|
||
else
|
||
""
|
||
end
|
||
end
|
||
end
|
||
def with_cppflags(flags)
|
||
cppflags = $CPPFLAGS
|
||
$CPPFLAGS = flags
|
||
ret = yield
|
||
ensure
|
||
$CPPFLAGS = cppflags unless ret
|
||
end
|
||
def with_cppflags(flags)
|
||
cppflags = $CPPFLAGS
|
||
$CPPFLAGS = flags
|
||
ret = yield
|
||
ensure
|
||
$CPPFLAGS = cppflags unless ret
|
||
end
|
||
def with_cflags(flags)
|
||
cflags = $CFLAGS
|
||
$CFLAGS = flags
|
||
ret = yield
|
||
ensure
|
||
$CFLAGS = cflags unless ret
|
||
end
|
||
def with_cflags(flags)
|
||
cflags = $CFLAGS
|
||
$CFLAGS = flags
|
||
ret = yield
|
||
ensure
|
||
$CFLAGS = cflags unless ret
|
||
end
|
||
def with_ldflags(flags)
|
||
ldflags = $LDFLAGS
|
||
$LDFLAGS = flags
|
||
ret = yield
|
||
ensure
|
||
$LDFLAGS = ldflags unless ret
|
||
end
|
||
def with_ldflags(flags)
|
||
ldflags = $LDFLAGS
|
||
$LDFLAGS = flags
|
||
ret = yield
|
||
ensure
|
||
$LDFLAGS = ldflags unless ret
|
||
end
|
||
def try_static_assert(expr, headers = nil, opt = "", &b)
|
||
headers = cpp_include(headers)
|
||
try_compile(<<SRC, opt, &b)
|
||
def try_static_assert(expr, headers = nil, opt = "", &b)
|
||
headers = cpp_include(headers)
|
||
try_compile(<<SRC, opt, &b)
|
||
#{headers}
|
||
/*top*/
|
||
int conftest_const[(#{expr}) ? 1 : -1];
|
||
SRC
|
||
end
|
||
end
|
||
def 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
|
||
# 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 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 = %{#{includes}
|
||
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 = %{#{includes}
|
||
#include <stdio.h>
|
||
/*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)
|
||
if try_link0(src, opt, &b)
|
||
xpopen("./conftest") do |f|
|
||
return Integer(f.gets)
|
||
end
|
||
end
|
||
end
|
||
nil
|
||
end
|
||
nil
|
||
end
|
||
# You should use +have_func+ rather than +try_func+.
|
||
#
|
||
# [+func+] a String which contains a symbol name
|
||
# [+libs+] a String which contains library names.
|
||
# [+headers+] a String or an Array of strings which contains
|
||
# names of header files.
|
||
def try_func(func, libs, headers = nil, opt = "", &b)
|
||
headers = cpp_include(headers)
|
||
case func
|
||
when /^&/
|
||
decltype = proc {|x|"const volatile void *#{x}"}
|
||
when /\)$/
|
||
call = func
|
||
else
|
||
call = "#{func}()"
|
||
decltype = proc {|x| "void ((*#{x})())"}
|
||
end
|
||
if opt and !opt.empty?
|
||
[[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
|
||
if opt.respond_to?(meth)
|
||
break opt = opt.send(meth, *args)
|
||
# You should use +have_func+ rather than +try_func+.
|
||
#
|
||
# [+func+] a String which contains a symbol name
|
||
# [+libs+] a String which contains library names.
|
||
# [+headers+] a String or an Array of strings which contains
|
||
# names of header files.
|
||
def try_func(func, libs, headers = nil, opt = "", &b)
|
||
headers = cpp_include(headers)
|
||
case func
|
||
when /^&/
|
||
decltype = proc {|x|"const volatile void *#{x}"}
|
||
when /\)$/
|
||
call = func
|
||
else
|
||
call = "#{func}()"
|
||
decltype = proc {|x| "void ((*#{x})())"}
|
||
end
|
||
if opt and !opt.empty?
|
||
[[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
|
||
if opt.respond_to?(meth)
|
||
break opt = opt.send(meth, *args)
|
||
end
|
||
end
|
||
opt = "#{opt} #{libs}"
|
||
else
|
||
opt = libs
|
||
end
|
||
opt = "#{opt} #{libs}"
|
||
else
|
||
opt = libs
|
||
end
|
||
decltype && try_link(<<"SRC", opt, &b) or
|
||
decltype && try_link(<<"SRC", opt, &b) or
|
||
#{headers}
|
||
/*top*/
|
||
#{MAIN_DOES_NOTHING}
|
||
int t() { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
|
||
SRC
|
||
call && try_link(<<"SRC", opt, &b)
|
||
call && try_link(<<"SRC", opt, &b)
|
||
#{headers}
|
||
/*top*/
|
||
#{MAIN_DOES_NOTHING}
|
||
int t() { #{call}; return 0; }
|
||
int t() { #{func}(); return 0; }
|
||
SRC
|
||
end
|
||
end
|
||
# You should use +have_var+ rather than +try_var+.
|
||
def try_var(var, headers = nil, opt = "", &b)
|
||
headers = cpp_include(headers)
|
||
try_compile(<<"SRC", opt, &b)
|
||
# You should use +have_var+ rather than +try_var+.
|
||
def try_var(var, headers = nil, opt = "", &b)
|
||
headers = cpp_include(headers)
|
||
try_compile(<<"SRC", opt, &b)
|
||
#{headers}
|
||
/*top*/
|
||
#{MAIN_DOES_NOTHING}
|
||
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
||
SRC
|
||
end
|
||
end
|
||
# Returns whether or not the +src+ can be preprocessed with the C preprocessor and
|
||
# matches with +pat+.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+pat+] a Regexp or a String
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains preprocessor options
|
||
#
|
||
# Note:
|
||
# When pat is a Regexp the matching will be checked in process,
|
||
# otherwise egrep(1) will be invoked to check it.
|
||
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)
|
||
# Returns whether or not the +src+ can be preprocessed with the C preprocessor and
|
||
# matches with +pat+.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+pat+] a Regexp or a String
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains preprocessor options
|
||
#
|
||
# Note:
|
||
# When pat is a Regexp the matching will be checked in process,
|
||
# otherwise egrep(1) will be invoked to check it.
|
||
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)
|
||
end
|
||
end
|
||
end
|
||
ensure
|
||
rm_f "conftest*"
|
||
log_src(src)
|
||
end
|
||
ensure
|
||
rm_f "conftest*"
|
||
log_src(src)
|
||
end
|
||
# This is used internally by the have_macro? method.
|
||
def macro_defined?(macro, src, opt = "", &b)
|
||
src = src.sub(/[^\n]\z/, "\\&\n")
|
||
try_compile(src + <<"SRC", opt, &b)
|
||
# This is used internally by the have_macro? method.
|
||
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
|
||
SRC
|
||
end
|
||
end
|
||
# Returns whether or not
|
||
# * the +src+ can be compiled as a C source,
|
||
# * the result object can be linked with its depending libraries successfully,
|
||
# * the linked file can be invoked as an executable
|
||
# * and the executable exits successfully
|
||
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
|
||
# are also passed to the linker.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains linker options
|
||
#
|
||
# @return true when the executable exits successfully, false when it fails, or
|
||
# nil when preprocessing, compilation or link fails.
|
||
def try_run(src, opt = "", &b)
|
||
if try_link0(src, opt, &b)
|
||
xsystem("./conftest")
|
||
else
|
||
nil
|
||
# Returns whether or not
|
||
# * the +src+ can be compiled as a C source,
|
||
# * the result object can be linked with its depending libraries successfully,
|
||
# * the linked file can be invoked as an executable
|
||
# * and the executable exits successfully
|
||
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
|
||
# are also passed to the linker.
|
||
#
|
||
# If a block given, it is called with the source before compilation. You can
|
||
# modify the source in the block.
|
||
#
|
||
# [+src+] a String which contains a C source
|
||
# [+opt+] a String which contains linker options
|
||
#
|
||
# @return true when the executable exits successfully, false when it fails, or
|
||
# nil when preprocessing, compilation or link fails.
|
||
def try_run(src, opt = "", &b)
|
||
if try_link0(src, opt, &b)
|
||
xsystem("./conftest")
|
||
else
|
||
nil
|
||
end
|
||
ensure
|
||
rm_f "conftest*"
|
||
end
|
||
ensure
|
||
rm_f "conftest*"
|
||
end
|
||
def install_files(mfile, ifiles, map = nil, srcprefix = nil)
|
||
ifiles or return
|
||
ifiles.empty? and return
|
||
srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
|
||
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
|
||
def install_files(mfile, ifiles, map = nil, srcprefix = nil)
|
||
ifiles or return
|
||
ifiles.empty? and return
|
||
srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
|
||
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
|
||
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
|
||
dirs
|
||
end
|
||
dirs
|
||
end
|
||
def install_rb(mfile, dest, srcdir = nil)
|
||
install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
|
||
end
|
||
def install_rb(mfile, dest, srcdir = nil)
|
||
install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
|
||
end
|
||
def append_library(libs, lib) # :no-doc:
|
||
format(LIBARG, lib) + " " + libs
|
||
end
|
||
def append_library(libs, lib) # :no-doc:
|
||
format(LIBARG, lib) + " " + libs
|
||
end
|
||
def message(*s)
|
||
unless Logging.quiet and not $VERBOSE
|
||
printf(*s)
|
||
$stdout.flush
|
||
def message(*s)
|
||
unless Logging.quiet and not $VERBOSE
|
||
printf(*s)
|
||
$stdout.flush
|
||
end
|
||
end
|
||
end
|
||
# This emits a string to stdout that allows users to see the results of the
|
||
# various have* and find* methods as they are tested.
|
||
#
|
||
# Internal use only.
|
||
#
|
||
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
|
||
# This emits a string to stdout that allows users to see the results of the
|
||
# various have* and find* methods as they are tested.
|
||
#
|
||
# Internal use only.
|
||
#
|
||
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 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 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?
|