* transcode.c (trans_open_i): check the result of rb_transcoding_open.
[ruby-svn.git] / lib / mkmf.rb
blobdf8861a71e4ca602a1cb76e3b26655f6384860b1
1 # module to create Makefile for extension modules
2 # invoke like: ruby -r mkmf extconf.rb
4 require 'rbconfig'
5 require 'fileutils'
6 require 'shellwords'
8 CONFIG = RbConfig::MAKEFILE_CONFIG
9 ORIG_LIBPATH = ENV['LIB']
11 CXX_EXT = %w[cc cxx cpp]
12 if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']
13   CXX_EXT.concat(%w[C])
14 end
15 SRC_EXT = %w[c m] << CXX_EXT
16 $static = $config_h = nil
17 $default_static = $static
19 unless defined? $configure_args
20   $configure_args = {}
21   args = CONFIG["configure_args"]
22   if ENV["CONFIGURE_ARGS"]
23     args << " " << ENV["CONFIGURE_ARGS"]
24   end
25   for arg in Shellwords::shellwords(args)
26     arg, val = arg.split('=', 2)
27     next unless arg
28     arg.tr!('_', '-')
29     if arg.sub!(/^(?!--)/, '--')
30       val or next
31       arg.downcase!
32     end
33     next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
34     $configure_args[arg] = val || true
35   end
36   for arg in ARGV
37     arg, val = arg.split('=', 2)
38     next unless arg
39     arg.tr!('_', '-')
40     if arg.sub!(/^(?!--)/, '--')
41       val or next
42       arg.downcase!
43     end
44     $configure_args[arg] = val || true
45   end
46 end
48 $libdir = CONFIG["libdir"]
49 $rubylibdir = CONFIG["rubylibdir"]
50 $archdir = CONFIG["archdir"]
51 $sitedir = CONFIG["sitedir"]
52 $sitelibdir = CONFIG["sitelibdir"]
53 $sitearchdir = CONFIG["sitearchdir"]
54 $vendordir = CONFIG["vendordir"]
55 $vendorlibdir = CONFIG["vendorlibdir"]
56 $vendorarchdir = CONFIG["vendorarchdir"]
58 $mswin = /mswin/ =~ RUBY_PLATFORM
59 $bccwin = /bccwin/ =~ RUBY_PLATFORM
60 $mingw = /mingw/ =~ RUBY_PLATFORM
61 $cygwin = /cygwin/ =~ RUBY_PLATFORM
62 $human = /human/ =~ RUBY_PLATFORM
63 $netbsd = /netbsd/ =~ RUBY_PLATFORM
64 $os2 = /os2/ =~ RUBY_PLATFORM
65 $beos = /beos/ =~ RUBY_PLATFORM
66 $haiku = /haiku/ =~ RUBY_PLATFORM
67 $solaris = /solaris/ =~ RUBY_PLATFORM
68 $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
70 # :stopdoc:
72 def config_string(key, config = CONFIG)
73   s = config[key] and !s.empty? and block_given? ? yield(s) : s
74 end
76 def dir_re(dir)
77   Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
78 end
80 def relative_from(path, base)
81   dir = File.join(path, "")
82   if File.expand_path(dir) == File.expand_path(dir, base)
83     path
84   else
85     File.join(base, path)
86   end
87 end
89 INSTALL_DIRS = [
90   [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
91   [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
92   [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
93   [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
94   [dir_re('archdir'), "$(RUBYARCHDIR)"],
95   [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
96   [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
97   [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
98   [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
99   [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"],
100   [dir_re('sitehdrdir'), "$(SITEHDRDIR)"],
101   [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"],
102   [dir_re('bindir'), "$(BINDIR)"],
105 def install_dirs(target_prefix = nil)
106   if $extout
107     dirs = [
108       ['BINDIR',        '$(extout)/bin'],
109       ['RUBYCOMMONDIR', '$(extout)/common'],
110       ['RUBYLIBDIR',    '$(RUBYCOMMONDIR)$(target_prefix)'],
111       ['RUBYARCHDIR',   '$(extout)/$(arch)$(target_prefix)'],
112       ['HDRDIR',        '$(extout)/include/ruby$(target_prefix)'],
113       ['ARCHHDRDIR',    '$(extout)/include/$(arch)/ruby$(target_prefix)'],
114       ['extout',        "#$extout"],
115       ['extout_prefix', "#$extout_prefix"],
116     ]
117   elsif $extmk
118     dirs = [
119       ['BINDIR',        '$(bindir)'],
120       ['RUBYCOMMONDIR', '$(rubylibdir)'],
121       ['RUBYLIBDIR',    '$(rubylibdir)$(target_prefix)'],
122       ['RUBYARCHDIR',   '$(archdir)$(target_prefix)'],
123       ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
124       ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
125     ]
126   elsif $configure_args.has_key?('--vendor')
127     dirs = [
128       ['BINDIR',        '$(bindir)'],
129       ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
130       ['RUBYLIBDIR',    '$(vendorlibdir)$(target_prefix)'],
131       ['RUBYARCHDIR',   '$(vendorarchdir)$(target_prefix)'],
132       ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
133       ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
134     ]
135   else
136     dirs = [
137       ['BINDIR',        '$(bindir)'],
138       ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
139       ['RUBYLIBDIR',    '$(sitelibdir)$(target_prefix)'],
140       ['RUBYARCHDIR',   '$(sitearchdir)$(target_prefix)'],
141       ['HDRDIR',        '$(rubyhdrdir)/ruby$(target_prefix)'],
142       ['ARCHHDRDIR',    '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
143     ]
144   end
145   dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
146   dirs
149 def map_dir(dir, map = nil)
150   map ||= INSTALL_DIRS
151   map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)}
154 topdir = File.dirname(libdir = File.dirname(__FILE__))
155 extdir = File.expand_path("ext", topdir)
156 path = File.expand_path($0)
157 $extmk = path[0, topdir.size+1] == topdir+"/" && %r"\A(ext|enc|tool)\z" =~ File.dirname(path[topdir.size+1..-1])
158 if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
159   $topdir = $hdrdir
160   $top_srcdir = $hdrdir
161   $arch_hdrdir = $hdrdir + "/$(arch)"
162 elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include")  + "/ruby.h") and
163     File.exist?("#{CONFIG["EXTOUT"]}/include/#{CONFIG["arch"]}/ruby/config.h")
164   $topdir ||= RbConfig::CONFIG["topdir"]
165   $arch_hdrdir = "$(extout)/include/$(arch)"
166 else
167   abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
170 OUTFLAG = CONFIG['OUTFLAG']
171 COUTFLAG = CONFIG['COUTFLAG']
172 CPPOUTFILE = CONFIG['CPPOUTFILE']
174 CONFTEST_C = "conftest.c".freeze
176 class String
177   # Wraps a string in escaped quotes if it contains whitespace.
178   def quote
179     /\s/ =~ self ? "\"#{self}\"" : "#{self}"
180   end
182   # Generates a string used as cpp macro name.
183   def tr_cpp
184     strip.upcase.tr_s("^A-Z0-9_", "_")
185   end
187 class Array
188   # Wraps all strings in escaped quotes if they contain whitespace.
189   def quote
190     map {|s| s.quote}
191   end
194 def rm_f(*files)
195   FileUtils.rm_f(Dir[*files])
198 # Returns time stamp of the +target+ file if it exists and is newer
199 # than or equal to all of +times+.
200 def modified?(target, times)
201   (t = File.mtime(target)) rescue return nil
202   Array === times or times = [times]
203   t if times.all? {|n| n <= t}
206 def merge_libs(*libs)
207   libs.inject([]) do |x, y|
208     xy = x & y
209     xn = yn = 0
210     y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
211     y.each_with_index do |v, yi|
212       if xy.include?(v)
213         xi = [x.index(v), xn].max()
214         x[xi, 1] = y[yn..yi]
215         xn, yn = xi + (yi - yn + 1), yi + 1
216       end
217     end
218     x.concat(y[yn..-1] || [])
219   end
222 # This is a custom logging module. It generates an mkmf.log file when you
223 # run your extconf.rb script. This can be useful for debugging unexpected
224 # failures.
226 # This module and its associated methods are meant for internal use only.
228 module Logging
229   @log = nil
230   @logfile = 'mkmf.log'
231   @orgerr = $stderr.dup
232   @orgout = $stdout.dup
233   @postpone = 0
234   @quiet = $extmk
236   def self::open
237     @log ||= File::open(@logfile, 'w')
238     @log.sync = true
239     $stderr.reopen(@log)
240     $stdout.reopen(@log)
241     yield
242   ensure
243     $stderr.reopen(@orgerr)
244     $stdout.reopen(@orgout)
245   end
247   def self::message(*s)
248     @log ||= File::open(@logfile, 'w')
249     @log.sync = true
250     @log.printf(*s)
251   end
253   def self::logfile file
254     @logfile = file
255     if @log and not @log.closed?
256       @log.flush
257       @log.close
258       @log = nil
259     end
260   end
261   
262   def self::postpone
263     tmplog = "mkmftmp#{@postpone += 1}.log"
264     open do
265       log, *save = @log, @logfile, @orgout, @orgerr
266       @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
267       begin
268         log.print(open {yield})
269         @log.close
270         File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
271       ensure
272         @log, @logfile, @orgout, @orgerr = log, *save
273         @postpone -= 1
274         rm_f tmplog
275       end
276     end
277   end
279   class << self
280     attr_accessor :quiet
281   end
284 def xsystem command
285   varpat = /\$\((\w+)\)|\$\{(\w+)\}/
286   if varpat =~ command
287     vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
288     command = command.dup
289     nil while command.gsub!(varpat) {vars[$1||$2]}
290   end
291   Logging::open do
292     puts command.quote
293     system(command)
294   end
297 def xpopen command, *mode, &block
298   Logging::open do
299     case mode[0]
300     when nil, /^r/
301       puts "#{command} |"
302     else
303       puts "| #{command}"
304     end
305     IO.popen(command, *mode, &block)
306   end
309 def log_src(src)
310   src = src.split(/^/)
311   fmt = "%#{src.size.to_s.size}d: %s"
312   Logging::message <<"EOM"
313 checked program was:
314 /* begin */
316   src.each_with_index {|line, no| Logging::message fmt, no+1, line}
317   Logging::message <<"EOM"
318 /* end */
323 def create_tmpsrc(src)
324   src = yield(src) if block_given?
325   src[0, 0] = COMMON_HEADERS + "\n"
326   src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n")
327   count = 0
328   begin
329     open(CONFTEST_C, "wb") do |cfile|
330       cfile.print src
331     end
332   rescue Errno::EACCES
333     if (count += 1) < 5
334       sleep 0.2
335       retry
336     end
337   end
338   src
341 def try_do(src, command, &b)
342   src = create_tmpsrc(src, &b)
343   xsystem(command)
344 ensure
345   log_src(src)
348 def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
349   conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
350                                 'src' => CONFTEST_C,
351                                 'arch_hdrdir' => "#$arch_hdrdir",
352                                 'top_srcdir' => $top_srcdir.quote,
353                                 'INCFLAGS' => "#$INCFLAGS",
354                                 'CPPFLAGS' => "#$CPPFLAGS",
355                                 'CFLAGS' => "#$CFLAGS",
356                                 'ARCH_FLAG' => "#$ARCH_FLAG",
357                                 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
358                                 'LIBPATH' => libpathflag(libpath),
359                                 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
360                                 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
361   RbConfig::expand(TRY_LINK.dup, conf)
364 def cc_command(opt="")
365   conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
366                                 'arch_hdrdir' => "#$arch_hdrdir",
367                                 'top_srcdir' => $top_srcdir.quote)
368   RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
369                    conf)
372 def cpp_command(outfile, opt="")
373   conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
374                                 'arch_hdrdir' => "#$arch_hdrdir",
375                                 'top_srcdir' => $top_srcdir.quote)
376   RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
377                    conf)
380 def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
381   libpath.map{|x|
382     case x
383     when "$(topdir)", /\A\./
384       LIBPATHFLAG
385     else
386       LIBPATHFLAG+RPATHFLAG
387     end % x.quote
388   }.join
391 def try_link0(src, opt="", &b)
392   try_do(src, link_command("", opt), &b)
395 def try_link(src, opt="", &b)
396   try_link0(src, opt, &b)
397 ensure
398   rm_f "conftest*", "c0x32*"
401 def try_compile(src, opt="", &b)
402   try_do(src, cc_command(opt), &b)
403 ensure
404   rm_f "conftest*"
407 def try_cpp(src, opt="", &b)
408   try_do(src, cpp_command(CPPOUTFILE, opt), &b)
409 ensure
410   rm_f "conftest*"
413 def cpp_include(header)
414   if header
415     header = [header] unless header.kind_of? Array
416     header.map {|h| "#include <#{h}>\n"}.join
417   else
418     ""
419   end
422 def with_cppflags(flags)
423   cppflags = $CPPFLAGS
424   $CPPFLAGS = flags
425   ret = yield
426 ensure
427   $CPPFLAGS = cppflags unless ret
430 def with_cflags(flags)
431   cflags = $CFLAGS
432   $CFLAGS = flags
433   ret = yield
434 ensure
435   $CFLAGS = cflags unless ret
438 def with_ldflags(flags)
439   ldflags = $LDFLAGS
440   $LDFLAGS = flags
441   ret = yield
442 ensure
443   $LDFLAGS = ldflags unless ret
446 def try_static_assert(expr, headers = nil, opt = "", &b)
447   headers = cpp_include(headers)
448   try_compile(<<SRC, opt, &b)
449 #{COMMON_HEADERS}
450 #{headers}
451 /*top*/
452 int conftest_const[(#{expr}) ? 1 : -1];
456 def try_constant(const, headers = nil, opt = "", &b)
457   includes = cpp_include(headers)
458   if CROSS_COMPILING
459     if try_static_assert("#{const} > 0", headers, opt)
460       # positive constant
461     elsif try_static_assert("#{const} < 0", headers, opt)
462       neg = true
463       const = "-(#{const})"
464     elsif try_static_assert("#{const} == 0", headers, opt)
465       return 0
466     else
467       # not a constant
468       return nil
469     end
470     upper = 1
471     lower = 0
472     until try_static_assert("#{const} <= #{upper}", headers, opt)
473       lower = upper
474       upper <<= 1
475     end
476     return nil unless lower
477     while upper > lower + 1
478       mid = (upper + lower) / 2
479       if try_static_assert("#{const} > #{mid}", headers, opt)
480         lower = mid
481       else
482         upper = mid
483       end
484     end
485     upper = -upper if neg
486     return upper
487   else
488     src = %{#{COMMON_HEADERS}
489 #{includes}
490 #include <stdio.h>
491 /*top*/
492 int conftest_const = (int)(#{const});
493 int main() {printf("%d\\n", conftest_const); return 0;}
495     if try_link0(src, opt, &b)
496       xpopen("./conftest") do |f|
497         return Integer(f.gets)
498       end
499     end
500   end
501   nil
504 def try_func(func, libs, headers = nil, &b)
505   headers = cpp_include(headers)
506   try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
507 #{COMMON_HEADERS}
508 #{headers}
509 /*top*/
510 int main() { return 0; }
511 int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
513 #{headers}
514 /*top*/
515 int main() { return 0; }
516 int t() { #{func}(); return 0; }
520 def try_var(var, headers = nil, &b)
521   headers = cpp_include(headers)
522   try_compile(<<"SRC", &b)
523 #{COMMON_HEADERS}
524 #{headers}
525 /*top*/
526 int main() { return 0; }
527 int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
531 def egrep_cpp(pat, src, opt = "", &b)
532   src = create_tmpsrc(src, &b)
533   xpopen(cpp_command('', opt)) do |f|
534     if Regexp === pat
535       puts("    ruby -ne 'print if #{pat.inspect}'")
536       f.grep(pat) {|l|
537         puts "#{f.lineno}: #{l}"
538         return true
539       }
540       false
541     else
542       puts("    egrep '#{pat}'")
543       begin
544         stdin = $stdin.dup
545         $stdin.reopen(f)
546         system("egrep", pat)
547       ensure
548         $stdin.reopen(stdin)
549       end
550     end
551   end
552 ensure
553   rm_f "conftest*"
554   log_src(src)
557 # This is used internally by the have_macro? method.
558 def macro_defined?(macro, src, opt = "", &b)
559   src = src.sub(/[^\n]\z/, "\\&\n")
560   try_compile(src + <<"SRC", opt, &b)
561 /*top*/
562 #ifndef #{macro}
563 # error
564 >>>>>> #{macro} undefined <<<<<<
565 #endif
569 def try_run(src, opt = "", &b)
570   if try_link0(src, opt, &b)
571     xsystem("./conftest")
572   else
573     nil
574   end
575 ensure
576   rm_f "conftest*"
579 def install_files(mfile, ifiles, map = nil, srcprefix = nil)
580   ifiles or return
581   ifiles.empty? and return
582   srcprefix ||= '$(srcdir)'
583   RbConfig::expand(srcdir = srcprefix.dup)
584   dirs = []
585   path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
586   ifiles.each do |files, dir, prefix|
587     dir = map_dir(dir, map)
588     prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
589     if /\A\.\// =~ files
590       # install files which are in current working directory.
591       files = files[2..-1]
592       len = nil
593     else
594       # install files which are under the $(srcdir).
595       files = File.join(srcdir, files)
596       len = srcdir.size
597     end
598     f = nil
599     Dir.glob(files) do |fx|
600       f = fx
601       f[0..len] = "" if len
602       case File.basename(f)
603       when *$NONINSTALLFILES
604         next
605       end
606       d = File.dirname(f)
607       d.sub!(prefix, "") if prefix
608       d = (d.empty? || d == ".") ? dir : File.join(dir, d)
609       f = File.join(srcprefix, f) if len
610       path[d] << f
611     end
612     unless len or f
613       d = File.dirname(files)
614       d.sub!(prefix, "") if prefix
615       d = (d.empty? || d == ".") ? dir : File.join(dir, d)
616       path[d] << files
617     end
618   end
619   dirs
622 def install_rb(mfile, dest, srcdir = nil)
623   install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
626 def append_library(libs, lib) # :no-doc:
627   format(LIBARG, lib) + " " + libs
630 def message(*s)
631   unless Logging.quiet and not $VERBOSE
632     printf(*s)
633     $stdout.flush
634   end
637 # This emits a string to stdout that allows users to see the results of the
638 # various have* and find* methods as they are tested.
640 # Internal use only.
642 def checking_for(m, fmt = nil)
643   f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim #'
644   m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
645   message "%s", m
646   a = r = nil
647   Logging::postpone do
648     r = yield
649     a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
650     "#{f}#{m}-------------------- #{a}\n"
651   end
652   message(a)
653   Logging::message "--------------------\n\n"
654   r
657 def checking_message(target, place = nil, opt = nil)
658   [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
659     if noun
660       [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
661         if noun.respond_to?(meth)
662           break noun = noun.send(meth, *args)
663         end
664       end
665       msg << " #{pre} #{noun}" unless noun.empty?
666     end
667     msg
668   end
671 # :startdoc:
673 # Returns whether or not +macro+ is defined either in the common header
674 # files or within any +headers+ you provide.
676 # Any options you pass to +opt+ are passed along to the compiler.
678 def have_macro(macro, headers = nil, opt = "", &b)
679   checking_for checking_message(macro, headers, opt) do
680     macro_defined?(macro, cpp_include(headers), opt, &b)
681   end
684 # Returns whether or not the given entry point +func+ can be found within
685 # +lib+.  If +func+ is nil, the 'main()' entry point is used by default.
686 # If found, it adds the library to list of libraries to be used when linking
687 # your extension.
689 # If +headers+ are provided, it will include those header files as the
690 # header files it looks in when searching for +func+.
692 # The real name of the library to be linked can be altered by
693 # '--with-FOOlib' configuration option.
695 def have_library(lib, func = nil, headers = nil, &b)
696   func = "main" if !func or func.empty?
697   lib = with_config(lib+'lib', lib)
698   checking_for checking_message("#{func}()", LIBARG%lib) do
699     if COMMON_LIBS.include?(lib)
700       true
701     else
702       libs = append_library($libs, lib)
703       if try_func(func, libs, headers, &b)
704         $libs = libs
705         true
706       else
707         false
708       end
709     end
710   end
713 # Returns whether or not the entry point +func+ can be found within the library
714 # +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.
715 # If +func+ is nil , then the main() function is used as the entry point.
717 # If +lib+ is found, then the path it was found on is added to the list of
718 # library paths searched and linked against.
720 def find_library(lib, func, *paths, &b)
721   func = "main" if !func or func.empty?
722   lib = with_config(lib+'lib', lib)
723   paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
724   checking_for "#{func}() in #{LIBARG%lib}" do
725     libpath = $LIBPATH
726     libs = append_library($libs, lib)
727     begin
728       until r = try_func(func, libs, &b) or paths.empty?
729         $LIBPATH = libpath | [paths.shift]
730       end
731       if r
732         $libs = libs
733         libpath = nil
734       end
735     ensure
736       $LIBPATH = libpath if libpath
737     end
738     r
739   end
742 # Returns whether or not the function +func+ can be found in the common
743 # header files, or within any +headers+ that you provide.  If found, a
744 # macro is passed as a preprocessor constant to the compiler using the
745 # function name, in uppercase, prepended with 'HAVE_'.
747 # For example, if have_func('foo') returned true, then the HAVE_FOO
748 # preprocessor macro would be passed to the compiler.
750 def have_func(func, headers = nil, &b)
751   checking_for checking_message("#{func}()", headers) do
752     if try_func(func, $libs, headers, &b)
753       $defs.push(format("-DHAVE_%s", func.tr_cpp))
754       true
755     else
756       false
757     end
758   end
761 # Returns whether or not the variable +var+ can be found in the common
762 # header files, or within any +headers+ that you provide.  If found, a
763 # macro is passed as a preprocessor constant to the compiler using the
764 # variable name, in uppercase, prepended with 'HAVE_'.
766 # For example, if have_var('foo') returned true, then the HAVE_FOO
767 # preprocessor macro would be passed to the compiler.
769 def have_var(var, headers = nil, &b)
770   checking_for checking_message(var, headers) do
771     if try_var(var, headers, &b)
772       $defs.push(format("-DHAVE_%s", var.tr_cpp))
773       true
774     else
775       false
776     end
777   end
780 # Returns whether or not the given +header+ file can be found on your system.
781 # If found, a macro is passed as a preprocessor constant to the compiler using
782 # the header file name, in uppercase, prepended with 'HAVE_'.
784 # For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
785 # preprocessor macro would be passed to the compiler.
787 def have_header(header, &b)
788   checking_for header do
789     if try_cpp(cpp_include(header), &b)
790       $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
791       true
792     else
793       false
794     end
795   end
798 # Instructs mkmf to search for the given +header+ in any of the +paths+
799 # provided, and returns whether or not it was found in those paths.
801 # If the header is found then the path it was found on is added to the list
802 # of included directories that are sent to the compiler (via the -I switch).
804 def find_header(header, *paths)
805   message = checking_message(header, paths)
806   header = cpp_include(header)
807   checking_for message do
808     if try_cpp(header)
809       true
810     else
811       found = false
812       paths.each do |dir|
813         opt = "-I#{dir}".quote
814         if try_cpp(header, opt)
815           $INCFLAGS << " " << opt
816           found = true
817           break
818         end
819       end
820       found
821     end
822   end
825 # Returns whether or not the struct of type +type+ contains +member+.  If
826 # it does not, or the struct type can't be found, then false is returned.  You
827 # may optionally specify additional +headers+ in which to look for the struct
828 # (in addition to the common header files).
830 # If found, a macro is passed as a preprocessor constant to the compiler using
831 # the type name and the member name, in uppercase, prepended with 'HAVE_'.
833 # For example, if have_struct_member('struct foo', 'bar') returned true, then the
834 # HAVE_STRUCT_FOO_BAR preprocessor macro would be passed to the compiler.
836 # HAVE_ST_BAR is also defined for backward compatibility.
838 def have_struct_member(type, member, headers = nil, &b)
839   checking_for checking_message("#{type}.#{member}", headers) do
840     if try_compile(<<"SRC", &b)
841 #{COMMON_HEADERS}
842 #{cpp_include(headers)}
843 /*top*/
844 int main() { return 0; }
845 int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
847       $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
848       $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility
849       true
850     else
851       false
852     end
853   end
856 def try_type(type, headers = nil, opt = "", &b)
857   if try_compile(<<"SRC", opt, &b)
858 #{COMMON_HEADERS}
859 #{cpp_include(headers)}
860 /*top*/
861 typedef #{type} conftest_type;
862 int conftestval[sizeof(conftest_type)?1:-1];
864     $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
865     true
866   else
867     false
868   end
871 # Returns whether or not the static type +type+ is defined.  You may
872 # optionally pass additional +headers+ to check against in addition to the
873 # common header files.
875 # You may also pass additional flags to +opt+ which are then passed along to
876 # the compiler.
878 # If found, a macro is passed as a preprocessor constant to the compiler using
879 # the type name, in uppercase, prepended with 'HAVE_TYPE_'.
881 # For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO
882 # preprocessor macro would be passed to the compiler.
884 def have_type(type, headers = nil, opt = "", &b)
885   checking_for checking_message(type, headers, opt) do
886     try_type(type, headers, opt, &b)
887   end
890 # Returns where the static type +type+ is defined.
892 # You may also pass additional flags to +opt+ which are then passed along to
893 # the compiler.
895 # See also +have_type+.
897 def find_type(type, opt, *headers, &b)
898   opt ||= ""
899   fmt = "not found"
900   def fmt.%(x)
901     x ? x.respond_to?(:join) ? x.join(",") : x : self
902   end
903   checking_for checking_message(type, nil, opt), fmt do
904     headers.find do |h|
905       try_type(type, h, opt, &b)
906     end
907   end
910 def try_const(const, headers = nil, opt = "", &b)
911   const, type = *const
912   if try_compile(<<"SRC", opt, &b)
913 #{COMMON_HEADERS}
914 #{cpp_include(headers)}
915 /*top*/
916 typedef #{type || 'int'} conftest_type;
917 conftest_type conftestval = #{type ? '' : '(int)'}#{const};
919     $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
920     true
921   else
922     false
923   end
926 # Returns whether or not the constant +const+ is defined.  You may
927 # optionally pass the +type+ of +const+ as <code>[const, type]</code>,
928 # like as:
930 #   have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
932 # You may also pass additional +headers+ to check against in addition
933 # to the common header files, and additional flags to +opt+ which are
934 # then passed along to the compiler.
936 # If found, a macro is passed as a preprocessor constant to the compiler using
937 # the type name, in uppercase, prepended with 'HAVE_CONST_'.
939 # For example, if have_const('foo') returned true, then the HAVE_CONST_FOO
940 # preprocessor macro would be passed to the compiler.
942 def have_const(const, headers = nil, opt = "", &b)
943   checking_for checking_message([*const].compact.join(' '), headers, opt) do
944     try_const(const, headers, opt, &b)
945   end
948 # Returns the size of the given +type+.  You may optionally specify additional
949 # +headers+ to search in for the +type+.
951 # If found, a macro is passed as a preprocessor constant to the compiler using
952 # the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
953 # name, followed by '=X' where 'X' is the actual size.
955 # For example, if check_sizeof('mystruct') returned 12, then the
956 # SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
958 def check_sizeof(type, headers = nil, &b)
959   expr = "sizeof(#{type})"
960   fmt = "%d"
961   def fmt.%(x)
962     x ? super : "failed"
963   end
964   checking_for checking_message("size of #{type}", headers), fmt do
965     if size = try_constant(expr, headers, &b)
966       $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
967       size
968     end
969   end
972 # :stopdoc:
974 # Used internally by the what_type? method to determine if +type+ is a scalar
975 # pointer.
976 def scalar_ptr_type?(type, member = nil, headers = nil, &b)
977   try_compile(<<"SRC", &b)   # pointer
978 #{COMMON_HEADERS}
979 #{cpp_include(headers)}
980 /*top*/
981 volatile #{type} conftestval;
982 int main() { return 0; }
983 int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
987 # Used internally by the what_type? method to determine if +type+ is a scalar
988 # pointer.
989 def scalar_type?(type, member = nil, headers = nil, &b)
990   try_compile(<<"SRC", &b)   # pointer
991 #{COMMON_HEADERS}
992 #{cpp_include(headers)}
993 /*top*/
994 volatile #{type} conftestval;
995 int main() { return 0; }
996 int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
1000 def what_type?(type, member = nil, headers = nil, &b)
1001   m = "#{type}"
1002   name = type
1003   if member
1004     m << "." << member
1005     name = "(((#{type} *)0)->#{member})"
1006   end
1007   fmt = "seems %s"
1008   def fmt.%(x)
1009     x ? super : "unknown"
1010   end
1011   checking_for checking_message(m, headers), fmt do
1012     if scalar_ptr_type?(type, member, headers, &b)
1013       if try_static_assert("sizeof(*#{name}) == 1", headers)
1014         "string"
1015       end
1016     elsif scalar_type?(type, member, headers, &b)
1017       if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
1018         "long long"
1019       elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
1020         "long"
1021       elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
1022         "int"
1023       elsif try_static_assert("sizeof(#{name}) > 1", headers)
1024         "short"
1025       else
1026         "char"
1027       end
1028     end
1029   end
1032 # This method is used internally by the find_executable method.
1034 # Internal use only.
1036 def find_executable0(bin, path = nil)
1037   ext = config_string('EXEEXT')
1038   if File.expand_path(bin) == bin
1039     return bin if File.executable?(bin)
1040     ext and File.executable?(file = bin + ext) and return file
1041     return nil
1042   end
1043   if path ||= ENV['PATH']
1044     path = path.split(File::PATH_SEPARATOR)
1045   else
1046     path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
1047   end
1048   file = nil
1049   path.each do |dir|
1050     return file if File.executable?(file = File.join(dir, bin))
1051     return file if ext and File.executable?(file << ext)
1052   end
1053   nil
1056 # :startdoc:
1058 # Searches for the executable +bin+ on +path+. The default path is your
1059 # PATH environment variable. If that isn't defined, it will resort to
1060 # searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
1062 # If found, it will return the full path, including the executable name,
1063 # of where it was found.
1065 # Note that this method does not actually affect the generated Makefile.
1067 def find_executable(bin, path = nil)
1068   checking_for checking_message(bin, path) do
1069     find_executable0(bin, path)
1070   end
1073 # :stopdoc:
1075 def arg_config(config, default=nil, &block)
1076   $arg_config << [config, default]
1077   defaults = []
1078   if default
1079     defaults << default
1080   elsif !block
1081     defaults << nil
1082   end
1083   $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
1086 # :startdoc:
1088 # Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>
1089 # option. Returns true if the with option is given, false if the without
1090 # option is given, and the default value otherwise.
1092 # This can be useful for adding custom definitions, such as debug information.
1094 # Example:
1096 #    if with_config("debug")
1097 #       $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1098 #    end
1100 def with_config(config, default=nil)
1101   config = config.sub(/^--with[-_]/, '')
1102   val = arg_config("--with-"+config) do
1103     if arg_config("--without-"+config)
1104       false
1105     elsif block_given?
1106       yield(config, default)
1107     else
1108       break default
1109     end
1110   end
1111   case val
1112   when "yes"
1113     true
1114   when "no"
1115     false
1116   else
1117     val
1118   end
1121 # Tests for the presence of an --enable-<tt>config</tt> or
1122 # --disable-<tt>config</tt> option. Returns true if the enable option is given,
1123 # false if the disable option is given, and the default value otherwise.
1125 # This can be useful for adding custom definitions, such as debug information.
1127 # Example:
1129 #    if enable_config("debug")
1130 #       $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1131 #    end
1133 def enable_config(config, default=nil)
1134   if arg_config("--enable-"+config)
1135     true
1136   elsif arg_config("--disable-"+config)
1137     false
1138   elsif block_given?
1139     yield(config, default)
1140   else
1141     return default
1142   end
1145 # Generates a header file consisting of the various macro definitions generated
1146 # by other methods such as have_func and have_header. These are then wrapped in
1147 # a custom #ifndef based on the +header+ file name, which defaults to
1148 # 'extconf.h'.
1150 # For example:
1152 #    # extconf.rb
1153 #    require 'mkmf'
1154 #    have_func('realpath')
1155 #    have_header('sys/utime.h')
1156 #    create_header
1157 #    create_makefile('foo')
1159 # The above script would generate the following extconf.h file:
1161 #    #ifndef EXTCONF_H
1162 #    #define EXTCONF_H
1163 #    #define HAVE_REALPATH 1
1164 #    #define HAVE_SYS_UTIME_H 1
1165 #    #endif
1167 # Given that the create_header method generates a file based on definitions
1168 # set earlier in your extconf.rb file, you will probably want to make this
1169 # one of the last methods you call in your script.
1171 def create_header(header = "extconf.h")
1172   message "creating %s\n", header
1173     sym = header.tr("a-z./\055", "A-Z___")
1174   hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1175       for line in $defs
1176         case line
1177         when /^-D([^=]+)(?:=(.*))?/
1178       hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
1179         when /^-U(.*)/
1180       hdr << "#undef #$1\n"
1181         end
1182       end
1183   hdr << "#endif\n"
1184   hdr = hdr.join
1185   unless (IO.read(header) == hdr rescue false)
1186     open(header, "w") do |hfile|
1187       hfile.write(hdr)
1188     end
1189   end
1190   $extconf_h = header
1193 # Sets a +target+ name that the user can then use to configure various 'with'
1194 # options with on the command line by using that name.  For example, if the
1195 # target is set to "foo", then the user could use the --with-foo-dir command
1196 # line option.
1198 # You may pass along additional 'include' or 'lib' defaults via the +idefault+
1199 # and +ldefault+ parameters, respectively.
1201 # Note that dir_config only adds to the list of places to search for libraries
1202 # and include files.  It does not link the libraries into your application.
1204 def dir_config(target, idefault=nil, ldefault=nil)
1205   if dir = with_config(target + "-dir", (idefault unless ldefault))
1206     defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
1207     idefault = ldefault = nil
1208   end
1210   idir = with_config(target + "-include", idefault)
1211   $arg_config.last[1] ||= "${#{target}-dir}/include"
1212   ldir = with_config(target + "-lib", ldefault)
1213   $arg_config.last[1] ||= "${#{target}-dir}/lib"
1215   idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
1216   if defaults
1217     idirs.concat(defaults.collect {|d| d + "/include"})
1218     idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1219   end
1220   unless idirs.empty?
1221     idirs.collect! {|d| "-I" + d}
1222     idirs -= Shellwords.shellwords($CPPFLAGS)
1223     unless idirs.empty?
1224       $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1225     end
1226   end
1228   ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
1229   if defaults
1230     ldirs.concat(defaults.collect {|d| d + "/lib"})
1231     ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1232   end
1233   $LIBPATH = ldirs | $LIBPATH
1235   [idir, ldir]
1238 # :stopdoc:
1240 # Handles meta information about installed libraries. Uses your platform's
1241 # pkg-config program if it has one.
1242 def pkg_config(pkg)
1243   if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1244     # iff package specific config command is given
1245     get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1246   elsif ($PKGCONFIG ||= 
1247          (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1248          find_executable0(pkgconfig) && pkgconfig) and
1249       system("#{$PKGCONFIG} --exists #{pkg}")
1250     # default to pkg-config command
1251     get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
1252   elsif find_executable0(pkgconfig = "#{pkg}-config")
1253     # default to package specific config command, as a last resort.
1254     get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1255   end
1256   if get
1257     cflags = get['cflags']
1258     ldflags = get['libs']
1259     libs = get['libs-only-l']
1260     ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
1261     $CFLAGS += " " << cflags
1262     $LDFLAGS += " " << ldflags
1263     $libs += " " << libs
1264     Logging::message "package configuration for %s\n", pkg
1265     Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
1266                      cflags, ldflags, libs
1267     [cflags, ldflags, libs]
1268   else
1269     Logging::message "package configuration for %s is not found\n", pkg
1270     nil
1271   end
1274 def with_destdir(dir)
1275   dir = dir.sub($dest_prefix_pattern, '')
1276   /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
1279 # Converts forward slashes to backslashes. Aimed at MS Windows.
1281 # Internal use only.
1283 def winsep(s)
1284   s.tr('/', '\\')
1287 def configuration(srcdir)
1288   mk = []
1289   vpath = $VPATH.dup
1290   if !CROSS_COMPILING
1291     case CONFIG['build_os']
1292     when 'cygwin'
1293       if CONFIG['target_os'] != 'cygwin'
1294         vpath = vpath.map {|p| p.sub(/.*/, '$(shell cygpath -u \&)')}
1295       end
1296     when 'msdosdjgpp', 'mingw32'
1297       CONFIG['PATH_SEPARATOR'] = ';'
1298     end
1299   end
1300   CONFIG["hdrdir"] ||= $hdrdir
1301   mk << %{
1302 SHELL = /bin/sh
1304 #### Start of system configuration section. ####
1306 if $extmk
1307   "top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/")
1310 srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {CONFIG[$1||$2]}.quote}
1311 topdir = #{($extmk ? CONFIG["topdir"] : $topdir).quote}
1312 hdrdir = #{CONFIG["hdrdir"].quote}
1313 arch_hdrdir = #{$arch_hdrdir}
1314 VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
1316   if $extmk
1317     mk << "RUBYLIB = -\nRUBYOPT = -r$(top_srcdir)/ext/purelib.rb\n"
1318   end
1319   if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
1320     mk << "\nDESTDIR = #{destdir}\n"
1321   end
1322   CONFIG.each do |key, var|
1323     next unless /prefix$/ =~ key
1324     mk << "#{key} = #{with_destdir(var)}\n"
1325   end
1326   CONFIG.each do |key, var|
1327     next if /^abs_/ =~ key
1328     next if /^(?:src|top|hdr)dir$/ =~ key
1329     next unless /dir$/ =~ key
1330     mk << "#{key} = #{with_destdir(var)}\n"
1331   end
1332   if !$extmk and !$configure_args.has_key?('--ruby') and
1333       sep = config_string('BUILD_FILE_SEPARATOR')
1334     sep = ":/=#{sep}"
1335   else
1336     sep = ""
1337   end
1338   extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" "
1339   mk << %{
1340 CC = #{CONFIG['CC']}
1341 CXX = #{CONFIG['CXX']}
1342 LIBRUBY = #{CONFIG['LIBRUBY']}
1343 LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
1344 LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
1345 LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
1346 OUTFLAG = #{OUTFLAG}
1347 COUTFLAG = #{COUTFLAG}
1349 RUBY_EXTCONF_H = #{$extconf_h}
1350 cflags   = #{CONFIG['cflags']}
1351 optflags = #{CONFIG['optflags']}
1352 debugflags = #{CONFIG['debugflags']}
1353 warnflags = #{CONFIG['warnflags']}
1354 CFLAGS   = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
1355 INCFLAGS = -I. #$INCFLAGS
1356 DEFS     = #{CONFIG['DEFS']}
1357 CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
1358 CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
1359 ldflags  = #{$LDFLAGS}
1360 dldflags = #{$DLDFLAGS}
1361 archflag = #{$ARCH_FLAG}
1362 DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
1363 LDSHARED = #{CONFIG['LDSHARED']}
1364 LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'}
1365 AR = #{CONFIG['AR']}
1366 EXEEXT = #{CONFIG['EXEEXT']}
1368 RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
1369 RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
1370 arch = #{CONFIG['arch']}
1371 sitearch = #{CONFIG['sitearch']}
1372 ruby_version = #{RbConfig::CONFIG['ruby_version']}
1373 ruby = #{$ruby}
1374 RUBY = $(ruby#{sep})
1375 RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
1376 MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
1377 INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
1378 INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
1379 INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
1380 COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
1382 #### End of system configuration section. ####
1384 preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''}
1386   if $nmake == ?b
1387     mk.each do |x|
1388       x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
1389         "!ifndef " + $1 + "\n" +
1390         $& +
1391         "!endif\n"
1392       end
1393     end
1394   end
1395   mk
1397 # :startdoc:
1399 def dummy_makefile(srcdir)
1400   configuration(srcdir) << <<RULES << CLEANINGS
1401 CLEANFILES = #{$cleanfiles.join(' ')}
1402 DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1404 all install static install-so install-rb: Makefile
1406 RULES
1409 def depend_rules(depend)
1410   suffixes = []
1411   depout = []
1412   cont = implicit = nil
1413   impconv = proc do
1414     COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
1415     implicit = nil
1416   end
1417   ruleconv = proc do |line|
1418     if implicit
1419       if /\A\t/ =~ line
1420         implicit[1] << line
1421         next
1422       else
1423         impconv[]
1424       end
1425     end
1426     if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1427       suffixes << m[1] << m[2]
1428       implicit = [[m[1], m[2]], [m.post_match]]
1429       next
1430     elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1431       line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1432     end
1433     depout << line
1434   end
1435   depend.each_line do |line|
1436     line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1437     line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
1438     line.gsub!(%r"\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
1439     if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
1440       line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")}
1441       line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\')
1442     end
1443     if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1444       (cont ||= []) << line
1445       next
1446     elsif cont
1447       line = (cont << line).join
1448       cont = nil
1449     end
1450     ruleconv.call(line)
1451   end
1452   if cont
1453     ruleconv.call(cont.join)
1454   elsif implicit
1455     impconv.call
1456   end
1457   unless suffixes.empty?
1458     depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
1459   end
1460   depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") if $extconf_h
1461   depout.flatten!
1462   depout
1465 # Generates the Makefile for your extension, passing along any options and
1466 # preprocessor constants that you may have generated through other methods.
1468 # The +target+ name should correspond the name of the global function name
1469 # defined within your C extension, minus the 'Init_'.  For example, if your
1470 # C extension is defined as 'Init_foo', then your target would simply be 'foo'.
1472 # If any '/' characters are present in the target name, only the last name
1473 # is interpreted as the target name, and the rest are considered toplevel
1474 # directory names, and the generated Makefile will be altered accordingly to
1475 # follow that directory structure.
1477 # For example, if you pass 'test/foo' as a target name, your extension will
1478 # be installed under the 'test' directory.  This means that in order to
1479 # load the file within a Ruby program later, that directory structure will
1480 # have to be followed, e.g. "require 'test/foo'".
1482 # The +srcprefix+ should be used when your source files are not in the same
1483 # directory as your build script. This will not only eliminate the need for
1484 # you to manually copy the source files into the same directory as your build
1485 # script, but it also sets the proper +target_prefix+ in the generated
1486 # Makefile.
1488 # Setting the +target_prefix+ will, in turn, install the generated binary in
1489 # a directory under your Config::CONFIG['sitearchdir'] that mimics your local
1490 # filesystem when you run 'make install'.
1492 # For example, given the following file tree:
1494 #    ext/
1495 #       extconf.rb
1496 #       test/
1497 #          foo.c
1499 # And given the following code:
1501 #    create_makefile('test/foo', 'test')
1503 # That will set the +target_prefix+ in the generated Makefile to 'test'. That,
1504 # in turn, will create the following file tree when installed via the
1505 # 'make install' command:
1507 #    /path/to/ruby/sitearchdir/test/foo.so
1509 # It is recommended that you use this approach to generate your makefiles,
1510 # instead of copying files around manually, because some third party
1511 # libraries may depend on the +target_prefix+ being set properly.
1513 # The +srcprefix+ argument can be used to override the default source
1514 # directory, i.e. the current directory . It is included as part of the VPATH
1515 # and added to the list of INCFLAGS.
1517 def create_makefile(target, srcprefix = nil)
1518   $target = target
1519   libpath = $DEFLIBPATH|$LIBPATH
1520   message "creating Makefile\n"
1521   rm_f "conftest*"
1522   if CONFIG["DLEXT"] == $OBJEXT
1523     for lib in libs = $libs.split
1524       lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
1525     end
1526     $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
1527   end
1529   if target.include?('/')
1530     target_prefix, target = File.split(target)
1531     target_prefix[0,0] = '/'
1532   else
1533     target_prefix = ""
1534   end
1536   srcprefix ||= '$(srcdir)'
1537   RbConfig::expand(srcdir = srcprefix.dup)
1539   if not $objs
1540     $objs = []
1541     srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1542     for f in srcs
1543       obj = File.basename(f, ".*") << ".o"
1544       $objs.push(obj) unless $objs.index(obj)
1545     end
1546   elsif !(srcs = $srcs)
1547     srcs = $objs.collect {|o| o.sub(/\.o\z/, '.c')}
1548   end
1549   $srcs = srcs
1550   for i in $objs
1551     i.sub!(/\.o\z/, ".#{$OBJEXT}")
1552   end
1553   $objs = $objs.join(" ")
1555   target = nil if $objs == ""
1557   if target and EXPORT_PREFIX
1558     if File.exist?(File.join(srcdir, target + '.def'))
1559       deffile = "$(srcdir)/$(TARGET).def"
1560       unless EXPORT_PREFIX.empty?
1561         makedef = %{-pe "$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
1562       end
1563     else
1564       makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
1565     end
1566     if makedef
1567       $distcleanfiles << '$(DEFFILE)'
1568       origdef = deffile
1569       deffile = "$(TARGET)-$(arch).def"
1570     end
1571   end
1572   origdef ||= ''
1574   if $extmk and not $extconf_h
1575     create_header
1576   end
1578   libpath = libpathflag(libpath)
1580   dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1581   staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1582   mfile = open("Makefile", "wb")
1583   mfile.print(*configuration(srcprefix))
1584   mfile.print "
1585 libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1586 LIBPATH = #{libpath}
1587 DEFFILE = #{deffile}
1589 CLEANFILES = #{$cleanfiles.join(' ')}
1590 DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1592 extout = #{$extout}
1593 extout_prefix = #{$extout_prefix}
1594 target_prefix = #{target_prefix}
1595 LOCAL_LIBS = #{$LOCAL_LIBS}
1596 LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1597 SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1598 OBJS = #{$objs}
1599 TARGET = #{target}
1600 DLLIB = #{dllib}
1601 EXTSTATIC = #{$static || ""}
1602 STATIC_LIB = #{staticlib unless $static.nil?}
1603 #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
1604 " #"
1605   # TODO: fixme
1606   install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
1607   n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET)'
1608   mfile.print "
1609 TARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
1610 CLEANLIBS     = #{n}.#{CONFIG['DLEXT']} #{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
1611 CLEANOBJS     = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, '$(TARGET)')}} *.bak
1613 all:            #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1614 static:         $(STATIC_LIB)#{$extout ? " install-rb" : ""}
1616   mfile.print CLEANINGS
1617   dirs = []
1618   mfile.print "install: install-so install-rb\n\n"
1619   sodir = (dir = "$(RUBYARCHDIR)").dup
1620   mfile.print("install-so: ")
1621   if target
1622     f = "$(DLLIB)"
1623     dest = "#{dir}/#{f}"
1624     mfile.puts dir, "install-so: #{dest}"
1625     unless $extout
1626       mfile.print "#{dest}: #{f}\n"
1627       if (sep = config_string('BUILD_FILE_SEPARATOR'))
1628         f.gsub!("/", sep)
1629         dir.gsub!("/", sep)
1630         sep = ":/="+sep
1631         f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1632         f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1633         dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1634         dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1635       end
1636       mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
1637       if defined?($installed_list)
1638         mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
1639       end
1640     end
1641   else
1642     mfile.puts "Makefile"
1643   end
1644   mfile.print("install-rb: pre-install-rb install-rb-default\n")
1645   mfile.print("install-rb-default: pre-install-rb-default\n")
1646   mfile.print("pre-install-rb: Makefile\n")
1647   mfile.print("pre-install-rb-default: Makefile\n")
1648   for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
1649     files = install_files(mfile, i, nil, srcprefix) or next
1650     for dir, *files in files
1651       unless dirs.include?(dir)
1652         dirs << dir
1653         mfile.print "pre-install-rb#{sfx}: #{dir}\n"
1654       end if $nmake
1655       for f in files
1656         dest = "#{dir}/#{File.basename(f)}"
1657         mfile.print("install-rb#{sfx}: #{dest}\n")
1658         mfile.print("#{dest}: #{f}\n")
1659         mfile.print("\t$(MAKEDIRS) $(@D)\n") unless $nmake
1660         mfile.print("\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
1661         sep = config_string('BUILD_FILE_SEPARATOR')
1662         if sep
1663           f = f.gsub("/", sep)
1664           sep = ":/="+sep
1665           f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
1666           f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
1667         else
1668           sep = ""
1669         end
1670         mfile.print("#{f} $(@D#{sep})\n")
1671         if defined?($installed_list) and !$extout
1672           mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
1673         end
1674       end
1675     end
1676   end
1677   dirs.unshift(sodir) if target and !dirs.include?(sodir)
1678   dirs.each {|d| mfile.print "#{d}:\n\t$(MAKEDIRS) $@\n" if $nmake || d == sodir}
1680   mfile.print <<-SITEINSTALL
1682 site-install: site-install-so site-install-rb
1683 site-install-so: install-so
1684 site-install-rb: install-rb
1686   SITEINSTALL
1688   return unless target
1690   mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
1691   mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
1692   mfile.print "\n"
1694   CXX_EXT.each do |ext|
1695     COMPILE_RULES.each do |rule|
1696       mfile.printf(rule, ext, $OBJEXT)
1697       mfile.printf("\n\t%s\n\n", COMPILE_CXX)
1698     end
1699   end
1700   %w[c].each do |ext|
1701     COMPILE_RULES.each do |rule|
1702       mfile.printf(rule, ext, $OBJEXT)
1703       mfile.printf("\n\t%s\n\n", COMPILE_C)
1704     end
1705   end
1707   sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || ""
1708   mfile.print "$(RUBYARCHDIR)/" if $extout
1709   mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n"
1710   mfile.print "\t@-$(RM) $(@#{sep})\n"
1711   mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
1712   link_so = LINK_SO.gsub(/^/, "\t")
1713   if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===))
1714     link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
1715   end
1716   mfile.print link_so, "\n\n"
1717   unless $static.nil?
1718     mfile.print "$(STATIC_LIB): $(OBJS)\n\t@-$(RM) $(@#{sep})\n\t"
1719     mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
1720     config_string('RANLIB') do |ranlib|
1721       mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
1722     end
1723   end
1724   mfile.print "\n\n"
1725   if makedef
1726     mfile.print "$(DEFFILE): #{origdef}\n"
1727     mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
1728   end
1730   depend = File.join(srcdir, "depend")
1731   if File.exist?(depend)
1732     mfile.print("###\n", *depend_rules(File.read(depend)))
1733   else
1734     headers = %w[ruby.h defines.h]
1735     if RULE_SUBST
1736       headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))}
1737     end
1738     headers << $config_h if $config_h
1739     headers << '$(RUBY_EXTCONF_H)' if $extconf_h
1740     mfile.print "$(OBJS): ", headers.join(' '), "\n"
1741   end
1743   $makefile_created = true
1744 ensure
1745   mfile.close if mfile
1748 # :stopdoc:
1750 def init_mkmf(config = CONFIG)
1751   $makefile_created = false
1752   $arg_config = []
1753   $enable_shared = config['ENABLE_SHARED'] == 'yes'
1754   $defs = []
1755   $extconf_h = nil
1756   $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
1757   $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
1758   $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
1759   $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
1760   $INCFLAGS = "-I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir)"
1761   $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
1762   $LIBEXT = config['LIBEXT'].dup
1763   $OBJEXT = config["OBJEXT"].dup
1764   $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
1765   $LIBRUBYARG = ""
1766   $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
1767   $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
1768   $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"]
1769   $DEFLIBPATH.unshift(".")
1770   $LIBPATH = []
1771   $INSTALLFILES = []
1772   $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
1773   $VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby]
1775   $objs = nil
1776   $srcs = nil
1777   $libs = ""
1778   if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup)
1779     $LIBRUBYARG = config['LIBRUBYARG']
1780   end
1782   $LOCAL_LIBS = ""
1784   $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
1785   $cleanfiles << "mkmf.log"
1786   $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
1788   $extout ||= nil
1789   $extout_prefix ||= nil
1791   $arg_config.clear
1792   dir_config("opt")
1795 FailedMessage = <<MESSAGE
1796 Could not create Makefile due to some reason, probably lack of
1797 necessary libraries and/or headers.  Check the mkmf.log file for more
1798 details.  You may need configuration options.
1800 Provided configuration options:
1801 MESSAGE
1803 # Returns whether or not the Makefile was successfully generated. If not,
1804 # the script will abort with an error message.
1806 # Internal use only.
1808 def mkmf_failed(path)
1809   unless $makefile_created or File.exist?("Makefile")
1810     opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
1811     abort "*** #{path} failed ***\n" + FailedMessage + opts.join
1812   end
1815 # :startdoc:
1817 init_mkmf
1819 $make = with_config("make-prog", ENV["MAKE"] || "make")
1820 make, = Shellwords.shellwords($make)
1821 $nmake = nil
1822 case
1823 when $mswin
1824   $nmake = ?m if /nmake/i =~ make
1825 when $bccwin
1826   $nmake = ?b if /Borland/i =~ `#{make} -h`
1829 RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
1830   $srcdir = arg_config("--srcdir", File.dirname($0))
1831 $configure_args["--topsrcdir"] ||= $srcdir
1832 if $curdir = arg_config("--curdir")
1833   RbConfig.expand(curdir = $curdir.dup)
1834 else
1835   curdir = $curdir = "."
1837 unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir)
1838   CONFIG["topdir"] = $curdir
1839   RbConfig::CONFIG["topdir"] = curdir
1841 $configure_args["--topdir"] ||= $curdir
1842 $ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"]))
1844 split = Shellwords.method(:shellwords).to_proc
1846 EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
1848 hdr = ['#include "ruby.h"' "\n"]
1849 config_string('COMMON_MACROS') do |s|
1850   Shellwords.shellwords(s).each do |w|
1851     hdr << "#define " + w.split(/=/, 2).join(" ")
1852   end
1854 config_string('COMMON_HEADERS') do |s|
1855   Shellwords.shellwords(s).each {|w| hdr << "#include <#{w}>"}
1857 COMMON_HEADERS = hdr.join("\n")
1858 COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
1860 COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
1861 RULE_SUBST = config_string('RULE_SUBST')
1862 COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<'
1863 COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<'
1864 TRY_LINK = config_string('TRY_LINK') ||
1865   "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \
1866   "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
1867 LINK_SO = config_string('LINK_SO') ||
1868   if CONFIG["DLEXT"] == $OBJEXT
1869     "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
1870   else
1871     "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
1872     "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
1873   end
1874 LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
1875 RPATHFLAG = config_string('RPATHFLAG') || ''
1876 LIBARG = config_string('LIBARG') || '-l%s'
1878 sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if sep != "/"} || ""
1879 CLEANINGS = "
1880 clean:
1881                 @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
1883 distclean:      clean
1884                 @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
1885                 @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
1887 realclean:      distclean
1890 if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
1891   END {mkmf_failed($0)}