Project

General

Profile

Feature #5658 ยป mkmf.rb.in_a_module.2.patch

Corrected patch - drbrain (Eric Hodel), 11/23/2011 07:46 AM

View differences:

lib/mkmf.rb (working copy)
6 6
require 'fileutils'
7 7
require 'shellwords'
8 8

  
9
CONFIG = RbConfig::MAKEFILE_CONFIG
10
ORIG_LIBPATH = ENV['LIB']
11

  
12
C_EXT = %w[c m]
13
CXX_EXT = %w[cc mm cxx cpp]
14
if File::FNM_SYSCASE.zero?
15
  CXX_EXT.concat(%w[C])
16
end
17
SRC_EXT = C_EXT + CXX_EXT
18
$static = nil
19
$config_h = '$(arch_hdrdir)/ruby/config.h'
20
$default_static = $static
21

  
22
unless defined? $configure_args
23
  $configure_args = {}
24
  args = CONFIG["configure_args"]
25
  if ENV["CONFIGURE_ARGS"]
26
    args << " " << ENV["CONFIGURE_ARGS"]
27
  end
28
  for arg in Shellwords::shellwords(args)
29
    arg, val = arg.split('=', 2)
30
    next unless arg
31
    arg.tr!('_', '-')
32
    if arg.sub!(/^(?!--)/, '--')
33
      val or next
34
      arg.downcase!
35
    end
36
    next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
37
    $configure_args[arg] = val || true
38
  end
39
  for arg in ARGV
40
    arg, val = arg.split('=', 2)
41
    next unless arg
42
    arg.tr!('_', '-')
43
    if arg.sub!(/^(?!--)/, '--')
44
      val or next
45
      arg.downcase!
46
    end
47
    $configure_args[arg] = val || true
48
  end
49
end
50

  
51
$libdir = CONFIG["libdir"]
52
$rubylibdir = CONFIG["rubylibdir"]
53
$archdir = CONFIG["archdir"]
54
$sitedir = CONFIG["sitedir"]
55
$sitelibdir = CONFIG["sitelibdir"]
56
$sitearchdir = CONFIG["sitearchdir"]
57
$vendordir = CONFIG["vendordir"]
58
$vendorlibdir = CONFIG["vendorlibdir"]
59
$vendorarchdir = CONFIG["vendorarchdir"]
60

  
61
$mswin = /mswin/ =~ RUBY_PLATFORM
62
$bccwin = /bccwin/ =~ RUBY_PLATFORM
63
$mingw = /mingw/ =~ RUBY_PLATFORM
64
$cygwin = /cygwin/ =~ RUBY_PLATFORM
65
$netbsd = /netbsd/ =~ RUBY_PLATFORM
66
$os2 = /os2/ =~ RUBY_PLATFORM
67
$beos = /beos/ =~ RUBY_PLATFORM
68
$haiku = /haiku/ =~ RUBY_PLATFORM
69
$solaris = /solaris/ =~ RUBY_PLATFORM
70
$universal = /universal/ =~ RUBY_PLATFORM
71
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
72

  
73 9
# :stopdoc:
74

  
75
def config_string(key, config = CONFIG)
76
  s = config[key] and !s.empty? and block_given? ? yield(s) : s
77
end
78

  
79
def dir_re(dir)
80
  Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
81
end
82

  
83
def relative_from(path, base)
84
  dir = File.join(path, "")
85
  if File.expand_path(dir) == File.expand_path(dir, base)
86
    path
87
  else
88
    File.join(base, path)
89
  end
90
end
91

  
92
INSTALL_DIRS = [
93
  [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
94
  [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
95
  [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
96
  [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
97
  [dir_re('archdir'), "$(RUBYARCHDIR)"],
98
  [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
99
  [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
100
  [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
101
  [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
102
  [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"],
103
  [dir_re('sitehdrdir'), "$(SITEHDRDIR)"],
104
  [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"],
105
  [dir_re('bindir'), "$(BINDIR)"],
106
]
107

  
108
def install_dirs(target_prefix = nil)
109
  if $extout
110
    dirs = [
111
      ['BINDIR',        '$(extout)/bin'],
112
      ['RUBYCOMMONDIR', '$(extout)/common'],
113
      ['RUBYLIBDIR',    '$(RUBYCOMMONDIR)$(target_prefix)'],
114
      ['RUBYARCHDIR',   '$(extout)/$(arch)$(target_prefix)'],
115
      ['HDRDIR',        '$(extout)/include/ruby$(target_prefix)'],
116
      ['ARCHHDRDIR',    '$(extout)/include/$(arch)/ruby$(target_prefix)'],
117
      ['extout',        "#$extout"],
118
      ['extout_prefix', "#$extout_prefix"],
119
    ]
120
  elsif $extmk
121
    dirs = [
122
      ['BINDIR',        '$(bindir)'],
123
      ['RUBYCOMMONDIR', '$(rubylibdir)'],
124
      ['RUBYLIBDIR',    '$(rubylibdir)$(target_prefix)'],
125
      ['RUBYARCHDIR',   '$(archdir)$(target_prefix)'],
126
      ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
127
      ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
128
    ]
129
  elsif $configure_args.has_key?('--vendor')
130
    dirs = [
131
      ['BINDIR',        '$(bindir)'],
132
      ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
133
      ['RUBYLIBDIR',    '$(vendorlibdir)$(target_prefix)'],
134
      ['RUBYARCHDIR',   '$(vendorarchdir)$(target_prefix)'],
135
      ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
136
      ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
137
    ]
138
  else
139
    dirs = [
140
      ['BINDIR',        '$(bindir)'],
141
      ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
142
      ['RUBYLIBDIR',    '$(sitelibdir)$(target_prefix)'],
143
      ['RUBYARCHDIR',   '$(sitearchdir)$(target_prefix)'],
144
      ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
145
      ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
146
    ]
147
  end
148
  dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
149
  dirs
150
end
151

  
152
def map_dir(dir, map = nil)
153
  map ||= INSTALL_DIRS
154
  map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)}
155
end
156

  
157
topdir = File.dirname(File.dirname(__FILE__))
158
path = File.expand_path($0)
159
$extmk = path[0, topdir.size+1] == topdir+"/"
160
$extmk &&= %r"\A(?:ext|enc|tool|test(?:/.+)?)\z" =~ File.dirname(path[topdir.size+1..-1])
161
$extmk &&= true
162
if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
163
  $topdir = $hdrdir
164
  $top_srcdir = $hdrdir
165
  $arch_hdrdir = $hdrdir + "/$(arch)"
166
elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include")  + "/ruby.h")
167
  $topdir ||= RbConfig::CONFIG["topdir"]
168
  $arch_hdrdir = "$(extout)/include/$(arch)"
169
else
170
  abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
171
end
172

  
173
OUTFLAG = CONFIG['OUTFLAG']
174
COUTFLAG = CONFIG['COUTFLAG']
175
CPPOUTFILE = CONFIG['CPPOUTFILE']
176

  
177
CONFTEST_C = "conftest.c".freeze
178

  
179 10
class String
180 11
  # Wraps a string in escaped quotes if it contains whitespace.
181 12
  def quote
......
195 26
    self[/\A[^()]+/]
196 27
  end
197 28
end
29

  
198 30
class Array
199 31
  # Wraps all strings in escaped quotes if they contain whitespace.
200 32
  def quote
201 33
    map {|s| s.quote}
202 34
  end
203 35
end
36
# :startdoc:
204 37

  
205
def rm_f(*files)
206
  opt = (Hash === files.last ? [files.pop] : [])
207
  FileUtils.rm_f(Dir[*files.flatten], *opt)
208
end
38
module MakeMakefile
209 39

  
210
def rm_rf(*files)
211
  opt = (Hash === files.last ? [files.pop] : [])
212
  FileUtils.rm_rf(Dir[*files.flatten], *opt)
213
end
40
  CONFIG = RbConfig::MAKEFILE_CONFIG
41
  ORIG_LIBPATH = ENV['LIB']
214 42

  
215
# Returns time stamp of the +target+ file if it exists and is newer
216
# than or equal to all of +times+.
217
def modified?(target, times)
218
  (t = File.mtime(target)) rescue return nil
219
  Array === times or times = [times]
220
  t if times.all? {|n| n <= t}
221
end
43
  C_EXT = %w[c m]
44
  CXX_EXT = %w[cc mm cxx cpp]
45
  if File::FNM_SYSCASE.zero?
46
    CXX_EXT.concat(%w[C])
47
  end
48
  SRC_EXT = C_EXT + CXX_EXT
49
  $static = nil
50
  $config_h = '$(arch_hdrdir)/ruby/config.h'
51
  $default_static = $static
52

  
53
  unless defined? $configure_args
54
    $configure_args = {}
55
    args = CONFIG["configure_args"]
56
    if ENV["CONFIGURE_ARGS"]
57
      args << " " << ENV["CONFIGURE_ARGS"]
58
    end
59
    for arg in Shellwords::shellwords(args)
60
      arg, val = arg.split('=', 2)
61
      next unless arg
62
      arg.tr!('_', '-')
63
      if arg.sub!(/^(?!--)/, '--')
64
        val or next
65
        arg.downcase!
66
      end
67
      next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
68
      $configure_args[arg] = val || true
69
    end
70
    for arg in ARGV
71
      arg, val = arg.split('=', 2)
72
      next unless arg
73
      arg.tr!('_', '-')
74
      if arg.sub!(/^(?!--)/, '--')
75
        val or next
76
        arg.downcase!
77
      end
78
      $configure_args[arg] = val || true
79
    end
80
  end
81

  
82
  $libdir = CONFIG["libdir"]
83
  $rubylibdir = CONFIG["rubylibdir"]
84
  $archdir = CONFIG["archdir"]
85
  $sitedir = CONFIG["sitedir"]
86
  $sitelibdir = CONFIG["sitelibdir"]
87
  $sitearchdir = CONFIG["sitearchdir"]
88
  $vendordir = CONFIG["vendordir"]
89
  $vendorlibdir = CONFIG["vendorlibdir"]
90
  $vendorarchdir = CONFIG["vendorarchdir"]
91

  
92
  $mswin = /mswin/ =~ RUBY_PLATFORM
93
  $bccwin = /bccwin/ =~ RUBY_PLATFORM
94
  $mingw = /mingw/ =~ RUBY_PLATFORM
95
  $cygwin = /cygwin/ =~ RUBY_PLATFORM
96
  $netbsd = /netbsd/ =~ RUBY_PLATFORM
97
  $os2 = /os2/ =~ RUBY_PLATFORM
98
  $beos = /beos/ =~ RUBY_PLATFORM
99
  $haiku = /haiku/ =~ RUBY_PLATFORM
100
  $solaris = /solaris/ =~ RUBY_PLATFORM
101
  $universal = /universal/ =~ RUBY_PLATFORM
102
  $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
103

  
104
  # :stopdoc:
105

  
106
  def config_string(key, config = CONFIG)
107
    s = config[key] and !s.empty? and block_given? ? yield(s) : s
108
  end
109
  module_function :config_string
110

  
111
  def dir_re(dir)
112
    Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
113
  end
114
  module_function :dir_re
115

  
116
  def relative_from(path, base)
117
    dir = File.join(path, "")
118
    if File.expand_path(dir) == File.expand_path(dir, base)
119
      path
120
    else
121
      File.join(base, path)
122
    end
123
  end
124

  
125
  INSTALL_DIRS = [
126
    [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
127
    [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
128
    [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
129
    [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
130
    [dir_re('archdir'), "$(RUBYARCHDIR)"],
131
    [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
132
    [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
133
    [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
134
    [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
135
    [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"],
136
    [dir_re('sitehdrdir'), "$(SITEHDRDIR)"],
137
    [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"],
138
    [dir_re('bindir'), "$(BINDIR)"],
139
  ]
222 140

  
223
def merge_libs(*libs)
224
  libs.inject([]) do |x, y|
225
    xy = x & y
226
    xn = yn = 0
227
    y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
228
    y.each_with_index do |v, yi|
229
      if xy.include?(v)
230
        xi = [x.index(v), xn].max()
231
        x[xi, 1] = y[yn..yi]
232
        xn, yn = xi + (yi - yn + 1), yi + 1
141
  def install_dirs(target_prefix = nil)
142
    if $extout
143
      dirs = [
144
        ['BINDIR',        '$(extout)/bin'],
145
        ['RUBYCOMMONDIR', '$(extout)/common'],
146
        ['RUBYLIBDIR',    '$(RUBYCOMMONDIR)$(target_prefix)'],
147
        ['RUBYARCHDIR',   '$(extout)/$(arch)$(target_prefix)'],
148
        ['HDRDIR',        '$(extout)/include/ruby$(target_prefix)'],
149
        ['ARCHHDRDIR',    '$(extout)/include/$(arch)/ruby$(target_prefix)'],
150
        ['extout',        "#$extout"],
151
        ['extout_prefix', "#$extout_prefix"],
152
      ]
153
    elsif $extmk
154
      dirs = [
155
        ['BINDIR',        '$(bindir)'],
156
        ['RUBYCOMMONDIR', '$(rubylibdir)'],
157
        ['RUBYLIBDIR',    '$(rubylibdir)$(target_prefix)'],
158
        ['RUBYARCHDIR',   '$(archdir)$(target_prefix)'],
159
        ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
160
        ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
161
      ]
162
    elsif $configure_args.has_key?('--vendor')
163
      dirs = [
164
        ['BINDIR',        '$(bindir)'],
165
        ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
166
        ['RUBYLIBDIR',    '$(vendorlibdir)$(target_prefix)'],
167
        ['RUBYARCHDIR',   '$(vendorarchdir)$(target_prefix)'],
168
        ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
169
        ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
170
      ]
171
    else
172
      dirs = [
173
        ['BINDIR',        '$(bindir)'],
174
        ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
175
        ['RUBYLIBDIR',    '$(sitelibdir)$(target_prefix)'],
176
        ['RUBYARCHDIR',   '$(sitearchdir)$(target_prefix)'],
177
        ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
178
        ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
179
      ]
180
    end
181
    dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
182
    dirs
183
  end
184

  
185
  def map_dir(dir, map = nil)
186
    map ||= INSTALL_DIRS
187
    map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)}
188
  end
189

  
190
  topdir = File.dirname(File.dirname(__FILE__))
191
  path = File.expand_path($0)
192
  $extmk = path[0, topdir.size+1] == topdir+"/"
193
  $extmk &&= %r"\A(?:ext|enc|tool|test(?:/.+)?)\z" =~ File.dirname(path[topdir.size+1..-1])
194
  $extmk &&= true
195
  if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
196
    $topdir = $hdrdir
197
    $top_srcdir = $hdrdir
198
    $arch_hdrdir = $hdrdir + "/$(arch)"
199
  elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include")  + "/ruby.h")
200
    $topdir ||= RbConfig::CONFIG["topdir"]
201
    $arch_hdrdir = "$(extout)/include/$(arch)"
202
  else
203
    abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
204
  end
205

  
206
  OUTFLAG = CONFIG['OUTFLAG']
207
  COUTFLAG = CONFIG['COUTFLAG']
208
  CPPOUTFILE = CONFIG['CPPOUTFILE']
209

  
210
  CONFTEST_C = "conftest.c".freeze
211

  
212
  def rm_f(*files)
213
    opt = (Hash === files.last ? [files.pop] : [])
214
    FileUtils.rm_f(Dir[*files.flatten], *opt)
215
  end
216

  
217
  def rm_rf(*files)
218
    opt = (Hash === files.last ? [files.pop] : [])
219
    FileUtils.rm_rf(Dir[*files.flatten], *opt)
220
  end
221

  
222
  # Returns time stamp of the +target+ file if it exists and is newer
223
  # than or equal to all of +times+.
224
  def modified?(target, times)
225
    (t = File.mtime(target)) rescue return nil
226
    Array === times or times = [times]
227
    t if times.all? {|n| n <= t}
228
  end
229

  
230
  def merge_libs(*libs)
231
    libs.inject([]) do |x, y|
232
      xy = x & y
233
      xn = yn = 0
234
      y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
235
      y.each_with_index do |v, yi|
236
        if xy.include?(v)
237
          xi = [x.index(v), xn].max()
238
          x[xi, 1] = y[yn..yi]
239
          xn, yn = xi + (yi - yn + 1), yi + 1
240
        end
233 241
      end
242
      x.concat(y[yn..-1] || [])
234 243
    end
235
    x.concat(y[yn..-1] || [])
236 244
  end
237
end
238 245

  
239
# This is a custom logging module. It generates an mkmf.log file when you
240
# run your extconf.rb script. This can be useful for debugging unexpected
241
# failures.
242
#
243
# This module and its associated methods are meant for internal use only.
244
#
245
module Logging
246
  @log = nil
247
  @logfile = 'mkmf.log'
248
  @orgerr = $stderr.dup
249
  @orgout = $stdout.dup
250
  @postpone = 0
251
  @quiet = $extmk
252

  
253
  def self::log_open
254
    @log ||= File::open(@logfile, 'wb')
255
    @log.sync = true
256
  end
257

  
258
  def self::open
259
    log_open
260
    $stderr.reopen(@log)
261
    $stdout.reopen(@log)
262
    yield
263
  ensure
264
    $stderr.reopen(@orgerr)
265
    $stdout.reopen(@orgout)
266
  end
246
  # This is a custom logging module. It generates an mkmf.log file when you
247
  # run your extconf.rb script. This can be useful for debugging unexpected
248
  # failures.
249
  #
250
  # This module and its associated methods are meant for internal use only.
251
  #
252
  module Logging
253
    @log = nil
254
    @logfile = 'mkmf.log'
255
    @orgerr = $stderr.dup
256
    @orgout = $stdout.dup
257
    @postpone = 0
258
    @quiet = $extmk
259

  
260
    def self::log_open
261
      @log ||= File::open(@logfile, 'wb')
262
      @log.sync = true
263
    end
264

  
265
    def self::open
266
      log_open
267
      $stderr.reopen(@log)
268
      $stdout.reopen(@log)
269
      yield
270
    ensure
271
      $stderr.reopen(@orgerr)
272
      $stdout.reopen(@orgout)
273
    end
267 274

  
268
  def self::message(*s)
269
    log_open
270
    @log.printf(*s)
271
  end
275
    def self::message(*s)
276
      log_open
277
      @log.printf(*s)
278
    end
272 279

  
273
  def self::logfile file
274
    @logfile = file
275
    log_close
276
  end
280
    def self::logfile file
281
      @logfile = file
282
      log_close
283
    end
277 284

  
278
  def self::log_close
279
    if @log and not @log.closed?
280
      @log.flush
281
      @log.close
282
      @log = nil
285
    def self::log_close
286
      if @log and not @log.closed?
287
        @log.flush
288
        @log.close
289
        @log = nil
290
      end
283 291
    end
284
  end
285 292

  
286
  def self::postpone
287
    tmplog = "mkmftmp#{@postpone += 1}.log"
288
    open do
289
      log, *save = @log, @logfile, @orgout, @orgerr
290
      @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
291
      begin
292
        log.print(open {yield @log})
293
      ensure
294
        @log.close if @log and not @log.closed?
295
        File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
296
        @log, @logfile, @orgout, @orgerr = log, *save
297
        @postpone -= 1
298
        rm_f tmplog
293
    def self::postpone
294
      tmplog = "mkmftmp#{@postpone += 1}.log"
295
      open do
296
        log, *save = @log, @logfile, @orgout, @orgerr
297
        @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
298
        begin
299
          log.print(open {yield @log})
300
        ensure
301
          @log.close if @log and not @log.closed?
302
          File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
303
          @log, @logfile, @orgout, @orgerr = log, *save
304
          @postpone -= 1
305
          rm_f tmplog
306
        end
299 307
      end
300 308
    end
301
  end
302 309

  
303
  class << self
304
    attr_accessor :quiet
310
    class << self
311
      attr_accessor :quiet
312
    end
305 313
  end
306
end
307 314

  
308
def xsystem command, opts = nil
309
  varpat = /\$\((\w+)\)|\$\{(\w+)\}/
310
  if varpat =~ command
311
    vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
312
    command = command.dup
313
    nil while command.gsub!(varpat) {vars[$1||$2]}
314
  end
315
  Logging::open do
316
    puts command.quote
317
    if opts and opts[:werror]
318
      result = nil
319
      Logging.postpone do |log|
320
        result = (system(command) and File.zero?(log.path))
321
        ""
315
  def xsystem command, opts = nil
316
    varpat = /\$\((\w+)\)|\$\{(\w+)\}/
317
    if varpat =~ command
318
      vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
319
      command = command.dup
320
      nil while command.gsub!(varpat) {vars[$1||$2]}
321
    end
322
    Logging::open do
323
      puts command.quote
324
      if opts and opts[:werror]
325
        result = nil
326
        Logging.postpone do |log|
327
          result = (system(command) and File.zero?(log.path))
328
          ""
329
        end
330
        result
331
      else
332
        system(command)
322 333
      end
323
      result
324
    else
325
      system(command)
326 334
    end
327 335
  end
328
end
329 336

  
330
def xpopen command, *mode, &block
331
  Logging::open do
332
    case mode[0]
333
    when nil, /^r/
334
      puts "#{command} |"
335
    else
336
      puts "| #{command}"
337
  def xpopen command, *mode, &block
338
    Logging::open do
339
      case mode[0]
340
      when nil, /^r/
341
        puts "#{command} |"
342
      else
343
        puts "| #{command}"
344
      end
345
      IO.popen(command, *mode, &block)
337 346
    end
338
    IO.popen(command, *mode, &block)
339 347
  end
340
end
341 348

  
342
def log_src(src)
343
  src = src.split(/^/)
344
  fmt = "%#{src.size.to_s.size}d: %s"
345
  Logging::message <<"EOM"
349
  def log_src(src)
350
    src = src.split(/^/)
351
    fmt = "%#{src.size.to_s.size}d: %s"
352
    Logging::message <<"EOM"
346 353
checked program was:
347 354
/* begin */
348 355
EOM
349
  src.each_with_index {|line, no| Logging::message fmt, no+1, line}
350
  Logging::message <<"EOM"
356
    src.each_with_index {|line, no| Logging::message fmt, no+1, line}
357
    Logging::message <<"EOM"
351 358
/* end */
352 359

  
353 360
EOM
354
end
361
  end
355 362

  
356
def create_tmpsrc(src)
357
  src = "#{COMMON_HEADERS}\n#{src}"
358
  src = yield(src) if block_given?
359
  src.gsub!(/[ \t]+$/, '')
360
  src.gsub!(/\A\n+|^\n+$/, '')
361
  src.sub!(/[^\n]\z/, "\\&\n")
362
  count = 0
363
  begin
364
    open(CONFTEST_C, "wb") do |cfile|
365
      cfile.print src
366
    end
367
  rescue Errno::EACCES
368
    if (count += 1) < 5
369
      sleep 0.2
370
      retry
363
  def create_tmpsrc(src)
364
    src = "#{COMMON_HEADERS}\n#{src}"
365
    src = yield(src) if block_given?
366
    src.gsub!(/[ \t]+$/, '')
367
    src.gsub!(/\A\n+|^\n+$/, '')
368
    src.sub!(/[^\n]\z/, "\\&\n")
369
    count = 0
370
    begin
371
      open(CONFTEST_C, "wb") do |cfile|
372
        cfile.print src
373
      end
374
    rescue Errno::EACCES
375
      if (count += 1) < 5
376
        sleep 0.2
377
        retry
378
      end
371 379
    end
380
    src
372 381
  end
373
  src
374
end
375 382

  
376
def have_devel?
377
  unless defined? $have_devel
378
    $have_devel = true
379
    $have_devel = try_link(MAIN_DOES_NOTHING)
383
  def have_devel?
384
    unless defined? $have_devel
385
      $have_devel = true
386
      $have_devel = try_link(MAIN_DOES_NOTHING)
387
    end
388
    $have_devel
380 389
  end
381
  $have_devel
382
end
383 390

  
384
def try_do(src, command, *opts, &b)
385
  unless have_devel?
386
    raise <<MSG
391
  def try_do(src, command, *opts, &b)
392
    unless have_devel?
393
      raise <<MSG
387 394
The compiler failed to generate an executable file.
388 395
You have to install development tools first.
389 396
MSG
397
    end
398
    begin
399
      src = create_tmpsrc(src, &b)
400
      xsystem(command, *opts)
401
    ensure
402
      log_src(src)
403
      rm_rf 'conftest.dSYM'
404
    end
390 405
  end
391
  begin
392
    src = create_tmpsrc(src, &b)
393
    xsystem(command, *opts)
394
  ensure
395
    log_src(src)
396
    rm_rf 'conftest.dSYM'
397
  end
398
end
399

  
400
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
401
  librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
402
  conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
403
                                'src' => "#{CONFTEST_C}",
404
                                'arch_hdrdir' => $arch_hdrdir.quote,
405
                                'top_srcdir' => $top_srcdir.quote,
406
                                'INCFLAGS' => "#$INCFLAGS",
407
                                'CPPFLAGS' => "#$CPPFLAGS",
408
                                'CFLAGS' => "#$CFLAGS",
409
                                'ARCH_FLAG' => "#$ARCH_FLAG",
410
                                'LDFLAGS' => "#$LDFLAGS #{ldflags}",
411
                                'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
412
                                'LIBS' => "#{librubyarg} #{opt} #$LIBS")
413
  conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
414
  RbConfig::expand(TRY_LINK.dup, conf)
415
end
416 406

  
417
def cc_command(opt="")
418
  conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
419
                                'arch_hdrdir' => $arch_hdrdir.quote,
420
                                'top_srcdir' => $top_srcdir.quote)
421
  RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
422
                   conf)
423
end
424

  
425
def cpp_command(outfile, opt="")
426
  conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
427
                                'arch_hdrdir' => $arch_hdrdir.quote,
428
                                'top_srcdir' => $top_srcdir.quote)
429
  if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
430
    conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
407
  def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
408
    librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
409
    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
410
                                  'src' => "#{CONFTEST_C}",
411
                                  'arch_hdrdir' => $arch_hdrdir.quote,
412
                                  'top_srcdir' => $top_srcdir.quote,
413
                                  'INCFLAGS' => "#$INCFLAGS",
414
                                  'CPPFLAGS' => "#$CPPFLAGS",
415
                                  'CFLAGS' => "#$CFLAGS",
416
                                  'ARCH_FLAG' => "#$ARCH_FLAG",
417
                                  'LDFLAGS' => "#$LDFLAGS #{ldflags}",
418
                                  'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
419
                                  'LIBS' => "#{librubyarg} #{opt} #$LIBS")
420
    conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
421
    RbConfig::expand(TRY_LINK.dup, conf)
422
  end
423

  
424
  def cc_command(opt="")
425
    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
426
                                  'arch_hdrdir' => $arch_hdrdir.quote,
427
                                  'top_srcdir' => $top_srcdir.quote)
428
    RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
429
                     conf)
430
  end
431

  
432
  def cpp_command(outfile, opt="")
433
    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
434
                                  'arch_hdrdir' => $arch_hdrdir.quote,
435
                                  'top_srcdir' => $top_srcdir.quote)
436
    if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
437
      conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
438
    end
439
    RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
440
                     conf)
441
  end
442

  
443
  def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
444
    libpath.map{|x|
445
      case x
446
      when "$(topdir)", /\A\./
447
        LIBPATHFLAG
448
      else
449
        LIBPATHFLAG+RPATHFLAG
450
      end % x.quote
451
    }.join
431 452
  end
432
  RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
433
                   conf)
434
end
435 453

  
436
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
437
  libpath.map{|x|
438
    case x
439
    when "$(topdir)", /\A\./
440
      LIBPATHFLAG
441
    else
442
      LIBPATHFLAG+RPATHFLAG
443
    end % x.quote
444
  }.join
445
end
446

  
447
def with_werror(opt, opts = nil)
448
  if opts
449
    if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
450
      (opts = opts.dup).delete(:werror)
454
  def with_werror(opt, opts = nil)
455
    if opts
456
      if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
457
        (opts = opts.dup).delete(:werror)
458
      end
459
      yield(opt, opts)
460
    else
461
      yield(opt)
451 462
    end
452
    yield(opt, opts)
453
  else
454
    yield(opt)
455 463
  end
456
end
457 464

  
458
# :nodoc:
459
def try_link0(src, opt="", *opts, &b)
460
  cmd = link_command("", opt)
461
  if $universal
462
    require 'tmpdir'
463
    Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
464
      begin
465
        ENV["TMPDIR"] = tmpdir
466
        try_do(src, cmd, *opts, &b)
467
      ensure
468
        ENV["TMPDIR"] = oldtmpdir
465
  # :nodoc:
466
  def try_link0(src, opt="", *opts, &b)
467
    cmd = link_command("", opt)
468
    if $universal
469
      require 'tmpdir'
470
      Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
471
        begin
472
          ENV["TMPDIR"] = tmpdir
473
          try_do(src, cmd, *opts, &b)
474
        ensure
475
          ENV["TMPDIR"] = oldtmpdir
476
        end
469 477
      end
478
    else
479
      try_do(src, cmd, *opts, &b)
470 480
    end
471
  else
472
    try_do(src, cmd, *opts, &b)
473 481
  end
474
end
475 482

  
476
# Returns whether or not the +src+ can be compiled as a C source and
477
# linked with its depending libraries successfully.
478
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
479
# are also passed to the linker.
480
#
481
# If a block given, it is called with the source before compilation. You can
482
# modify the source in the block.
483
#
484
# [+src+] a String which contains a C source
485
# [+opt+] a String which contains linker options
486
def try_link(src, opt="", *opts, &b)
487
  try_link0(src, opt, *opts, &b)
488
ensure
489
  rm_f "conftest*", "c0x32*"
490
end
483
  # Returns whether or not the +src+ can be compiled as a C source and
484
  # linked with its depending libraries successfully.
485
  # +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
486
  # are also passed to the linker.
487
  #
488
  # If a block given, it is called with the source before compilation. You can
489
  # modify the source in the block.
490
  #
491
  # [+src+] a String which contains a C source
492
  # [+opt+] a String which contains linker options
493
  def try_link(src, opt="", *opts, &b)
494
    try_link0(src, opt, *opts, &b)
495
  ensure
496
    rm_f "conftest*", "c0x32*"
497
  end
491 498

  
492
# Returns whether or not the +src+ can be compiled as a C source.
493
# +opt+ is passed to the C compiler as options. Note that +$CFLAGS+ is
494
# also passed to the compiler.
495
#
496
# If a block given, it is called with the source before compilation. You can
497
# modify the source in the block.
498
#
499
# [+src+] a String which contains a C source
500
# [+opt+] a String which contains compiler options
501
def try_compile(src, opt="", *opts, &b)
502
  with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)}
503
ensure
504
  rm_f "conftest*"
505
end
499
  # Returns whether or not the +src+ can be compiled as a C source.
500
  # +opt+ is passed to the C compiler as options. Note that +$CFLAGS+ is
501
  # also passed to the compiler.
502
  #
503
  # If a block given, it is called with the source before compilation. You can
504
  # modify the source in the block.
505
  #
506
  # [+src+] a String which contains a C source
507
  # [+opt+] a String which contains compiler options
508
  def try_compile(src, opt="", *opts, &b)
509
    with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)}
510
  ensure
511
    rm_f "conftest*"
512
  end
506 513

  
507
# Returns whether or not the +src+ can be preprocessed with the C preprocessor.
508
# +opt+ is passed to the preprocessor as options. Note that +$CFLAGS+ is
509
# also passed to the preprocessor.
510
#
511
# If a block given, it is called with the source before preprocessing. You can
512
# modify the source in the block.
513
#
514
# [+src+] a String which contains a C source
515
# [+opt+] a String which contains preprocessor options
516
def try_cpp(src, opt="", *opts, &b)
517
  try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b)
518
ensure
519
  rm_f "conftest*"
520
end
514
  # Returns whether or not the +src+ can be preprocessed with the C preprocessor.
515
  # +opt+ is passed to the preprocessor as options. Note that +$CFLAGS+ is
516
  # also passed to the preprocessor.
517
  #
518
  # If a block given, it is called with the source before preprocessing. You can
519
  # modify the source in the block.
520
  #
521
  # [+src+] a String which contains a C source
522
  # [+opt+] a String which contains preprocessor options
523
  def try_cpp(src, opt="", *opts, &b)
524
    try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b)
525
  ensure
526
    rm_f "conftest*"
527
  end
521 528

  
522
class Object
523 529
  alias_method :try_header, (config_string('try_header') || :try_cpp)
524
end
525 530

  
526
def cpp_include(header)
527
  if header
528
    header = [header] unless header.kind_of? Array
529
    header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
530
  else
531
    ""
531
  def cpp_include(header)
532
    if header
533
      header = [header] unless header.kind_of? Array
534
      header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
535
    else
536
      ""
537
    end
532 538
  end
533
end
534 539

  
535
def with_cppflags(flags)
536
  cppflags = $CPPFLAGS
537
  $CPPFLAGS = flags
538
  ret = yield
539
ensure
540
  $CPPFLAGS = cppflags unless ret
541
end
540
  def with_cppflags(flags)
541
    cppflags = $CPPFLAGS
542
    $CPPFLAGS = flags
543
    ret = yield
544
  ensure
545
    $CPPFLAGS = cppflags unless ret
546
  end
542 547

  
543
def with_cflags(flags)
544
  cflags = $CFLAGS
545
  $CFLAGS = flags
546
  ret = yield
547
ensure
548
  $CFLAGS = cflags unless ret
549
end
548
  def with_cflags(flags)
549
    cflags = $CFLAGS
550
    $CFLAGS = flags
551
    ret = yield
552
  ensure
553
    $CFLAGS = cflags unless ret
554
  end
550 555

  
551
def with_ldflags(flags)
552
  ldflags = $LDFLAGS
553
  $LDFLAGS = flags
554
  ret = yield
555
ensure
556
  $LDFLAGS = ldflags unless ret
557
end
556
  def with_ldflags(flags)
557
    ldflags = $LDFLAGS
558
    $LDFLAGS = flags
559
    ret = yield
560
  ensure
561
    $LDFLAGS = ldflags unless ret
562
  end
558 563

  
559
def try_static_assert(expr, headers = nil, opt = "", &b)
560
  headers = cpp_include(headers)
561
  try_compile(<<SRC, opt, &b)
564
  def try_static_assert(expr, headers = nil, opt = "", &b)
565
    headers = cpp_include(headers)
566
    try_compile(<<SRC, opt, &b)
562 567
#{headers}
563 568
/*top*/
564 569
int conftest_const[(#{expr}) ? 1 : -1];
565 570
SRC
566
end
571
  end
567 572

  
568
def try_constant(const, headers = nil, opt = "", &b)
569
  includes = cpp_include(headers)
570
  if CROSS_COMPILING
571
    if try_static_assert("#{const} > 0", headers, opt)
572
      # positive constant
573
    elsif try_static_assert("#{const} < 0", headers, opt)
574
      neg = true
575
      const = "-(#{const})"
576
    elsif try_static_assert("#{const} == 0", headers, opt)
577
      return 0
578
    else
579
      # not a constant
580
      return nil
581
    end
582
    upper = 1
583
    lower = 0
584
    until try_static_assert("#{const} <= #{upper}", headers, opt)
585
      lower = upper
586
      upper <<= 1
587
    end
588
    return nil unless lower
589
    while upper > lower + 1
590
      mid = (upper + lower) / 2
591
      if try_static_assert("#{const} > #{mid}", headers, opt)
592
        lower = mid
573
  def try_constant(const, headers = nil, opt = "", &b)
574
    includes = cpp_include(headers)
575
    if CROSS_COMPILING
576
      if try_static_assert("#{const} > 0", headers, opt)
577
        # positive constant
578
      elsif try_static_assert("#{const} < 0", headers, opt)
579
        neg = true
580
        const = "-(#{const})"
581
      elsif try_static_assert("#{const} == 0", headers, opt)
582
        return 0
593 583
      else
594
        upper = mid
584
        # not a constant
585
        return nil
595 586
      end
596
    end
597
    upper = -upper if neg
598
    return upper
599
  else
600
    src = %{#{includes}
587
      upper = 1
588
      lower = 0
589
      until try_static_assert("#{const} <= #{upper}", headers, opt)
590
        lower = upper
591
        upper <<= 1
592
      end
593
      return nil unless lower
594
      while upper > lower + 1
595
        mid = (upper + lower) / 2
596
        if try_static_assert("#{const} > #{mid}", headers, opt)
597
          lower = mid
598
        else
599
          upper = mid
600
        end
601
      end
602
      upper = -upper if neg
603
      return upper
604
    else
605
      src = %{#{includes}
601 606
#include <stdio.h>
602 607
/*top*/
603 608
int conftest_const = (int)(#{const});
604 609
int main() {printf("%d\\n", conftest_const); return 0;}
605 610
}
606
    if try_link0(src, opt, &b)
607
      xpopen("./conftest") do |f|
608
        return Integer(f.gets)
611
      if try_link0(src, opt, &b)
612
        xpopen("./conftest") do |f|
613
          return Integer(f.gets)
614
        end
609 615
      end
610 616
    end
617
    nil
611 618
  end
612
  nil
613
end
614 619

  
615
# You should use +have_func+ rather than +try_func+.
616
#
617
# [+func+] a String which contains a symbol name
618
# [+libs+] a String which contains library names.
619
# [+headers+] a String or an Array of strings which contains
620
#             names of header files.
621
def try_func(func, libs, headers = nil, opt = "", &b)
622
  headers = cpp_include(headers)
623
  case func
624
  when /^&/
625
    decltype = proc {|x|"const volatile void *#{x}"}
626
  when /\)$/
627
    call = func
628
  else
629
    call = "#{func}()"
630
    decltype = proc {|x| "void ((*#{x})())"}
631
  end
632
  if opt and !opt.empty?
633
    [[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
634
      if opt.respond_to?(meth)
635
	break opt = opt.send(meth, *args)
620
  # You should use +have_func+ rather than +try_func+.
621
  #
622
  # [+func+] a String which contains a symbol name
623
  # [+libs+] a String which contains library names.
624
  # [+headers+] a String or an Array of strings which contains
625
  #             names of header files.
626
  def try_func(func, libs, headers = nil, opt = "", &b)
627
    headers = cpp_include(headers)
628
    case func
629
    when /^&/
630
      decltype = proc {|x|"const volatile void *#{x}"}
631
    when /\)$/
632
      call = func
633
    else
634
      call = "#{func}()"
635
      decltype = proc {|x| "void ((*#{x})())"}
636
    end
637
    if opt and !opt.empty?
638
      [[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
639
        if opt.respond_to?(meth)
640
    break opt = opt.send(meth, *args)
641
        end
636 642
      end
643
      opt = "#{opt} #{libs}"
644
    else
645
      opt = libs
637 646
    end
638
    opt = "#{opt} #{libs}"
639
  else
640
    opt = libs
641
  end
642
  decltype && try_link(<<"SRC", opt, &b) or
647
    decltype && try_link(<<"SRC", opt, &b) or
643 648
#{headers}
644 649
/*top*/
645 650
#{MAIN_DOES_NOTHING}
646 651
int t() { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
647 652
SRC
648
  call && try_link(<<"SRC", opt, &b)
653
    call && try_link(<<"SRC", opt, &b)
649 654
#{headers}
650 655
/*top*/
651 656
#{MAIN_DOES_NOTHING}
652 657
int t() { #{call}; return 0; }
653 658
SRC
654
end
659
  end
655 660

  
656
# You should use +have_var+ rather than +try_var+.
657
def try_var(var, headers = nil, opt = "", &b)
658
  headers = cpp_include(headers)
659
  try_compile(<<"SRC", opt, &b)
661
  # You should use +have_var+ rather than +try_var+.
662
  def try_var(var, headers = nil, opt = "", &b)
663
    headers = cpp_include(headers)
664
    try_compile(<<"SRC", opt, &b)
660 665
#{headers}
661 666
/*top*/
662 667
#{MAIN_DOES_NOTHING}
663 668
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
664 669
SRC
665
end
670
  end
666 671

  
667
# Returns whether or not the +src+ can be preprocessed with the C preprocessor and
668
# matches with +pat+.
669
#
670
# If a block given, it is called with the source before compilation. You can
671
# modify the source in the block.
672
#
673
# [+pat+] a Regexp or a String
674
# [+src+] a String which contains a C source
675
# [+opt+] a String which contains preprocessor options
676
#
677
# Note:
678
#   When pat is a Regexp the matching will be checked in process,
679
#   otherwise egrep(1) will be invoked to check it.
680
def egrep_cpp(pat, src, opt = "", &b)
681
  src = create_tmpsrc(src, &b)
682
  xpopen(cpp_command('', opt)) do |f|
683
    if Regexp === pat
684
      puts("    ruby -ne 'print if #{pat.inspect}'")
685
      f.grep(pat) {|l|
686
        puts "#{f.lineno}: #{l}"
687
        return true
688
      }
689
      false
690
    else
691
      puts("    egrep '#{pat}'")
692
      begin
693
        stdin = $stdin.dup
694
        $stdin.reopen(f)
695
        system("egrep", pat)
696
      ensure
697
        $stdin.reopen(stdin)
672
  # Returns whether or not the +src+ can be preprocessed with the C preprocessor and
673
  # matches with +pat+.
674
  #
675
  # If a block given, it is called with the source before compilation. You can
676
  # modify the source in the block.
677
  #
678
  # [+pat+] a Regexp or a String
679
  # [+src+] a String which contains a C source
680
  # [+opt+] a String which contains preprocessor options
681
  #
682
  # Note:
683
  #   When pat is a Regexp the matching will be checked in process,
684
  #   otherwise egrep(1) will be invoked to check it.
685
  def egrep_cpp(pat, src, opt = "", &b)
686
    src = create_tmpsrc(src, &b)
687
    xpopen(cpp_command('', opt)) do |f|
688
      if Regexp === pat
689
        puts("    ruby -ne 'print if #{pat.inspect}'")
690
        f.grep(pat) {|l|
691
          puts "#{f.lineno}: #{l}"
692
          return true
693
        }
694
        false
695
      else
696
        puts("    egrep '#{pat}'")
697
        begin
698
          stdin = $stdin.dup
699
          $stdin.reopen(f)
700
          system("egrep", pat)
701
        ensure
702
          $stdin.reopen(stdin)
703
        end
698 704
      end
699 705
    end
706
  ensure
707
    rm_f "conftest*"
708
    log_src(src)
700 709
  end
701
ensure
702
  rm_f "conftest*"
703
  log_src(src)
704
end
705 710

  
706
# This is used internally by the have_macro? method.
707
def macro_defined?(macro, src, opt = "", &b)
708
  src = src.sub(/[^\n]\z/, "\\&\n")
709
  try_compile(src + <<"SRC", opt, &b)
711
  # This is used internally by the have_macro? method.
712
  def macro_defined?(macro, src, opt = "", &b)
713
    src = src.sub(/[^\n]\z/, "\\&\n")
714
    try_compile(src + <<"SRC", opt, &b)
710 715
/*top*/
711 716
#ifndef #{macro}
712 717
# error
713 718
>>>>>> #{macro} undefined <<<<<<
714 719
#endif
715 720
SRC
716
end
721
  end
717 722

  
718
# Returns whether or not
719
# * the +src+ can be compiled as a C source,
720
# * the result object can be linked with its depending libraries successfully,
721
# * the linked file can be invoked as an executable
722
# * and the executable exits successfully
723
# +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
724
# are also passed to the linker.
725
#
726
# If a block given, it is called with the source before compilation. You can
727
# modify the source in the block.
728
#
729
# [+src+] a String which contains a C source
730
# [+opt+] a String which contains linker options
731
#
732
# @return true when the executable exits successfully, false when it fails, or
733
#         nil when preprocessing, compilation or link fails.
734
def try_run(src, opt = "", &b)
735
  if try_link0(src, opt, &b)
736
    xsystem("./conftest")
737
  else
738
    nil
723
  # Returns whether or not
724
  # * the +src+ can be compiled as a C source,
725
  # * the result object can be linked with its depending libraries successfully,
726
  # * the linked file can be invoked as an executable
727
  # * and the executable exits successfully
728
  # +opt+ is passed to the linker as options. Note that +$CFLAGS+ and +$LDFLAGS+
729
  # are also passed to the linker.
730
  #
731
  # If a block given, it is called with the source before compilation. You can
732
  # modify the source in the block.
733
  #
734
  # [+src+] a String which contains a C source
735
  # [+opt+] a String which contains linker options
736
  #
737
  # @return true when the executable exits successfully, false when it fails, or
738
  #         nil when preprocessing, compilation or link fails.
739
  def try_run(src, opt = "", &b)
740
    if try_link0(src, opt, &b)
741
      xsystem("./conftest")
742
    else
743
      nil
744
    end
745
  ensure
746
    rm_f "conftest*"
739 747
  end
740
ensure
741
  rm_f "conftest*"
742
end
743 748

  
744
def install_files(mfile, ifiles, map = nil, srcprefix = nil)
745
  ifiles or return
746
  ifiles.empty? and return
747
  srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
748
  RbConfig::expand(srcdir = srcprefix.dup)
749
  dirs = []
750
  path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
751
  ifiles.each do |files, dir, prefix|
752
    dir = map_dir(dir, map)
753
    prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
754
    if /\A\.\// =~ files
755
      # install files which are in current working directory.
756
      files = files[2..-1]
757
      len = nil
758
    else
759
      # install files which are under the $(srcdir).
760
      files = File.join(srcdir, files)
761
      len = srcdir.size
762
    end
763
    f = nil
764
    Dir.glob(files) do |fx|
765
      f = fx
766
      f[0..len] = "" if len
767
      case File.basename(f)
768
      when *$NONINSTALLFILES
769
        next
749
  def install_files(mfile, ifiles, map = nil, srcprefix = nil)
750
    ifiles or return
751
    ifiles.empty? and return
752
    srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
753
    RbConfig::expand(srcdir = srcprefix.dup)
754
    dirs = []
755
    path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
756
    ifiles.each do |files, dir, prefix|
757
      dir = map_dir(dir, map)
758
      prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
759
      if /\A\.\// =~ files
760
        # install files which are in current working directory.
761
        files = files[2..-1]
762
        len = nil
763
      else
764
        # install files which are under the $(srcdir).
765
        files = File.join(srcdir, files)
766
        len = srcdir.size
767
      end
768
      f = nil
769
      Dir.glob(files) do |fx|
770
        f = fx
771
        f[0..len] = "" if len
772
        case File.basename(f)
773
        when *$NONINSTALLFILES
774
          next
775
        end
776
        d = File.dirname(f)
777
        d.sub!(prefix, "") if prefix
778
        d = (d.empty? || d == ".") ? dir : File.join(dir, d)
779
        f = File.join(srcprefix, f) if len
780
        path[d] << f
781
      end
782
      unless len or f
783
        d = File.dirname(files)
784
        d.sub!(prefix, "") if prefix
785
        d = (d.empty? || d == ".") ? dir : File.join(dir, d)
786
        path[d] << files
770 787
      end
771
      d = File.dirname(f)
772
      d.sub!(prefix, "") if prefix
773
      d = (d.empty? || d == ".") ? dir : File.join(dir, d)
774
      f = File.join(srcprefix, f) if len
775
      path[d] << f
776
    end
777
    unless len or f
778
      d = File.dirname(files)
779
      d.sub!(prefix, "") if prefix
780
      d = (d.empty? || d == ".") ? dir : File.join(dir, d)
781
      path[d] << files
782 788
    end
789
    dirs
783 790
  end
784
  dirs
785
end
786 791

  
787
def install_rb(mfile, dest, srcdir = nil)
788
  install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
789
end
792
  def install_rb(mfile, dest, srcdir = nil)
793
    install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
794
  end
790 795

  
791
def append_library(libs, lib) # :no-doc:
792
  format(LIBARG, lib) + " " + libs
793
end
796
  def append_library(libs, lib) # :no-doc:
797
    format(LIBARG, lib) + " " + libs
798
  end
794 799

  
795
def message(*s)
796
  unless Logging.quiet and not $VERBOSE
797
    printf(*s)
798
    $stdout.flush
800
  def message(*s)
801
    unless Logging.quiet and not $VERBOSE
802
      printf(*s)
803
      $stdout.flush
804
    end
799 805
  end
800
end
801 806

  
802
# This emits a string to stdout that allows users to see the results of the
803
# various have* and find* methods as they are tested.
804
#
805
# Internal use only.
806
#
807
def checking_for(m, fmt = nil)
808
  f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
809
  m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
810
  message "%s", m
811
  a = r = nil
812
  Logging::postpone do
813
    r = yield
814
    a = (fmt ? "#{fmt % r}" : r ? "yes" : "no") << "\n"
815
    "#{f}#{m}-------------------- #{a}\n"
816
  end
817
  message(a)
818
  Logging::message "--------------------\n\n"
819
  r
820
end
807
  # This emits a string to stdout that allows users to see the results of the
808
  # various have* and find* methods as they are tested.
809
  #
810
  # Internal use only.
811
  #
812
  def checking_for(m, fmt = nil)
813
    f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
814
    m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
815
    message "%s", m
816
    a = r = nil
817
    Logging::postpone do
818
      r = yield
819
      a = (fmt ? "#{fmt % r}" : r ? "yes" : "no") << "\n"
820
      "#{f}#{m}-------------------- #{a}\n"
821
    end
822
    message(a)
823
    Logging::message "--------------------\n\n"
824
    r
825
  end
821 826

  
822
def checking_message(target, place = nil, opt = nil)
823
  [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
824
    if noun
825
      [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
826
        if noun.respond_to?(meth)
827
          break noun = noun.send(meth, *args)
827
  def checking_message(target, place = nil, opt = nil)
828
    [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
829
      if noun
830
        [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
831
          if noun.respond_to?(meth)
832
            break noun = noun.send(meth, *args)
833
          end
828 834
        end
835
        msg << " #{pre} #{noun}" unless noun.empty?
829 836
      end
830
      msg << " #{pre} #{noun}" unless noun.empty?
837
      msg
... This diff was truncated because it exceeds the maximum size that can be displayed.