1# -*- coding: us-ascii -*-
2# module to create Makefile for extension modules
3# invoke like: ruby -r mkmf extconf.rb
4
5require 'rbconfig'
6require 'fileutils'
7require 'shellwords'
8
9# :stopdoc:
10class String
11  # Wraps a string in escaped quotes if it contains whitespace.
12  def quote
13    /\s/ =~ self ? "\"#{self}\"" : "#{self}"
14  end
15
16  # Escape whitespaces for Makefile.
17  def unspace
18    gsub(/\s/, '\\\\\\&')
19  end
20
21  # Generates a string used as cpp macro name.
22  def tr_cpp
23    strip.upcase.tr_s("^A-Z0-9_*", "_").tr_s("*", "P")
24  end
25
26  def funcall_style
27    /\)\z/ =~ self ? dup : "#{self}()"
28  end
29
30  def sans_arguments
31    self[/\A[^()]+/]
32  end
33end
34
35class Array
36  # Wraps all strings in escaped quotes if they contain whitespace.
37  def quote
38    map {|s| s.quote}
39  end
40end
41# :startdoc:
42
43##
44# mkmf.rb is used by ruby C extensions to generate a Makefile which will
45# correctly compile and link the C extension to ruby and a third-party
46# library.
47module MakeMakefile
48
49  ##
50  # The makefile configuration using the defaults from when ruby was built.
51
52  CONFIG = RbConfig::MAKEFILE_CONFIG
53  ORIG_LIBPATH = ENV['LIB']
54
55  ##
56  # Extensions for files compiled with a C compiler
57
58  C_EXT = %w[c m]
59
60  ##
61  # Extensions for files complied with a C++ compiler
62
63  CXX_EXT = %w[cc mm cxx cpp]
64  if File::FNM_SYSCASE.zero?
65    CXX_EXT.concat(%w[C])
66  end
67
68  ##
69  # Extensions for source files
70
71  SRC_EXT = C_EXT + CXX_EXT
72
73  ##
74  # Extensions for header files
75
76  HDR_EXT = %w[h hpp]
77  $static = nil
78  $config_h = '$(arch_hdrdir)/ruby/config.h'
79  $default_static = $static
80
81  unless defined? $configure_args
82    $configure_args = {}
83    args = CONFIG["configure_args"]
84    if ENV["CONFIGURE_ARGS"]
85      args << " " << ENV["CONFIGURE_ARGS"]
86    end
87    for arg in Shellwords::shellwords(args)
88      arg, val = arg.split('=', 2)
89      next unless arg
90      arg.tr!('_', '-')
91      if arg.sub!(/^(?!--)/, '--')
92        val or next
93        arg.downcase!
94      end
95      next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
96      $configure_args[arg] = val || true
97    end
98    for arg in ARGV
99      arg, val = arg.split('=', 2)
100      next unless arg
101      arg.tr!('_', '-')
102      if arg.sub!(/^(?!--)/, '--')
103        val or next
104        arg.downcase!
105      end
106      $configure_args[arg] = val || true
107    end
108  end
109
110  $libdir = CONFIG["libdir"]
111  $rubylibdir = CONFIG["rubylibdir"]
112  $archdir = CONFIG["archdir"]
113  $sitedir = CONFIG["sitedir"]
114  $sitelibdir = CONFIG["sitelibdir"]
115  $sitearchdir = CONFIG["sitearchdir"]
116  $vendordir = CONFIG["vendordir"]
117  $vendorlibdir = CONFIG["vendorlibdir"]
118  $vendorarchdir = CONFIG["vendorarchdir"]
119
120  $mswin = /mswin/ =~ RUBY_PLATFORM
121  $bccwin = /bccwin/ =~ RUBY_PLATFORM
122  $mingw = /mingw/ =~ RUBY_PLATFORM
123  $cygwin = /cygwin/ =~ RUBY_PLATFORM
124  $netbsd = /netbsd/ =~ RUBY_PLATFORM
125  $os2 = /os2/ =~ RUBY_PLATFORM
126  $beos = /beos/ =~ RUBY_PLATFORM
127  $haiku = /haiku/ =~ RUBY_PLATFORM
128  $solaris = /solaris/ =~ RUBY_PLATFORM
129  $universal = /universal/ =~ RUBY_PLATFORM
130  $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
131
132  # :stopdoc:
133
134  def config_string(key, config = CONFIG)
135    s = config[key] and !s.empty? and block_given? ? yield(s) : s
136  end
137  module_function :config_string
138
139  def dir_re(dir)
140    Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
141  end
142  module_function :dir_re
143
144  def relative_from(path, base)
145    dir = File.join(path, "")
146    if File.expand_path(dir) == File.expand_path(dir, base)
147      path
148    else
149      File.join(base, path)
150    end
151  end
152
153  INSTALL_DIRS = [
154    [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
155    [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
156    [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
157    [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
158    [dir_re('archdir'), "$(RUBYARCHDIR)"],
159    [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
160    [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
161    [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
162    [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
163    [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"],
164    [dir_re('sitehdrdir'), "$(SITEHDRDIR)"],
165    [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"],
166    [dir_re('bindir'), "$(BINDIR)"],
167  ]
168
169  def install_dirs(target_prefix = nil)
170    if $extout
171      dirs = [
172        ['BINDIR',        '$(extout)/bin'],
173        ['RUBYCOMMONDIR', '$(extout)/common'],
174        ['RUBYLIBDIR',    '$(RUBYCOMMONDIR)$(target_prefix)'],
175        ['RUBYARCHDIR',   '$(extout)/$(arch)$(target_prefix)'],
176        ['HDRDIR',        '$(extout)/include/ruby$(target_prefix)'],
177        ['ARCHHDRDIR',    '$(extout)/include/$(arch)/ruby$(target_prefix)'],
178        ['extout',        "#$extout"],
179        ['extout_prefix', "#$extout_prefix"],
180      ]
181    elsif $extmk
182      dirs = [
183        ['BINDIR',        '$(bindir)'],
184        ['RUBYCOMMONDIR', '$(rubylibdir)'],
185        ['RUBYLIBDIR',    '$(rubylibdir)$(target_prefix)'],
186        ['RUBYARCHDIR',   '$(archdir)$(target_prefix)'],
187        ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
188        ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
189      ]
190    elsif $configure_args.has_key?('--vendor')
191      dirs = [
192        ['BINDIR',        '$(DESTDIR)$(bindir)'],
193        ['RUBYCOMMONDIR', '$(DESTDIR)$(vendordir)$(target_prefix)'],
194        ['RUBYLIBDIR',    '$(DESTDIR)$(vendorlibdir)$(target_prefix)'],
195        ['RUBYARCHDIR',   '$(DESTDIR)$(vendorarchdir)$(target_prefix)'],
196        ['HDRDIR',        '$(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix)'],
197        ['ARCHHDRDIR',    '$(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
198      ]
199    else
200      dirs = [
201        ['BINDIR',        '$(DESTDIR)$(bindir)'],
202        ['RUBYCOMMONDIR', '$(DESTDIR)$(sitedir)$(target_prefix)'],
203        ['RUBYLIBDIR',    '$(DESTDIR)$(sitelibdir)$(target_prefix)'],
204        ['RUBYARCHDIR',   '$(DESTDIR)$(sitearchdir)$(target_prefix)'],
205        ['HDRDIR',        '$(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix)'],
206        ['ARCHHDRDIR',    '$(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
207      ]
208    end
209    dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
210    dirs
211  end
212
213  def map_dir(dir, map = nil)
214    map ||= INSTALL_DIRS
215    map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)}
216  end
217
218  topdir = File.dirname(File.dirname(__FILE__))
219  path = File.expand_path($0)
220  until (dir = File.dirname(path)) == path
221    if File.identical?(dir, topdir)
222      $extmk = true if %r"\A(?:ext|enc|tool|test)\z" =~ File.basename(path)
223      break
224    end
225    path = dir
226  end
227  $extmk ||= false
228  if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
229    $topdir = $hdrdir
230    $top_srcdir = $hdrdir
231    $arch_hdrdir = RbConfig::CONFIG["rubyarchhdrdir"]
232  elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include")  + "/ruby.h")
233    $topdir ||= RbConfig::CONFIG["topdir"]
234    $arch_hdrdir = "$(extout)/include/$(arch)"
235  else
236    abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
237  end
238
239  OUTFLAG = CONFIG['OUTFLAG']
240  COUTFLAG = CONFIG['COUTFLAG']
241  CPPOUTFILE = CONFIG['CPPOUTFILE']
242
243  CONFTEST_C = "conftest.c".freeze
244
245  def rm_f(*files)
246    opt = (Hash === files.last ? [files.pop] : [])
247    FileUtils.rm_f(Dir[*files.flatten], *opt)
248  end
249  module_function :rm_f
250
251  def rm_rf(*files)
252    opt = (Hash === files.last ? [files.pop] : [])
253    FileUtils.rm_rf(Dir[*files.flatten], *opt)
254  end
255  module_function :rm_rf
256
257  # Returns time stamp of the +target+ file if it exists and is newer than or
258  # equal to all of +times+.
259  def modified?(target, times)
260    (t = File.mtime(target)) rescue return nil
261    Array === times or times = [times]
262    t if times.all? {|n| n <= t}
263  end
264
265  def split_libs(*strs)
266    strs.map {|s| s.split(/\s+(?=-|\z)/)}.flatten
267  end
268
269  def merge_libs(*libs)
270    libs.inject([]) do |x, y|
271      y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
272      y.each_with_index do |v, yi|
273        if xi = x.rindex(v)
274          x[(xi+1)..-1] = merge_libs(y[(yi+1)..-1], x[(xi+1)..-1])
275          x[xi, 0] = y[0...yi]
276          break
277        end
278      end and x.concat(y)
279      x
280    end
281  end
282
283  # This is a custom logging module. It generates an mkmf.log file when you
284  # run your extconf.rb script. This can be useful for debugging unexpected
285  # failures.
286  #
287  # This module and its associated methods are meant for internal use only.
288  #
289  module Logging
290    @log = nil
291    @logfile = 'mkmf.log'
292    @orgerr = $stderr.dup
293    @orgout = $stdout.dup
294    @postpone = 0
295    @quiet = $extmk
296
297    def self::log_open
298      @log ||= File::open(@logfile, 'wb')
299      @log.sync = true
300    end
301
302    def self::log_opened?
303      @log and not @log.closed?
304    end
305
306    def self::open
307      log_open
308      $stderr.reopen(@log)
309      $stdout.reopen(@log)
310      yield
311    ensure
312      $stderr.reopen(@orgerr)
313      $stdout.reopen(@orgout)
314    end
315
316    def self::message(*s)
317      log_open
318      @log.printf(*s)
319    end
320
321    def self::logfile file
322      @logfile = file
323      log_close
324    end
325
326    def self::log_close
327      if @log and not @log.closed?
328        @log.flush
329        @log.close
330        @log = nil
331      end
332    end
333
334    def self::postpone
335      tmplog = "mkmftmp#{@postpone += 1}.log"
336      open do
337        log, *save = @log, @logfile, @orgout, @orgerr
338        @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
339        begin
340          log.print(open {yield @log})
341        ensure
342          @log.close if @log and not @log.closed?
343          File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
344          @log, @logfile, @orgout, @orgerr = log, *save
345          @postpone -= 1
346          MakeMakefile.rm_f tmplog
347        end
348      end
349    end
350
351    class << self
352      attr_accessor :quiet
353    end
354  end
355
356  def xsystem command, opts = nil
357    varpat = /\$\((\w+)\)|\$\{(\w+)\}/
358    if varpat =~ command
359      vars = Hash.new {|h, k| h[k] = ENV[k]}
360      command = command.dup
361      nil while command.gsub!(varpat) {vars[$1||$2]}
362    end
363    Logging::open do
364      puts command.quote
365      if opts and opts[:werror]
366        result = nil
367        Logging.postpone do |log|
368          result = (system(command) and File.zero?(log.path))
369          ""
370        end
371        result
372      else
373        system(command)
374      end
375    end
376  end
377
378  def xpopen command, *mode, &block
379    Logging::open do
380      case mode[0]
381      when nil, /^r/
382        puts "#{command} |"
383      else
384        puts "| #{command}"
385      end
386      IO.popen(command, *mode, &block)
387    end
388  end
389
390  def log_src(src, heading="checked program was")
391    src = src.split(/^/)
392    fmt = "%#{src.size.to_s.size}d: %s"
393    Logging::message <<"EOM"
394#{heading}:
395/* begin */
396EOM
397    src.each_with_index {|line, no| Logging::message fmt, no+1, line}
398    Logging::message <<"EOM"
399/* end */
400
401EOM
402  end
403
404  def create_tmpsrc(src)
405    src = "#{COMMON_HEADERS}\n#{src}"
406    src = yield(src) if block_given?
407    src.gsub!(/[ \t]+$/, '')
408    src.gsub!(/\A\n+|^\n+$/, '')
409    src.sub!(/[^\n]\z/, "\\&\n")
410    count = 0
411    begin
412      open(CONFTEST_C, "wb") do |cfile|
413        cfile.print src
414      end
415    rescue Errno::EACCES
416      if (count += 1) < 5
417        sleep 0.2
418        retry
419      end
420    end
421    src
422  end
423
424  def have_devel?
425    unless defined? $have_devel
426      $have_devel = true
427      $have_devel = try_link(MAIN_DOES_NOTHING)
428    end
429    $have_devel
430  end
431
432  def try_do(src, command, *opts, &b)
433    unless have_devel?
434      raise <<MSG
435The compiler failed to generate an executable file.
436You have to install development tools first.
437MSG
438    end
439    begin
440      src = create_tmpsrc(src, &b)
441      xsystem(command, *opts)
442    ensure
443      log_src(src)
444      MakeMakefile.rm_rf 'conftest.dSYM'
445    end
446  end
447
448  def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
449    librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
450    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
451                                  'src' => "#{CONFTEST_C}",
452                                  'arch_hdrdir' => $arch_hdrdir.quote,
453                                  'top_srcdir' => $top_srcdir.quote,
454                                  'INCFLAGS' => "#$INCFLAGS",
455                                  'CPPFLAGS' => "#$CPPFLAGS",
456                                  'CFLAGS' => "#$CFLAGS",
457                                  'ARCH_FLAG' => "#$ARCH_FLAG",
458                                  'LDFLAGS' => "#$LDFLAGS #{ldflags}",
459                                  'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
460                                  'LIBS' => "#{librubyarg} #{opt} #$LIBS")
461    conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
462    RbConfig::expand(TRY_LINK.dup, conf)
463  end
464
465  def cc_command(opt="")
466    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
467                                  'arch_hdrdir' => $arch_hdrdir.quote,
468                                  'top_srcdir' => $top_srcdir.quote)
469    RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
470                     conf)
471  end
472
473  def cpp_command(outfile, opt="")
474    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
475                                  'arch_hdrdir' => $arch_hdrdir.quote,
476                                  'top_srcdir' => $top_srcdir.quote)
477    if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
478      conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
479    end
480    RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
481                     conf)
482  end
483
484  def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
485    libpath.map{|x|
486      case x
487      when "$(topdir)", /\A\./
488        LIBPATHFLAG
489      else
490        LIBPATHFLAG+RPATHFLAG
491      end % x.quote
492    }.join
493  end
494
495  def with_werror(opt, opts = nil)
496    if opts
497      if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
498        (opts = opts.dup).delete(:werror)
499      end
500      yield(opt, opts)
501    else
502      yield(opt)
503    end
504  end
505
506  def try_link0(src, opt="", *opts, &b) # :nodoc:
507    cmd = link_command("", opt)
508    if $universal
509      require 'tmpdir'
510      Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
511        begin
512          ENV["TMPDIR"] = tmpdir
513          try_do(src, cmd, *opts, &b)
514        ensure
515          ENV["TMPDIR"] = oldtmpdir
516        end
517      end
518    else
519      try_do(src, cmd, *opts, &b)
520    end and File.executable?("conftest#{$EXEEXT}")
521  end
522
523  # Returns whether or not the +src+ can be compiled as a C source and linked
524  # with its depending libraries successfully.  +opt+ is passed to the linker
525  # as options. Note that +$CFLAGS+ and +$LDFLAGS+ are also passed to the
526  # linker.
527  #
528  # If a block given, it is called with the source before compilation. You can
529  # modify the source in the block.
530  #
531  # [+src+] a String which contains a C source
532  # [+opt+] a String which contains linker options
533  def try_link(src, opt="", *opts, &b)
534    try_link0(src, opt, *opts, &b)
535  ensure
536    MakeMakefile.rm_f "conftest*", "c0x32*"
537  end
538
539  # Returns whether or not the +src+ can be compiled as a C source.  +opt+ is
540  # passed to the C compiler as options. Note that +$CFLAGS+ is also passed to
541  # the compiler.
542  #
543  # If a block given, it is called with the source before compilation. You can
544  # modify the source in the block.
545  #
546  # [+src+] a String which contains a C source
547  # [+opt+] a String which contains compiler options
548  def try_compile(src, opt="", *opts, &b)
549    with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)} and
550      File.file?("conftest.#{$OBJEXT}")
551  ensure
552    MakeMakefile.rm_f "conftest*"
553  end
554
555  # Returns whether or not the +src+ can be preprocessed with the C
556  # preprocessor.  +opt+ is passed to the preprocessor as options. Note that
557  # +$CFLAGS+ is also passed to the preprocessor.
558  #
559  # If a block given, it is called with the source before preprocessing. You
560  # can modify the source in the block.
561  #
562  # [+src+] a String which contains a C source
563  # [+opt+] a String which contains preprocessor options
564  def try_cpp(src, opt="", *opts, &b)
565    try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b) and
566      File.file?("conftest.i")
567  ensure
568    MakeMakefile.rm_f "conftest*"
569  end
570
571  alias_method :try_header, (config_string('try_header') || :try_cpp)
572
573  def cpp_include(header)
574    if header
575      header = [header] unless header.kind_of? Array
576      header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
577    else
578      ""
579    end
580  end
581
582  def with_cppflags(flags)
583    cppflags = $CPPFLAGS
584    $CPPFLAGS = flags
585    ret = yield
586  ensure
587    $CPPFLAGS = cppflags unless ret
588  end
589
590  def try_cppflags(flags)
591    with_cppflags(flags) do
592      try_header("int main() {return 0;}")
593    end
594  end
595
596  def with_cflags(flags)
597    cflags = $CFLAGS
598    $CFLAGS = flags
599    ret = yield
600  ensure
601    $CFLAGS = cflags unless ret
602  end
603
604  def try_cflags(flags)
605    with_cflags(flags) do
606      try_compile("int main() {return 0;}")
607    end
608  end
609
610  def with_ldflags(flags)
611    ldflags = $LDFLAGS
612    $LDFLAGS = flags
613    ret = yield
614  ensure
615    $LDFLAGS = ldflags unless ret
616  end
617
618  def try_ldflags(flags)
619    with_ldflags(flags) do
620      try_link("int main() {return 0;}")
621    end
622  end
623
624  def try_static_assert(expr, headers = nil, opt = "", &b)
625    headers = cpp_include(headers)
626    try_compile(<<SRC, opt, &b)
627#{headers}
628/*top*/
629int conftest_const[(#{expr}) ? 1 : -1];
630SRC
631  end
632
633  def try_constant(const, headers = nil, opt = "", &b)
634    includes = cpp_include(headers)
635    neg = try_static_assert("#{const} < 0", headers, opt)
636    if CROSS_COMPILING
637      if neg
638        const = "-(#{const})"
639      elsif try_static_assert("#{const} > 0", headers, opt)
640        # positive constant
641      elsif try_static_assert("#{const} == 0", headers, opt)
642        return 0
643      else
644        # not a constant
645        return nil
646      end
647      upper = 1
648      lower = 0
649      until try_static_assert("#{const} <= #{upper}", headers, opt)
650        lower = upper
651        upper <<= 1
652      end
653      return nil unless lower
654      while upper > lower + 1
655        mid = (upper + lower) / 2
656        if try_static_assert("#{const} > #{mid}", headers, opt)
657          lower = mid
658        else
659          upper = mid
660        end
661      end
662      upper = -upper if neg
663      return upper
664    else
665      src = %{#{includes}
666#include <stdio.h>
667/*top*/
668typedef#{neg ? '' : ' unsigned'}
669#ifdef PRI_LL_PREFIX
670#define PRI_CONFTEST_PREFIX PRI_LL_PREFIX
671LONG_LONG
672#else
673#define PRI_CONFTEST_PREFIX "l"
674long
675#endif
676conftest_type;
677conftest_type conftest_const = (conftest_type)(#{const});
678int main() {printf("%"PRI_CONFTEST_PREFIX"#{neg ? 'd' : 'u'}\\n", conftest_const); return 0;}
679}
680      begin
681        if try_link0(src, opt, &b)
682          xpopen("./conftest") do |f|
683            return Integer(f.gets)
684          end
685        end
686      ensure
687        MakeMakefile.rm_f "conftest*"
688      end
689    end
690    nil
691  end
692
693  # You should use +have_func+ rather than +try_func+.
694  #
695  # [+func+] a String which contains a symbol name
696  # [+libs+] a String which contains library names.
697  # [+headers+] a String or an Array of strings which contains names of header
698  #             files.
699  def try_func(func, libs, headers = nil, opt = "", &b)
700    headers = cpp_include(headers)
701    case func
702    when /^&/
703      decltype = proc {|x|"const volatile void *#{x}"}
704    when /\)$/
705      call = func
706    else
707      call = "#{func}()"
708      decltype = proc {|x| "void ((*#{x})())"}
709    end
710    if opt and !opt.empty?
711      [[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
712        if opt.respond_to?(meth)
713          break opt = opt.send(meth, *args)
714        end
715      end
716      opt = "#{opt} #{libs}"
717    else
718      opt = libs
719    end
720    decltype && try_link(<<"SRC", opt, &b) or
721#{headers}
722/*top*/
723extern int t(void);
724int t(void) { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
725#{MAIN_DOES_NOTHING "t"}
726SRC
727    call && try_link(<<"SRC", opt, &b)
728#{headers}
729/*top*/
730extern int t(void);
731int t(void) { #{call}; return 0; }
732#{MAIN_DOES_NOTHING "t"}
733SRC
734  end
735
736  # You should use +have_var+ rather than +try_var+.
737  def try_var(var, headers = nil, opt = "", &b)
738    headers = cpp_include(headers)
739    try_compile(<<"SRC", opt, &b)
740#{headers}
741/*top*/
742extern int t(void);
743int t(void) { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
744#{MAIN_DOES_NOTHING "t"}
745SRC
746  end
747
748  # Returns whether or not the +src+ can be preprocessed with the C
749  # preprocessor and matches with +pat+.
750  #
751  # If a block given, it is called with the source before compilation. You can
752  # modify the source in the block.
753  #
754  # [+pat+] a Regexp or a String
755  # [+src+] a String which contains a C source
756  # [+opt+] a String which contains preprocessor options
757  #
758  # NOTE: When pat is a Regexp the matching will be checked in process,
759  # otherwise egrep(1) will be invoked to check it.
760  def egrep_cpp(pat, src, opt = "", &b)
761    src = create_tmpsrc(src, &b)
762    xpopen(cpp_command('', opt)) do |f|
763      if Regexp === pat
764        puts("    ruby -ne 'print if #{pat.inspect}'")
765        f.grep(pat) {|l|
766          puts "#{f.lineno}: #{l}"
767          return true
768        }
769        false
770      else
771        puts("    egrep '#{pat}'")
772        begin
773          stdin = $stdin.dup
774          $stdin.reopen(f)
775          system("egrep", pat)
776        ensure
777          $stdin.reopen(stdin)
778        end
779      end
780    end
781  ensure
782    MakeMakefile.rm_f "conftest*"
783    log_src(src)
784  end
785
786  # This is used internally by the have_macro? method.
787  def macro_defined?(macro, src, opt = "", &b)
788    src = src.sub(/[^\n]\z/, "\\&\n")
789    try_compile(src + <<"SRC", opt, &b)
790/*top*/
791#ifndef #{macro}
792# error
793|:/ === #{macro} undefined === /:|
794#endif
795SRC
796  end
797
798  # Returns whether or not:
799  # * the +src+ can be compiled as a C source,
800  # * the result object can be linked with its depending libraries
801  #   successfully,
802  # * the linked file can be invoked as an executable
803  # * and the executable exits successfully
804  #
805  # +opt+ is passed to the linker as options. Note that +$CFLAGS+ and
806  # +$LDFLAGS+ are also passed to the linker.
807  #
808  # If a block given, it is called with the source before compilation. You can
809  # modify the source in the block.
810  #
811  # [+src+] a String which contains a C source
812  # [+opt+] a String which contains linker options
813  #
814  # Returns true when the executable exits successfully, false when it fails,
815  # or nil when preprocessing, compilation or link fails.
816  def try_run(src, opt = "", &b)
817    if try_link0(src, opt, &b)
818      xsystem("./conftest")
819    else
820      nil
821    end
822  ensure
823    MakeMakefile.rm_f "conftest*"
824  end
825
826  def install_files(mfile, ifiles, map = nil, srcprefix = nil)
827    ifiles or return
828    ifiles.empty? and return
829    srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
830    RbConfig::expand(srcdir = srcprefix.dup)
831    dirs = []
832    path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
833    ifiles.each do |files, dir, prefix|
834      dir = map_dir(dir, map)
835      prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
836      if /\A\.\// =~ files
837        # install files which are in current working directory.
838        files = files[2..-1]
839        len = nil
840      else
841        # install files which are under the $(srcdir).
842        files = File.join(srcdir, files)
843        len = srcdir.size
844      end
845      f = nil
846      Dir.glob(files) do |fx|
847        f = fx
848        f[0..len] = "" if len
849        case File.basename(f)
850        when *$NONINSTALLFILES
851          next
852        end
853        d = File.dirname(f)
854        d.sub!(prefix, "") if prefix
855        d = (d.empty? || d == ".") ? dir : File.join(dir, d)
856        f = File.join(srcprefix, f) if len
857        path[d] << f
858      end
859      unless len or f
860        d = File.dirname(files)
861        d.sub!(prefix, "") if prefix
862        d = (d.empty? || d == ".") ? dir : File.join(dir, d)
863        path[d] << files
864      end
865    end
866    dirs
867  end
868
869  def install_rb(mfile, dest, srcdir = nil)
870    install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
871  end
872
873  def append_library(libs, lib) # :no-doc:
874    format(LIBARG, lib) + " " + libs
875  end
876
877  def message(*s)
878    unless Logging.quiet and not $VERBOSE
879      printf(*s)
880      $stdout.flush
881    end
882  end
883
884  # This emits a string to stdout that allows users to see the results of the
885  # various have* and find* methods as they are tested.
886  #
887  # Internal use only.
888  #
889  def checking_for(m, fmt = nil)
890    f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
891    m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
892    message "%s", m
893    a = r = nil
894    Logging::postpone do
895      r = yield
896      a = (fmt ? "#{fmt % r}" : r ? "yes" : "no") << "\n"
897      "#{f}#{m}-------------------- #{a}\n"
898    end
899    message(a)
900    Logging::message "--------------------\n\n"
901    r
902  end
903
904  def checking_message(target, place = nil, opt = nil)
905    [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
906      if noun
907        [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
908          if noun.respond_to?(meth)
909            break noun = noun.send(meth, *args)
910          end
911        end
912        msg << " #{pre} #{noun}" unless noun.empty?
913      end
914      msg
915    end
916  end
917
918  # :startdoc:
919
920  # Returns whether or not +macro+ is defined either in the common header
921  # files or within any +headers+ you provide.
922  #
923  # Any options you pass to +opt+ are passed along to the compiler.
924  #
925  def have_macro(macro, headers = nil, opt = "", &b)
926    checking_for checking_message(macro, headers, opt) do
927      macro_defined?(macro, cpp_include(headers), opt, &b)
928    end
929  end
930
931  # Returns whether or not the given entry point +func+ can be found within
932  # +lib+.  If +func+ is +nil+, the <code>main()</code> entry point is used by
933  # default.  If found, it adds the library to list of libraries to be used
934  # when linking your extension.
935  #
936  # If +headers+ are provided, it will include those header files as the
937  # header files it looks in when searching for +func+.
938  #
939  # The real name of the library to be linked can be altered by
940  # <code>--with-FOOlib</code> configuration option.
941  #
942  def have_library(lib, func = nil, headers = nil, opt = "", &b)
943    func = "main" if !func or func.empty?
944    lib = with_config(lib+'lib', lib)
945    checking_for checking_message(func.funcall_style, LIBARG%lib, opt) do
946      if COMMON_LIBS.include?(lib)
947        true
948      else
949        libs = append_library($libs, lib)
950        if try_func(func, libs, headers, opt, &b)
951          $libs = libs
952          true
953        else
954          false
955        end
956      end
957    end
958  end
959
960  # Returns whether or not the entry point +func+ can be found within the
961  # library +lib+ in one of the +paths+ specified, where +paths+ is an array
962  # of strings.  If +func+ is +nil+ , then the <code>main()</code> function is
963  # used as the entry point.
964  #
965  # If +lib+ is found, then the path it was found on is added to the list of
966  # library paths searched and linked against.
967  #
968  def find_library(lib, func, *paths, &b)
969    func = "main" if !func or func.empty?
970    lib = with_config(lib+'lib', lib)
971    paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
972    checking_for checking_message(func.funcall_style, LIBARG%lib) do
973      libpath = $LIBPATH
974      libs = append_library($libs, lib)
975      begin
976        until r = try_func(func, libs, &b) or paths.empty?
977          $LIBPATH = libpath | [paths.shift]
978        end
979        if r
980          $libs = libs
981          libpath = nil
982        end
983      ensure
984        $LIBPATH = libpath if libpath
985      end
986      r
987    end
988  end
989
990  # Returns whether or not the function +func+ can be found in the common
991  # header files, or within any +headers+ that you provide.  If found, a macro
992  # is passed as a preprocessor constant to the compiler using the function
993  # name, in uppercase, prepended with +HAVE_+.
994  #
995  # To check functions in an additional library, you need to check that
996  # library first using <code>have_library()</code>.  The +func+ shall be
997  # either mere function name or function name with arguments.
998  #
999  # For example, if <code>have_func('foo')</code> returned +true+, then the
1000  # +HAVE_FOO+ preprocessor macro would be passed to the compiler.
1001  #
1002  def have_func(func, headers = nil, opt = "", &b)
1003    checking_for checking_message(func.funcall_style, headers, opt) do
1004      if try_func(func, $libs, headers, opt, &b)
1005        $defs << "-DHAVE_#{func.sans_arguments.tr_cpp}"
1006        true
1007      else
1008        false
1009      end
1010    end
1011  end
1012
1013  # Returns whether or not the variable +var+ can be found in the common
1014  # header files, or within any +headers+ that you provide.  If found, a macro
1015  # is passed as a preprocessor constant to the compiler using the variable
1016  # name, in uppercase, prepended with +HAVE_+.
1017  #
1018  # To check variables in an additional library, you need to check that
1019  # library first using <code>have_library()</code>.
1020  #
1021  # For example, if <code>have_var('foo')</code> returned true, then the
1022  # +HAVE_FOO+ preprocessor macro would be passed to the compiler.
1023  #
1024  def have_var(var, headers = nil, opt = "", &b)
1025    checking_for checking_message(var, headers, opt) do
1026      if try_var(var, headers, opt, &b)
1027        $defs.push(format("-DHAVE_%s", var.tr_cpp))
1028        true
1029      else
1030        false
1031      end
1032    end
1033  end
1034
1035  # Returns whether or not the given +header+ file can be found on your system.
1036  # If found, a macro is passed as a preprocessor constant to the compiler
1037  # using the header file name, in uppercase, prepended with +HAVE_+.
1038  #
1039  # For example, if <code>have_header('foo.h')</code> returned true, then the
1040  # +HAVE_FOO_H+ preprocessor macro would be passed to the compiler.
1041  #
1042  def have_header(header, preheaders = nil, opt = "", &b)
1043    checking_for header do
1044      if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
1045        $defs.push(format("-DHAVE_%s", header.tr_cpp))
1046        true
1047      else
1048        false
1049      end
1050    end
1051  end
1052
1053  # Returns whether or not the given +framework+ can be found on your system.
1054  # If found, a macro is passed as a preprocessor constant to the compiler
1055  # using the framework name, in uppercase, prepended with +HAVE_FRAMEWORK_+.
1056  #
1057  # For example, if <code>have_framework('Ruby')</code> returned true, then
1058  # the +HAVE_FRAMEWORK_RUBY+ preprocessor macro would be passed to the
1059  # compiler.
1060  #
1061  # If +fw+ is a pair of the framework name and its header file name
1062  # that header file is checked, instead of the normally used header
1063  # file which is named same as the framework.
1064  def have_framework(fw, &b)
1065    if Array === fw
1066      fw, header = *fw
1067    else
1068      header = "#{fw}.h"
1069    end
1070    checking_for fw do
1071      src = cpp_include("#{fw}/#{header}") << "\n" "int main(void){return 0;}"
1072      opt = " -framework #{fw}"
1073      if try_link(src, "-ObjC#{opt}", &b)
1074        $defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp))
1075        # TODO: non-worse way than this hack, to get rid of separating
1076        # option and its argument.
1077        $LDFLAGS << " -ObjC" unless /(\A|\s)-ObjC(\s|\z)/ =~ $LDFLAGS
1078        $LDFLAGS << opt
1079        true
1080      else
1081        false
1082      end
1083    end
1084  end
1085
1086  # Instructs mkmf to search for the given +header+ in any of the +paths+
1087  # provided, and returns whether or not it was found in those paths.
1088  #
1089  # If the header is found then the path it was found on is added to the list
1090  # of included directories that are sent to the compiler (via the
1091  # <code>-I</code> switch).
1092  #
1093  def find_header(header, *paths)
1094    message = checking_message(header, paths)
1095    header = cpp_include(header)
1096    checking_for message do
1097      if try_header(header)
1098        true
1099      else
1100        found = false
1101        paths.each do |dir|
1102          opt = "-I#{dir}".quote
1103          if try_header(header, opt)
1104            $INCFLAGS << " " << opt
1105            found = true
1106            break
1107          end
1108        end
1109        found
1110      end
1111    end
1112  end
1113
1114  # Returns whether or not the struct of type +type+ contains +member+.  If
1115  # it does not, or the struct type can't be found, then false is returned.
1116  # You may optionally specify additional +headers+ in which to look for the
1117  # struct (in addition to the common header files).
1118  #
1119  # If found, a macro is passed as a preprocessor constant to the compiler
1120  # using the type name and the member name, in uppercase, prepended with
1121  # +HAVE_+.
1122  #
1123  # For example, if <code>have_struct_member('struct foo', 'bar')</code>
1124  # returned true, then the +HAVE_STRUCT_FOO_BAR+ preprocessor macro would be
1125  # passed to the compiler.
1126  #
1127  # +HAVE_ST_BAR+ is also defined for backward compatibility.
1128  #
1129  def have_struct_member(type, member, headers = nil, opt = "", &b)
1130    checking_for checking_message("#{type}.#{member}", headers) do
1131      if try_compile(<<"SRC", opt, &b)
1132#{cpp_include(headers)}
1133/*top*/
1134int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
1135#{MAIN_DOES_NOTHING "s"}
1136SRC
1137        $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
1138        $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility
1139        true
1140      else
1141        false
1142      end
1143    end
1144  end
1145
1146  # Returns whether or not the static type +type+ is defined.
1147  #
1148  # See also +have_type+
1149  #
1150  def try_type(type, headers = nil, opt = "", &b)
1151    if try_compile(<<"SRC", opt, &b)
1152#{cpp_include(headers)}
1153/*top*/
1154typedef #{type} conftest_type;
1155int conftestval[sizeof(conftest_type)?1:-1];
1156SRC
1157      $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
1158      true
1159    else
1160      false
1161    end
1162  end
1163
1164  # Returns whether or not the static type +type+ is defined.  You may
1165  # optionally pass additional +headers+ to check against in addition to the
1166  # common header files.
1167  #
1168  # You may also pass additional flags to +opt+ which are then passed along to
1169  # the compiler.
1170  #
1171  # If found, a macro is passed as a preprocessor constant to the compiler
1172  # using the type name, in uppercase, prepended with +HAVE_TYPE_+.
1173  #
1174  # For example, if <code>have_type('foo')</code> returned true, then the
1175  # +HAVE_TYPE_FOO+ preprocessor macro would be passed to the compiler.
1176  #
1177  def have_type(type, headers = nil, opt = "", &b)
1178    checking_for checking_message(type, headers, opt) do
1179      try_type(type, headers, opt, &b)
1180    end
1181  end
1182
1183  # Returns where the static type +type+ is defined.
1184  #
1185  # You may also pass additional flags to +opt+ which are then passed along to
1186  # the compiler.
1187  #
1188  # See also +have_type+.
1189  #
1190  def find_type(type, opt, *headers, &b)
1191    opt ||= ""
1192    fmt = "not found"
1193    def fmt.%(x)
1194      x ? x.respond_to?(:join) ? x.join(",") : x : self
1195    end
1196    checking_for checking_message(type, nil, opt), fmt do
1197      headers.find do |h|
1198        try_type(type, h, opt, &b)
1199      end
1200    end
1201  end
1202
1203  # Returns whether or not the constant +const+ is defined.
1204  #
1205  # See also +have_const+
1206  #
1207  def try_const(const, headers = nil, opt = "", &b)
1208    const, type = *const
1209    if try_compile(<<"SRC", opt, &b)
1210#{cpp_include(headers)}
1211/*top*/
1212typedef #{type || 'int'} conftest_type;
1213conftest_type conftestval = #{type ? '' : '(int)'}#{const};
1214SRC
1215      $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
1216      true
1217    else
1218      false
1219    end
1220  end
1221
1222  # Returns whether or not the constant +const+ is defined.  You may
1223  # optionally pass the +type+ of +const+ as <code>[const, type]</code>,
1224  # such as:
1225  #
1226  #   have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
1227  #
1228  # You may also pass additional +headers+ to check against in addition to the
1229  # common header files, and additional flags to +opt+ which are then passed
1230  # along to the compiler.
1231  #
1232  # If found, a macro is passed as a preprocessor constant to the compiler
1233  # using the type name, in uppercase, prepended with +HAVE_CONST_+.
1234  #
1235  # For example, if <code>have_const('foo')</code> returned true, then the
1236  # +HAVE_CONST_FOO+ preprocessor macro would be passed to the compiler.
1237  #
1238  def have_const(const, headers = nil, opt = "", &b)
1239    checking_for checking_message([*const].compact.join(' '), headers, opt) do
1240      try_const(const, headers, opt, &b)
1241    end
1242  end
1243
1244  # :stopdoc:
1245  STRING_OR_FAILED_FORMAT = "%s"
1246  def STRING_OR_FAILED_FORMAT.%(x) # :nodoc:
1247    x ? super : "failed"
1248  end
1249
1250  def typedef_expr(type, headers)
1251    typename, member = type.split('.', 2)
1252    prelude = cpp_include(headers).split(/$/)
1253    prelude << "typedef #{typename} rbcv_typedef_;\n"
1254    return "rbcv_typedef_", member, prelude
1255  end
1256
1257  def try_signedness(type, member, headers = nil, opts = nil)
1258    raise ArgumentError, "don't know how to tell signedness of members" if member
1259    if try_static_assert("(#{type})-1 < 0", headers, opts)
1260      return -1
1261    elsif try_static_assert("(#{type})-1 > 0", headers, opts)
1262      return +1
1263    end
1264  end
1265
1266  # :startdoc:
1267
1268  # Returns the size of the given +type+.  You may optionally specify
1269  # additional +headers+ to search in for the +type+.
1270  #
1271  # If found, a macro is passed as a preprocessor constant to the compiler
1272  # using the type name, in uppercase, prepended with +SIZEOF_+, followed by
1273  # the type name, followed by <code>=X</code> where "X" is the actual size.
1274  #
1275  # For example, if <code>check_sizeof('mystruct')</code> returned 12, then
1276  # the <code>SIZEOF_MYSTRUCT=12</code> preprocessor macro would be passed to
1277  # the compiler.
1278  #
1279  def check_sizeof(type, headers = nil, opts = "", &b)
1280    typedef, member, prelude = typedef_expr(type, headers)
1281    prelude << "static #{typedef} *rbcv_ptr_;\n"
1282    prelude = [prelude]
1283    expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
1284    fmt = STRING_OR_FAILED_FORMAT
1285    checking_for checking_message("size of #{type}", headers), fmt do
1286      if size = try_constant(expr, prelude, opts, &b)
1287        $defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
1288        size
1289      end
1290    end
1291  end
1292
1293  # Returns the signedness of the given +type+.  You may optionally specify
1294  # additional +headers+ to search in for the +type+.
1295  #
1296  # If the +type+ is found and is a numeric type, a macro is passed as a
1297  # preprocessor constant to the compiler using the +type+ name, in uppercase,
1298  # prepended with +SIGNEDNESS_OF_+, followed by the +type+ name, followed by
1299  # <code>=X</code> where "X" is positive integer if the +type+ is unsigned
1300  # and a negative integer if the +type+ is signed.
1301  #
1302  # For example, if +size_t+ is defined as unsigned, then
1303  # <code>check_signedness('size_t')</code> would return +1 and the
1304  # <code>SIGNEDNESS_OF_SIZE_T=+1</code> preprocessor macro would be passed to
1305  # the compiler.  The <code>SIGNEDNESS_OF_INT=-1</code> macro would be set
1306  # for <code>check_signedness('int')</code>
1307  #
1308  def check_signedness(type, headers = nil, opts = nil, &b)
1309    typedef, member, prelude = typedef_expr(type, headers)
1310    signed = nil
1311    checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
1312      signed = try_signedness(typedef, member, [prelude], opts, &b) or next nil
1313      $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
1314      signed < 0 ? "signed" : "unsigned"
1315    end
1316    signed
1317  end
1318
1319  # Returns the convertible integer type of the given +type+.  You may
1320  # optionally specify additional +headers+ to search in for the +type+.
1321  # _convertible_ means actually the same type, or typedef'd from the same
1322  # type.
1323  #
1324  # If the +type+ is a integer type and the _convertible_ type is found,
1325  # the following macros are passed as preprocessor constants to the compiler
1326  # using the +type+ name, in uppercase.
1327  #
1328  # * +TYPEOF_+, followed by the +type+ name, followed by <code>=X</code>
1329  #   where "X" is the found _convertible_ type name.
1330  # * +TYP2NUM+ and +NUM2TYP+,
1331  #   where +TYP+ is the +type+ name in uppercase with replacing an +_t+
1332  #   suffix with "T", followed by <code>=X</code> where "X" is the macro name
1333  #   to convert +type+ to an Integer object, and vice versa.
1334  #
1335  # For example, if +foobar_t+ is defined as unsigned long, then
1336  # <code>convertible_int("foobar_t")</code> would return "unsigned long", and
1337  # define these macros:
1338  #
1339  #   #define TYPEOF_FOOBAR_T unsigned long
1340  #   #define FOOBART2NUM ULONG2NUM
1341  #   #define NUM2FOOBART NUM2ULONG
1342  #
1343  def convertible_int(type, headers = nil, opts = nil, &b)
1344    type, macname = *type
1345    checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do
1346      if UNIVERSAL_INTS.include?(type)
1347        type
1348      else
1349        typedef, member, prelude = typedef_expr(type, headers, &b)
1350        if member
1351          prelude << "static rbcv_typedef_ rbcv_var;"
1352          compat = UNIVERSAL_INTS.find {|t|
1353            try_static_assert("sizeof(rbcv_var.#{member}) == sizeof(#{t})", [prelude], opts, &b)
1354          }
1355        else
1356          next unless signed = try_signedness(typedef, member, [prelude])
1357          u = "unsigned " if signed > 0
1358          prelude << "extern rbcv_typedef_ foo();"
1359          compat = UNIVERSAL_INTS.find {|t|
1360            try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, :werror=>true, &b)
1361          }
1362        end
1363        if compat
1364          macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
1365          conv = (compat == "long long" ? "LL" : compat.upcase)
1366          compat = "#{u}#{compat}"
1367          typename = type.tr_cpp
1368          $defs.push(format("-DSIZEOF_%s=SIZEOF_%s", typename, compat.tr_cpp))
1369          $defs.push(format("-DTYPEOF_%s=%s", typename, compat.quote))
1370          $defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
1371          conv = (u ? "U" : "") + conv
1372          $defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
1373          $defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
1374          compat
1375        end
1376      end
1377    end
1378  end
1379  # :stopdoc:
1380
1381  # Used internally by the what_type? method to determine if +type+ is a scalar
1382  # pointer.
1383  def scalar_ptr_type?(type, member = nil, headers = nil, &b)
1384    try_compile(<<"SRC", &b)   # pointer
1385#{cpp_include(headers)}
1386/*top*/
1387volatile #{type} conftestval;
1388extern int t(void);
1389int t(void) {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
1390#{MAIN_DOES_NOTHING "t"}
1391SRC
1392  end
1393
1394  # Used internally by the what_type? method to determine if +type+ is a scalar
1395  # pointer.
1396  def scalar_type?(type, member = nil, headers = nil, &b)
1397    try_compile(<<"SRC", &b)   # pointer
1398#{cpp_include(headers)}
1399/*top*/
1400volatile #{type} conftestval;
1401extern int t(void);
1402int t(void) {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
1403#{MAIN_DOES_NOTHING "t"}
1404SRC
1405  end
1406
1407  # Used internally by the what_type? method to check if the _typeof_ GCC
1408  # extension is available.
1409  def have_typeof?
1410    return $typeof if defined?($typeof)
1411    $typeof = %w[__typeof__ typeof].find do |t|
1412      try_compile(<<SRC)
1413int rbcv_foo;
1414#{t}(rbcv_foo) rbcv_bar;
1415SRC
1416    end
1417  end
1418
1419  def what_type?(type, member = nil, headers = nil, &b)
1420    m = "#{type}"
1421    var = val = "*rbcv_var_"
1422    func = "rbcv_func_(void)"
1423    if member
1424      m << "." << member
1425    else
1426      type, member = type.split('.', 2)
1427    end
1428    if member
1429      val = "(#{var}).#{member}"
1430    end
1431    prelude = [cpp_include(headers).split(/^/)]
1432    prelude << ["typedef #{type} rbcv_typedef_;\n",
1433                "extern rbcv_typedef_ *#{func};\n",
1434                "static rbcv_typedef_ #{var};\n",
1435               ]
1436    type = "rbcv_typedef_"
1437    fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s"
1438    if typeof
1439      var = "*rbcv_member_"
1440      func = "rbcv_mem_func_(void)"
1441      member = nil
1442      type = "rbcv_mem_typedef_"
1443      prelude[-1] << "typedef #{typeof}(#{val}) #{type};\n"
1444      prelude[-1] << "extern #{type} *#{func};\n"
1445      prelude[-1] << "static #{type} #{var};\n"
1446      val = var
1447    end
1448    def fmt.%(x)
1449      x ? super : "unknown"
1450    end
1451    checking_for checking_message(m, headers), fmt do
1452      if scalar_ptr_type?(type, member, prelude, &b)
1453        if try_static_assert("sizeof(*#{var}) == 1", prelude)
1454          return "string"
1455        end
1456        ptr = "*"
1457      elsif scalar_type?(type, member, prelude, &b)
1458        unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude)
1459          unsigned = "unsigned"
1460        end
1461        ptr = ""
1462      else
1463        next
1464      end
1465      type = UNIVERSAL_INTS.find do |t|
1466        pre = prelude
1467        unless member
1468          pre += [["static #{unsigned} #{t} #{ptr}#{var};\n",
1469                   "extern #{unsigned} #{t} #{ptr}*#{func};\n"]]
1470        end
1471        try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre)
1472      end
1473      type or next
1474      [unsigned, type, ptr].join(" ").strip
1475    end
1476  end
1477
1478  # This method is used internally by the find_executable method.
1479  #
1480  # Internal use only.
1481  #
1482  def find_executable0(bin, path = nil)
1483    executable_file = proc do |name|
1484      begin
1485        stat = File.stat(name)
1486      rescue SystemCallError
1487      else
1488        next name if stat.file? and stat.executable?
1489      end
1490    end
1491
1492    exts = config_string('EXECUTABLE_EXTS') {|s| s.split} || config_string('EXEEXT') {|s| [s]}
1493    if File.expand_path(bin) == bin
1494      return bin if executable_file.call(bin)
1495      if exts
1496        exts.each {|ext| executable_file.call(file = bin + ext) and return file}
1497      end
1498      return nil
1499    end
1500    if path ||= ENV['PATH']
1501      path = path.split(File::PATH_SEPARATOR)
1502    else
1503      path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
1504    end
1505    file = nil
1506    path.each do |dir|
1507      return file if executable_file.call(file = File.join(dir, bin))
1508      if exts
1509        exts.each {|ext| executable_file.call(ext = file + ext) and return ext}
1510      end
1511    end
1512    nil
1513  end
1514
1515  # :startdoc:
1516
1517  # Searches for the executable +bin+ on +path+.  The default path is your
1518  # +PATH+ environment variable. If that isn't defined, it will resort to
1519  # searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
1520  #
1521  # If found, it will return the full path, including the executable name, of
1522  # where it was found.
1523  #
1524  # Note that this method does not actually affect the generated Makefile.
1525  #
1526  def find_executable(bin, path = nil)
1527    checking_for checking_message(bin, path) do
1528      find_executable0(bin, path)
1529    end
1530  end
1531
1532  # :stopdoc:
1533
1534  def arg_config(config, default=nil, &block)
1535    $arg_config << [config, default]
1536    defaults = []
1537    if default
1538      defaults << default
1539    elsif !block
1540      defaults << nil
1541    end
1542    $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
1543  end
1544
1545  # :startdoc:
1546
1547  # Tests for the presence of a <tt>--with-</tt>_config_ or
1548  # <tt>--without-</tt>_config_ option.  Returns +true+ if the with option is
1549  # given, +false+ if the without option is given, and the default value
1550  # otherwise.
1551  #
1552  # This can be useful for adding custom definitions, such as debug
1553  # information.
1554  #
1555  # Example:
1556  #
1557  #    if with_config("debug")
1558  #       $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1559  #    end
1560  #
1561  def with_config(config, default=nil)
1562    config = config.sub(/^--with[-_]/, '')
1563    val = arg_config("--with-"+config) do
1564      if arg_config("--without-"+config)
1565        false
1566      elsif block_given?
1567        yield(config, default)
1568      else
1569        break default
1570      end
1571    end
1572    case val
1573    when "yes"
1574      true
1575    when "no"
1576      false
1577    else
1578      val
1579    end
1580  end
1581
1582  # Tests for the presence of an <tt>--enable-</tt>_config_ or
1583  # <tt>--disable-</tt>_config_ option. Returns +true+ if the enable option is
1584  # given, +false+ if the disable option is given, and the default value
1585  # otherwise.
1586  #
1587  # This can be useful for adding custom definitions, such as debug
1588  # information.
1589  #
1590  # Example:
1591  #
1592  #    if enable_config("debug")
1593  #       $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1594  #    end
1595  #
1596  def enable_config(config, default=nil)
1597    if arg_config("--enable-"+config)
1598      true
1599    elsif arg_config("--disable-"+config)
1600      false
1601    elsif block_given?
1602      yield(config, default)
1603    else
1604      return default
1605    end
1606  end
1607
1608  # Generates a header file consisting of the various macro definitions
1609  # generated by other methods such as have_func and have_header. These are
1610  # then wrapped in a custom <code>#ifndef</code> based on the +header+ file
1611  # name, which defaults to "extconf.h".
1612  #
1613  # For example:
1614  #
1615  #   # extconf.rb
1616  #   require 'mkmf'
1617  #   have_func('realpath')
1618  #   have_header('sys/utime.h')
1619  #   create_header
1620  #   create_makefile('foo')
1621  #
1622  # The above script would generate the following extconf.h file:
1623  #
1624  #   #ifndef EXTCONF_H
1625  #   #define EXTCONF_H
1626  #   #define HAVE_REALPATH 1
1627  #   #define HAVE_SYS_UTIME_H 1
1628  #   #endif
1629  #
1630  # Given that the create_header method generates a file based on definitions
1631  # set earlier in your extconf.rb file, you will probably want to make this
1632  # one of the last methods you call in your script.
1633  #
1634  def create_header(header = "extconf.h")
1635    message "creating %s\n", header
1636    sym = header.tr_cpp
1637    hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1638    for line in $defs
1639      case line
1640      when /^-D([^=]+)(?:=(.*))?/
1641        hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
1642      when /^-U(.*)/
1643        hdr << "#undef #$1\n"
1644      end
1645    end
1646    hdr << "#endif\n"
1647    hdr = hdr.join("")
1648    log_src(hdr, "#{header} is")
1649    unless (IO.read(header) == hdr rescue false)
1650      open(header, "wb") do |hfile|
1651        hfile.write(hdr)
1652      end
1653    end
1654    $extconf_h = header
1655  end
1656
1657  # Sets a +target+ name that the user can then use to configure various
1658  # "with" options with on the command line by using that name.  For example,
1659  # if the target is set to "foo", then the user could use the
1660  # <code>--with-foo-dir</code> command line option.
1661  #
1662  # You may pass along additional "include" or "lib" defaults via the
1663  # +idefault+ and +ldefault+ parameters, respectively.
1664  #
1665  # Note that dir_config only adds to the list of places to search for
1666  # libraries and include files.  It does not link the libraries into your
1667  # application.
1668  #
1669  def dir_config(target, idefault=nil, ldefault=nil)
1670    if dir = with_config(target + "-dir", (idefault unless ldefault))
1671      defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
1672      idefault = ldefault = nil
1673    end
1674
1675    idir = with_config(target + "-include", idefault)
1676    $arg_config.last[1] ||= "${#{target}-dir}/include"
1677    ldir = with_config(target + "-lib", ldefault)
1678    $arg_config.last[1] ||= "${#{target}-dir}/#{@libdir_basename}"
1679
1680    idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
1681    if defaults
1682      idirs.concat(defaults.collect {|d| d + "/include"})
1683      idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1684    end
1685    unless idirs.empty?
1686      idirs.collect! {|d| "-I" + d}
1687      idirs -= Shellwords.shellwords($CPPFLAGS)
1688      unless idirs.empty?
1689        $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1690      end
1691    end
1692
1693    ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : []
1694    if defaults
1695      ldirs.concat(defaults.collect {|d| "#{d}/#{@libdir_basename}"})
1696      ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1697    end
1698    $LIBPATH = ldirs | $LIBPATH
1699
1700    [idir, ldir]
1701  end
1702
1703  # :stopdoc:
1704
1705  # Handles meta information about installed libraries. Uses your platform's
1706  # pkg-config program if it has one.
1707  #
1708  # The actual command name can be overridden by
1709  # <code>--with-pkg-config</code> command line option.
1710  def pkg_config(pkg)
1711    if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1712      # iff package specific config command is given
1713      get = proc {|opt| `#{pkgconfig} --#{opt}`.strip}
1714    elsif ($PKGCONFIG ||=
1715           (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1716           find_executable0(pkgconfig) && pkgconfig) and
1717        system("#{$PKGCONFIG} --exists #{pkg}")
1718      # default to pkg-config command
1719      get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.strip}
1720    elsif find_executable0(pkgconfig = "#{pkg}-config")
1721      # default to package specific config command, as a last resort.
1722      get = proc {|opt| `#{pkgconfig} --#{opt}`.strip}
1723    end
1724    orig_ldflags = $LDFLAGS
1725    if get and try_ldflags(ldflags = get['libs'])
1726      cflags = get['cflags']
1727      libs = get['libs-only-l']
1728      ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
1729      $CFLAGS += " " << cflags
1730      $LDFLAGS = [orig_ldflags, ldflags].join(' ')
1731      $libs += " " << libs
1732      Logging::message "package configuration for %s\n", pkg
1733      Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
1734                       cflags, ldflags, libs
1735      [cflags, ldflags, libs]
1736    else
1737      Logging::message "package configuration for %s is not found\n", pkg
1738      nil
1739    end
1740  end
1741
1742  def with_destdir(dir)
1743    return dir unless $extmk
1744    dir = dir.sub($dest_prefix_pattern, '')
1745    /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
1746  end
1747
1748  # Converts forward slashes to backslashes. Aimed at MS Windows.
1749  #
1750  # Internal use only.
1751  #
1752  def winsep(s)
1753    s.tr('/', '\\')
1754  end
1755
1756  # Converts native path to format acceptable in Makefile
1757  #
1758  # Internal use only.
1759  #
1760  if !CROSS_COMPILING
1761    case CONFIG['build_os']
1762    when 'mingw32'
1763      def mkintpath(path)
1764        # mingw uses make from msys and it needs special care
1765        # converts from C:\some\path to /C/some/path
1766        path = path.dup
1767        path.tr!('\\', '/')
1768        path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
1769        path
1770      end
1771    when 'cygwin'
1772      if CONFIG['target_os'] != 'cygwin'
1773        def mkintpath(path)
1774          IO.popen(["cygpath", "-u", path], &:read).chomp
1775        end
1776      end
1777    end
1778  end
1779  unless method_defined?(:mkintpath)
1780    def mkintpath(path)
1781      path
1782    end
1783  end
1784
1785  def configuration(srcdir)
1786    mk = []
1787    vpath = $VPATH.dup
1788    CONFIG["hdrdir"] ||= $hdrdir
1789    mk << %{
1790SHELL = /bin/sh
1791
1792# V=0 quiet, V=1 verbose.  other values don't work.
1793V = 0
1794Q1 = $(V:1=)
1795Q = $(Q1:0=@)
1796ECHO1 = $(V:1=@#{CONFIG['NULLCMD']})
1797ECHO = $(ECHO1:0=@echo)
1798
1799#### Start of system configuration section. ####
1800#{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk}
1801srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2]).unspace}}
1802topdir = #{mkintpath(topdir = $extmk ? CONFIG["topdir"] : $topdir).unspace}
1803hdrdir = #{(hdrdir = CONFIG["hdrdir"]) == topdir ? "$(topdir)" : mkintpath(hdrdir).unspace}
1804arch_hdrdir = #{$arch_hdrdir.quote}
1805PATH_SEPARATOR = #{CONFIG['PATH_SEPARATOR']}
1806VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
1807}
1808    if $extmk
1809      mk << "RUBYLIB =\n""RUBYOPT = -\n"
1810    end
1811    prefix = mkintpath(CONFIG["prefix"])
1812    if destdir = prefix[$dest_prefix_pattern, 1]
1813      mk << "\nDESTDIR = #{destdir}\n"
1814      prefix = prefix[destdir.size..-1]
1815    end
1816    mk << "prefix = #{with_destdir(prefix).unspace}\n"
1817    CONFIG.each do |key, var|
1818      mk << "#{key} = #{with_destdir(mkintpath(var)).unspace}\n" if /.prefix$/ =~ key
1819    end
1820    CONFIG.each do |key, var|
1821      next if /^abs_/ =~ key
1822      next if /^(?:src|top|hdr)dir$/ =~ key
1823      next unless /dir$/ =~ key
1824      mk << "#{key} = #{with_destdir(var)}\n"
1825    end
1826    if !$extmk and !$configure_args.has_key?('--ruby') and
1827        sep = config_string('BUILD_FILE_SEPARATOR')
1828      sep = ":/=#{sep}"
1829    else
1830      sep = ""
1831    end
1832    possible_command = (proc {|s| s if /top_srcdir/ !~ s} unless $extmk)
1833    extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ") << " "
1834    headers = %w[$(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h]
1835    if RULE_SUBST
1836      headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))}
1837    end
1838    headers << $config_h
1839    headers << '$(RUBY_EXTCONF_H)' if $extconf_h
1840    mk << %{
1841
1842CC = #{CONFIG['CC']}
1843CXX = #{CONFIG['CXX']}
1844LIBRUBY = #{CONFIG['LIBRUBY']}
1845LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
1846LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
1847LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
1848empty =
1849OUTFLAG = #{OUTFLAG}$(empty)
1850COUTFLAG = #{COUTFLAG}$(empty)
1851
1852RUBY_EXTCONF_H = #{$extconf_h}
1853cflags   = #{CONFIG['cflags']}
1854optflags = #{CONFIG['optflags']}
1855debugflags = #{CONFIG['debugflags']}
1856warnflags = #{$warnflags}
1857CCDLFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']}
1858CFLAGS   = $(CCDLFLAGS) #$CFLAGS $(ARCH_FLAG)
1859INCFLAGS = -I. #$INCFLAGS
1860DEFS     = #{CONFIG['DEFS']}
1861CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
1862CXXFLAGS = $(CCDLFLAGS) #{CONFIG['CXXFLAGS']} $(ARCH_FLAG)
1863ldflags  = #{$LDFLAGS}
1864dldflags = #{$DLDFLAGS} #{CONFIG['EXTDLDFLAGS']}
1865ARCH_FLAG = #{$ARCH_FLAG}
1866DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
1867LDSHARED = #{CONFIG['LDSHARED']}
1868LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'}
1869AR = #{CONFIG['AR']}
1870EXEEXT = #{CONFIG['EXEEXT']}
1871
1872}
1873    CONFIG.each do |key, val|
1874      mk << "#{key} = #{val}\n" if /^RUBY.*NAME/ =~ key
1875    end
1876    mk << %{
1877arch = #{CONFIG['arch']}
1878sitearch = #{CONFIG['sitearch']}
1879ruby_version = #{RbConfig::CONFIG['ruby_version']}
1880ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}}
1881RUBY = $(ruby#{sep})
1882ruby_headers = #{headers.join(' ')}
1883
1884RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'}
1885RM_RF = #{'$(RUBY) -run -e rm -- -rf'}
1886RMDIRS = #{config_string('RMDIRS', &possible_command) || '$(RUBY) -run -e rmdir -- -p'}
1887MAKEDIRS = #{config_string('MAKEDIRS', &possible_command) || '@$(RUBY) -run -e mkdir -- -p'}
1888INSTALL = #{config_string('INSTALL', &possible_command) || '@$(RUBY) -run -e install -- -vp'}
1889INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
1890INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
1891COPY = #{config_string('CP', &possible_command) || '@$(RUBY) -run -e cp -- -v'}
1892TOUCH = exit >
1893
1894#### End of system configuration section. ####
1895
1896preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''}
1897}
1898    if $nmake == ?b
1899      mk.each do |x|
1900        x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
1901          "!ifndef " + $1 + "\n" +
1902          $& +
1903          "!endif\n"
1904        end
1905      end
1906    end
1907    mk
1908  end
1909
1910  def timestamp_file(name)
1911    name = name.gsub(/(\$[({]|[})])|(\/+)|[^-.\w]+/) {$1 ? "" : $2 ? ".-." : "_"}
1912    "./.#{name}.time"
1913  end
1914  # :startdoc:
1915
1916  # creates a stub Makefile.
1917  #
1918  def dummy_makefile(srcdir)
1919    configuration(srcdir) << <<RULES << CLEANINGS
1920CLEANFILES = #{$cleanfiles.join(' ')}
1921DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1922
1923all install static install-so install-rb: Makefile
1924.PHONY: all install static install-so install-rb
1925.PHONY: clean clean-so clean-static clean-rb
1926
1927RULES
1928  end
1929
1930  def each_compile_rules # :nodoc:
1931    vpath_splat = /\$\(\*VPATH\*\)/
1932    COMPILE_RULES.each do |rule|
1933      if vpath_splat =~ rule
1934        $VPATH.each do |path|
1935          yield rule.sub(vpath_splat) {path}
1936        end
1937      else
1938        yield rule
1939      end
1940    end
1941  end
1942
1943  # Processes the data contents of the "depend" file.  Each line of this file
1944  # is expected to be a file name.
1945  #
1946  # Returns the output of findings, in Makefile format.
1947  #
1948  def depend_rules(depend)
1949    suffixes = []
1950    depout = []
1951    cont = implicit = nil
1952    impconv = proc do
1953      each_compile_rules {|rule| depout << (rule % implicit[0]) << implicit[1]}
1954      implicit = nil
1955    end
1956    ruleconv = proc do |line|
1957      if implicit
1958        if /\A\t/ =~ line
1959          implicit[1] << line
1960          next
1961        else
1962          impconv[]
1963        end
1964      end
1965      if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1966        suffixes << m[1] << m[2]
1967        implicit = [[m[1], m[2]], [m.post_match]]
1968        next
1969      elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1970        line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1971      end
1972      depout << line
1973    end
1974    depend.each_line do |line|
1975      line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1976      line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
1977      line.gsub!(%r"\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
1978      if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
1979        line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")}
1980        line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\')
1981      end
1982      if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1983        (cont ||= []) << line
1984        next
1985      elsif cont
1986        line = (cont << line).join
1987        cont = nil
1988      end
1989      ruleconv.call(line)
1990    end
1991    if cont
1992      ruleconv.call(cont.join)
1993    elsif implicit
1994      impconv.call
1995    end
1996    unless suffixes.empty?
1997      depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
1998    end
1999    depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") if $extconf_h
2000    depout.flatten!
2001    depout
2002  end
2003
2004  # Generates the Makefile for your extension, passing along any options and
2005  # preprocessor constants that you may have generated through other methods.
2006  #
2007  # The +target+ name should correspond the name of the global function name
2008  # defined within your C extension, minus the +Init_+.  For example, if your
2009  # C extension is defined as +Init_foo+, then your target would simply be
2010  # "foo".
2011  #
2012  # If any "/" characters are present in the target name, only the last name
2013  # is interpreted as the target name, and the rest are considered toplevel
2014  # directory names, and the generated Makefile will be altered accordingly to
2015  # follow that directory structure.
2016  #
2017  # For example, if you pass "test/foo" as a target name, your extension will
2018  # be installed under the "test" directory.  This means that in order to
2019  # load the file within a Ruby program later, that directory structure will
2020  # have to be followed, e.g. <code>require 'test/foo'</code>.
2021  #
2022  # The +srcprefix+ should be used when your source files are not in the same
2023  # directory as your build script. This will not only eliminate the need for
2024  # you to manually copy the source files into the same directory as your
2025  # build script, but it also sets the proper +target_prefix+ in the generated
2026  # Makefile.
2027  #
2028  # Setting the +target_prefix+ will, in turn, install the generated binary in
2029  # a directory under your <code>RbConfig::CONFIG['sitearchdir']</code> that
2030  # mimics your local filesystem when you run <code>make install</code>.
2031  #
2032  # For example, given the following file tree:
2033  #
2034  #   ext/
2035  #     extconf.rb
2036  #     test/
2037  #       foo.c
2038  #
2039  # And given the following code:
2040  #
2041  #   create_makefile('test/foo', 'test')
2042  #
2043  # That will set the +target_prefix+ in the generated Makefile to "test".
2044  # That, in turn, will create the following file tree when installed via the
2045  # <code>make install</code> command:
2046  #
2047  #   /path/to/ruby/sitearchdir/test/foo.so
2048  #
2049  # It is recommended that you use this approach to generate your makefiles,
2050  # instead of copying files around manually, because some third party
2051  # libraries may depend on the +target_prefix+ being set properly.
2052  #
2053  # The +srcprefix+ argument can be used to override the default source
2054  # directory, i.e. the current directory.  It is included as part of the
2055  # +VPATH+ and added to the list of +INCFLAGS+.
2056  #
2057  def create_makefile(target, srcprefix = nil)
2058    $target = target
2059    libpath = $DEFLIBPATH|$LIBPATH
2060    message "creating Makefile\n"
2061    MakeMakefile.rm_f "conftest*"
2062    if CONFIG["DLEXT"] == $OBJEXT
2063      for lib in libs = $libs.split
2064        lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
2065      end
2066      $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
2067    end
2068
2069    if target.include?('/')
2070      target_prefix, target = File.split(target)
2071      target_prefix[0,0] = '/'
2072    else
2073      target_prefix = ""
2074    end
2075
2076    srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
2077    RbConfig.expand(srcdir = srcprefix.dup)
2078
2079    ext = ".#{$OBJEXT}"
2080    orig_srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
2081    if not $objs
2082      srcs = $srcs || orig_srcs
2083      objs = srcs.inject(Hash.new {[]}) {|h, f| h[File.basename(f, ".*") << ext] <<= f; h}
2084      $objs = objs.keys
2085      unless objs.delete_if {|b, f| f.size == 1}.empty?
2086        dups = objs.sort.map {|b, f|
2087          "#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}"
2088        }
2089        abort "source files duplication - #{dups.join(", ")}"
2090      end
2091    else
2092      $objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
2093      srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
2094    end
2095    $srcs = srcs
2096
2097    hdrs = Dir[File.join(srcdir, "*.{#{HDR_EXT.join(%q{,})}}")]
2098
2099    target = nil if $objs.empty?
2100
2101    if target and EXPORT_PREFIX
2102      if File.exist?(File.join(srcdir, target + '.def'))
2103        deffile = "$(srcdir)/$(TARGET).def"
2104        unless EXPORT_PREFIX.empty?
2105          makedef = %{-pe "$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
2106        end
2107      else
2108        makedef = %{-e "puts 'EXPORTS', '$(TARGET_ENTRY)'"}
2109      end
2110      if makedef
2111        $cleanfiles << '$(DEFFILE)'
2112        origdef = deffile
2113        deffile = "$(TARGET)-$(arch).def"
2114      end
2115    end
2116    origdef ||= ''
2117
2118    if $extout and $INSTALLFILES
2119      $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.sub(/\A\.\//, ''))})
2120      $distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir})
2121    end
2122
2123    if $extmk and not $extconf_h
2124      create_header
2125    end
2126
2127    libpath = libpathflag(libpath)
2128
2129    dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
2130    staticlib = target ? "$(TARGET).#$LIBEXT" : ""
2131    mfile = open("Makefile", "wb")
2132    conf = configuration(srcprefix)
2133    conf = yield(conf) if block_given?
2134    mfile.puts(conf)
2135    mfile.print "
2136libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
2137LIBPATH = #{libpath}
2138DEFFILE = #{deffile}
2139
2140CLEANFILES = #{$cleanfiles.join(' ')}
2141DISTCLEANFILES = #{$distcleanfiles.join(' ')}
2142DISTCLEANDIRS = #{$distcleandirs.join(' ')}
2143
2144extout = #{$extout && $extout.quote}
2145extout_prefix = #{$extout_prefix}
2146target_prefix = #{target_prefix}
2147LOCAL_LIBS = #{$LOCAL_LIBS}
2148LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
2149ORIG_SRCS = #{orig_srcs.collect(&File.method(:basename)).join(' ')}
2150SRCS = $(ORIG_SRCS) #{(srcs - orig_srcs).collect(&File.method(:basename)).join(' ')}
2151OBJS = #{$objs.join(" ")}
2152HDRS = #{hdrs.map{|h| '$(srcdir)/' + File.basename(h)}.join(' ')}
2153TARGET = #{target}
2154TARGET_NAME = #{target && target[/\A\w+/]}
2155TARGET_ENTRY = #{EXPORT_PREFIX || ''}Init_$(TARGET_NAME)
2156DLLIB = #{dllib}
2157EXTSTATIC = #{$static || ""}
2158STATIC_LIB = #{staticlib unless $static.nil?}
2159#{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
2160" #"
2161    # TODO: fixme
2162    install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
2163    n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET)'
2164    mfile.print "
2165TARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
2166CLEANLIBS     = #{n}.#{CONFIG['DLEXT']} #{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
2167CLEANOBJS     = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")} if target} *.bak
2168
2169all:    #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
2170static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
2171.PHONY: all install static install-so install-rb
2172.PHONY: clean clean-so clean-static clean-rb
2173"
2174    mfile.print CLEANINGS
2175    fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"}
2176    if fsep
2177      sep = ":/=#{fsep}"
2178      fseprepl = proc {|s|
2179        s = s.gsub("/", fsep)
2180        s = s.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
2181        s = s.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
2182      }
2183      rsep = ":#{fsep}=/"
2184    else
2185      fseprepl = proc {|s| s}
2186      sep = ""
2187      rsep = ""
2188    end
2189    dirs = []
2190    mfile.print "install: install-so install-rb\n\n"
2191    sodir = (dir = "$(RUBYARCHDIR)").dup
2192    mfile.print("install-so: ")
2193    if target
2194      f = "$(DLLIB)"
2195      dest = "#{dir}/#{f}"
2196      if $extout
2197        mfile.puts dest
2198        mfile.print "clean-so::\n"
2199        mfile.print "\t-$(Q)$(RM) #{fseprepl[dest]}\n"
2200        mfile.print "\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n"
2201      else
2202        mfile.print "#{f} #{timestamp_file(dir)}\n"
2203        mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n"
2204        if defined?($installed_list)
2205          mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
2206        end
2207      end
2208      mfile.print "clean-static::\n"
2209      mfile.print "\t-$(Q)$(RM) $(STATIC_LIB)\n"
2210    else
2211      mfile.puts "Makefile"
2212    end
2213    mfile.print("install-rb: pre-install-rb install-rb-default\n")
2214    mfile.print("install-rb-default: pre-install-rb-default\n")
2215    mfile.print("pre-install-rb: Makefile\n")
2216    mfile.print("pre-install-rb-default: Makefile\n")
2217    for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
2218      files = install_files(mfile, i, nil, srcprefix) or next
2219      for dir, *files in files
2220        unless dirs.include?(dir)
2221          dirs << dir
2222          mfile.print "pre-install-rb#{sfx}: #{timestamp_file(dir)}\n"
2223        end
2224        for f in files
2225          dest = "#{dir}/#{File.basename(f)}"
2226          mfile.print("install-rb#{sfx}: #{dest}\n")
2227          mfile.print("#{dest}: #{f} #{timestamp_file(dir)}\n")
2228          mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
2229          if defined?($installed_list) and !$extout
2230            mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
2231          end
2232          if $extout
2233            mfile.print("clean-rb#{sfx}::\n")
2234            mfile.print("\t-$(Q)$(RM) #{fseprepl[dest]}\n")
2235          end
2236        end
2237      end
2238      mfile.print "pre-install-rb#{sfx}:\n"
2239      mfile.print("\t$(ECHO) installing#{sfx.sub(/^-/, " ")} #{target} libraries\n")
2240      if $extout
2241        dirs.uniq!
2242        unless dirs.empty?
2243          mfile.print("clean-rb#{sfx}::\n")
2244          for dir in dirs.sort_by {|d| -d.count('/')}
2245            mfile.print("\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n")
2246          end
2247        end
2248      end
2249    end
2250    dirs.unshift(sodir) if target and !dirs.include?(sodir)
2251    dirs.each do |d|
2252      t = timestamp_file(d)
2253      mfile.print "#{t}:\n\t$(Q) $(MAKEDIRS) #{d}\n\t$(Q) $(TOUCH) $@\n"
2254    end
2255
2256    mfile.print <<-SITEINSTALL
2257
2258site-install: site-install-so site-install-rb
2259site-install-so: install-so
2260site-install-rb: install-rb
2261
2262    SITEINSTALL
2263
2264    return unless target
2265
2266    mfile.puts SRC_EXT.collect {|e| ".path.#{e} = $(VPATH)"} if $nmake == ?b
2267    mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
2268    mfile.print "\n"
2269
2270    compile_command = "\n\t$(ECHO) compiling $(<#{rsep})\n\t$(Q) %s\n\n"
2271    CXX_EXT.each do |e|
2272      each_compile_rules do |rule|
2273        mfile.printf(rule, e, $OBJEXT)
2274        mfile.printf(compile_command, COMPILE_CXX)
2275      end
2276    end
2277    C_EXT.each do |e|
2278      each_compile_rules do |rule|
2279        mfile.printf(rule, e, $OBJEXT)
2280        mfile.printf(compile_command, COMPILE_C)
2281      end
2282    end
2283
2284    mfile.print "$(RUBYARCHDIR)/" if $extout
2285    mfile.print "$(DLLIB): "
2286    mfile.print "$(DEFFILE) " if makedef
2287    mfile.print "$(OBJS) Makefile"
2288    mfile.print " #{timestamp_file('$(RUBYARCHDIR)')}" if $extout
2289    mfile.print "\n"
2290    mfile.print "\t$(ECHO) linking shared-object #{target_prefix.sub(/\A\/(.*)/, '\1/')}$(DLLIB)\n"
2291    mfile.print "\t-$(Q)$(RM) $(@#{sep})\n"
2292    link_so = LINK_SO.gsub(/^/, "\t$(Q) ")
2293    if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===))
2294      link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
2295    end
2296    mfile.print link_so, "\n\n"
2297    unless $static.nil?
2298      mfile.print "$(STATIC_LIB): $(OBJS)\n\t-$(Q)$(RM) $(@#{sep})\n\t"
2299      mfile.print "$(ECHO) linking static-library $(@#{rsep})\n\t$(Q) "
2300      mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
2301      config_string('RANLIB') do |ranlib|
2302        mfile.print "\n\t-$(Q)#{ranlib} $(DLLIB) 2> /dev/null || true"
2303      end
2304    end
2305    mfile.print "\n\n"
2306    if makedef
2307      mfile.print "$(DEFFILE): #{origdef}\n"
2308      mfile.print "\t$(ECHO) generating $(@#{rsep})\n"
2309      mfile.print "\t$(Q) $(RUBY) #{makedef} #{origdef} > $@\n\n"
2310    end
2311
2312    depend = File.join(srcdir, "depend")
2313    if File.exist?(depend)
2314      mfile.print("###\n", *depend_rules(File.read(depend)))
2315    else
2316      mfile.print "$(OBJS): $(HDRS) $(ruby_headers)\n"
2317    end
2318
2319    $makefile_created = true
2320  ensure
2321    mfile.close if mfile
2322  end
2323
2324  # :stopdoc:
2325
2326  def init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG)
2327    $makefile_created = false
2328    $arg_config = []
2329    $enable_shared = config['ENABLE_SHARED'] == 'yes'
2330    $defs = []
2331    $extconf_h = nil
2332    if $warnflags = CONFIG['warnflags'] and CONFIG['GCC'] == 'yes'
2333      # turn warnings into errors only for bundled extensions.
2334      config['warnflags'] = $warnflags.gsub(/(\A|\s)-Werror[-=]/, '\1-W')
2335      RbConfig.expand(rbconfig['warnflags'] = config['warnflags'].dup)
2336      config.each do |key, val|
2337        RbConfig.expand(rbconfig[key] = val.dup) if /warnflags/ =~ val
2338      end
2339      $warnflags = config['warnflags'] unless $extmk
2340    end
2341    $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
2342    $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
2343    $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
2344    $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
2345    $INCFLAGS = "-I$(arch_hdrdir)"
2346    $INCFLAGS << " -I$(hdrdir)/ruby/backward" unless $extmk
2347    $INCFLAGS << " -I$(hdrdir) -I$(srcdir)"
2348    $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
2349    $LIBEXT = config['LIBEXT'].dup
2350    $OBJEXT = config["OBJEXT"].dup
2351    $EXEEXT = config["EXEEXT"].dup
2352    $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
2353    $LIBRUBYARG = ""
2354    $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
2355    $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
2356    $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
2357    $DEFLIBPATH.unshift(".")
2358    $LIBPATH = []
2359    $INSTALLFILES = []
2360    $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
2361    $VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby]
2362
2363    $objs = nil
2364    $srcs = nil
2365    $libs = ""
2366    if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup)
2367      $LIBRUBYARG = config['LIBRUBYARG']
2368    end
2369
2370    $LOCAL_LIBS = ""
2371
2372    $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
2373    $cleanfiles << "mkmf.log"
2374    $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
2375    $distcleandirs = config_string('DISTCLEANDIRS') {|s| Shellwords.shellwords(s)} || []
2376
2377    $extout ||= nil
2378    $extout_prefix ||= nil
2379
2380    @libdir_basename = config["libdir"] && config["libdir"][/\A\$\(exec_prefix\)\/(.*)/, 1] or "lib"
2381
2382    $arg_config.clear
2383    dir_config("opt")
2384  end
2385
2386  FailedMessage = <<MESSAGE
2387Could not create Makefile due to some reason, probably lack of necessary
2388libraries and/or headers.  Check the mkmf.log file for more details.  You may
2389need configuration options.
2390
2391Provided configuration options:
2392MESSAGE
2393
2394  # Returns whether or not the Makefile was successfully generated. If not,
2395  # the script will abort with an error message.
2396  #
2397  # Internal use only.
2398  #
2399  def mkmf_failed(path)
2400    unless $makefile_created or File.exist?("Makefile")
2401      opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
2402      abort "*** #{path} failed ***\n" + FailedMessage + opts.join
2403    end
2404  end
2405
2406  def MAIN_DOES_NOTHING(*refs)
2407    src = MAIN_DOES_NOTHING
2408    unless refs.empty?
2409      src = src.sub(/\{/) do
2410        $& +
2411          "\n  if (argc > 1000000) {\n" +
2412          refs.map {|n|"    printf(\"%p\", &#{n});\n"}.join("") +
2413          "  }\n"
2414      end
2415    end
2416    src
2417  end
2418
2419  extend self
2420  init_mkmf
2421
2422  $make = with_config("make-prog", ENV["MAKE"] || "make")
2423  make, = Shellwords.shellwords($make)
2424  $nmake = nil
2425  case
2426  when $mswin
2427    $nmake = ?m if /nmake/i =~ make
2428  when $bccwin
2429    $nmake = ?b if /Borland/i =~ `#{make} -h`
2430  end
2431  $ignore_error = $nmake ? '' : ' 2> /dev/null || true'
2432
2433  RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
2434    $srcdir = arg_config("--srcdir", File.dirname($0))
2435  $configure_args["--topsrcdir"] ||= $srcdir
2436  if $curdir = arg_config("--curdir")
2437    RbConfig.expand(curdir = $curdir.dup)
2438  else
2439    curdir = $curdir = "."
2440  end
2441  unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir)
2442    CONFIG["topdir"] = $curdir
2443    RbConfig::CONFIG["topdir"] = curdir
2444  end
2445  $configure_args["--topdir"] ||= $curdir
2446  $ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"]))
2447
2448  # :startdoc:
2449
2450  split = Shellwords.method(:shellwords).to_proc
2451
2452  EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
2453
2454  hdr = ['#include "ruby.h"' "\n"]
2455  config_string('COMMON_MACROS') do |s|
2456    Shellwords.shellwords(s).each do |w|
2457      w, v = w.split(/=/, 2)
2458      hdr << "#ifndef #{w}"
2459      hdr << "#define #{[w, v].compact.join(" ")}"
2460      hdr << "#endif /* #{w} */"
2461    end
2462  end
2463  config_string('COMMON_HEADERS') do |s|
2464    Shellwords.shellwords(s).each {|w| hdr << "#include <#{w}>"}
2465  end
2466
2467  ##
2468  # Common headers for ruby C extensions
2469
2470  COMMON_HEADERS = hdr.join("\n")
2471
2472  ##
2473  # Common libraries for ruby C extensions
2474
2475  COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
2476
2477  ##
2478  # make compile rules
2479
2480  COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
2481  RULE_SUBST = config_string('RULE_SUBST')
2482
2483  ##
2484  # Command which will compile C files in the generated Makefile
2485
2486  COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<'
2487
2488  ##
2489  # Command which will compile C++ files in the generated Makefile
2490
2491  COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<'
2492
2493  ##
2494  # Command which will compile a program in order to test linking a library
2495
2496  TRY_LINK = config_string('TRY_LINK') ||
2497    "$(CC) #{OUTFLAG}conftest#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \
2498    "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
2499
2500  ##
2501  # Command which will link a shared library
2502
2503  LINK_SO = (config_string('LINK_SO') || "").sub(/^$/) do
2504    if CONFIG["DLEXT"] == $OBJEXT
2505      "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
2506    else
2507      "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
2508      "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
2509    end
2510  end
2511
2512  ##
2513  # Argument which will add a library path to the linker
2514
2515  LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L%s'
2516  RPATHFLAG = config_string('RPATHFLAG') || ''
2517
2518  ##
2519  # Argument which will add a library to the linker
2520
2521  LIBARG = config_string('LIBARG') || '-l%s'
2522
2523  ##
2524  # A C main function which does no work
2525
2526  MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n  return 0;\n}"
2527  UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
2528    %w[int short long long\ long]
2529
2530  sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || ""
2531
2532  ##
2533  # Makefile rules that will clean the extension build directory
2534
2535  CLEANINGS = "
2536clean-static::
2537clean-rb-default::
2538clean-rb::
2539clean-so::
2540clean: clean-so clean-static clean-rb-default clean-rb
2541\t\t-$(Q)$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) .*.time
2542
2543distclean-rb-default::
2544distclean-rb::
2545distclean-so::
2546distclean-static::
2547distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
2548\t\t-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
2549\t\t-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
2550\t\t-$(Q)$(RMDIRS) $(DISTCLEANDIRS#{sep})#{$ignore_error}
2551
2552realclean: distclean
2553"
2554end
2555
2556include MakeMakefile
2557
2558if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
2559  END {mkmf_failed($0)}
2560end
2561