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