Project

General

Profile

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

drbrain (Eric Hodel), 11/22/2011 11:42 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
222 124

  
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
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
  ]
140

  
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
491

  
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
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
506 498

  
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
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
521 513

  
522
class Object
523
  alias_method :try_header, (config_string('try_header') || :try_cpp)
524
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
525 528

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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