PageRenderTime 62ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ruby/1.8/mkmf.rb

https://github.com/MagLev/maglev
Ruby | 1851 lines | 1523 code | 90 blank | 238 comment | 106 complexity | 8993f93c1537d7078bcbd0210b88d03a MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. # module to create Makefile for extension modules
  2. # invoke like: ruby -r mkmf extconf.rb
  3. require 'rbconfig'
  4. # ---------------------- Changed for Maglev ------------------------------------
  5. $topdir = Config::MAKEFILE_CONFIG['includedir']
  6. $hdrdir = $topdir
  7. $top_srcdir = $topdir
  8. $extmk = false
  9. # Make sure the headers are extracted into the file-system
  10. unless File.exists?($hdrdir + "/ruby.h")
  11. abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
  12. end
  13. # -----------------------------------------------------------------------------
  14. require 'fileutils'
  15. require 'shellwords'
  16. CONFIG = Config::MAKEFILE_CONFIG
  17. ORIG_LIBPATH = ENV['LIB']
  18. CXX_EXT = %w[cc cxx cpp]
  19. if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']
  20. CXX_EXT.concat(%w[C])
  21. end
  22. SRC_EXT = %w[c m].concat(CXX_EXT)
  23. $static = $config_h = nil
  24. $default_static = $static
  25. unless defined? $configure_args
  26. $configure_args = {}
  27. args = CONFIG["configure_args"]
  28. if ENV["CONFIGURE_ARGS"]
  29. args << " " << ENV["CONFIGURE_ARGS"]
  30. end
  31. for arg in Shellwords::shellwords(args)
  32. arg, val = arg.split('=', 2)
  33. next unless arg
  34. arg.tr!('_', '-')
  35. if arg.sub!(/^(?!--)/, '--')
  36. val or next
  37. arg.downcase!
  38. end
  39. next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
  40. $configure_args[arg] = val || true
  41. end
  42. for arg in ARGV
  43. arg, val = arg.split('=', 2)
  44. next unless arg
  45. arg.tr!('_', '-')
  46. if arg.sub!(/^(?!--)/, '--')
  47. val or next
  48. arg.downcase!
  49. end
  50. $configure_args[arg] = val || true
  51. end
  52. end
  53. $libdir = CONFIG["libdir"]
  54. $rubylibdir = CONFIG["rubylibdir"]
  55. $archdir = CONFIG["archdir"]
  56. $sitedir = CONFIG["sitedir"]
  57. $sitelibdir = CONFIG["sitelibdir"]
  58. $sitearchdir = CONFIG["sitearchdir"]
  59. $vendordir = CONFIG["vendordir"]
  60. $vendorlibdir = CONFIG["vendorlibdir"]
  61. $vendorarchdir = CONFIG["vendorarchdir"]
  62. $mswin = /mswin/ =~ RUBY_PLATFORM
  63. $bccwin = /bccwin/ =~ RUBY_PLATFORM
  64. $mingw = /mingw/ =~ RUBY_PLATFORM
  65. $cygwin = /cygwin/ =~ RUBY_PLATFORM
  66. $human = /human/ =~ RUBY_PLATFORM
  67. $netbsd = /netbsd/ =~ RUBY_PLATFORM
  68. $os2 = /os2/ =~ RUBY_PLATFORM
  69. $beos = /beos/ =~ RUBY_PLATFORM
  70. $solaris = /solaris/ =~ RUBY_PLATFORM
  71. $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
  72. # :stopdoc:
  73. def config_string(key, config = CONFIG)
  74. s = config[key] and !s.empty? and block_given? ? yield(s) : s
  75. end
  76. def dir_re(dir)
  77. Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
  78. end
  79. INSTALL_DIRS = [
  80. [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
  81. [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
  82. [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
  83. [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
  84. [dir_re('archdir'), "$(RUBYARCHDIR)"],
  85. [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
  86. [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
  87. [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
  88. [dir_re('bindir'), "$(BINDIR)"],
  89. [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
  90. ]
  91. def install_dirs(target_prefix = nil)
  92. if $extout
  93. dirs = [
  94. ['BINDIR', '$(extout)/bin'],
  95. ['RUBYCOMMONDIR', '$(extout)/common'],
  96. ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'],
  97. ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
  98. ['extout', "#$extout"],
  99. ['extout_prefix', "#$extout_prefix"],
  100. ]
  101. elsif $extmk
  102. dirs = [
  103. ['BINDIR', '$(bindir)'],
  104. ['RUBYCOMMONDIR', '$(rubylibdir)'],
  105. ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
  106. ['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
  107. ]
  108. elsif $configure_args.has_key?('--vendor')
  109. dirs = [
  110. ['BINDIR', '$(bindir)'],
  111. ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
  112. ['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'],
  113. ['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'],
  114. ]
  115. else
  116. dirs = [
  117. ['BINDIR', '$(bindir)'],
  118. ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
  119. ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
  120. ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
  121. ]
  122. end
  123. dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
  124. dirs
  125. end
  126. def map_dir(dir, map = nil)
  127. map ||= INSTALL_DIRS
  128. map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
  129. end
  130. OUTFLAG = CONFIG['OUTFLAG']
  131. CPPOUTFILE = CONFIG['CPPOUTFILE']
  132. CONFTEST_C = "conftest.c"
  133. class String
  134. # Wraps a string in escaped quotes if it contains whitespace.
  135. def quote
  136. /\s/ =~ self ? "\"#{self}\"" : "#{self}"
  137. end
  138. # Generates a string used as cpp macro name.
  139. def tr_cpp
  140. strip.upcase.tr_s("^A-Z0-9_", "_")
  141. end
  142. end
  143. class Array
  144. # Wraps all strings in escaped quotes if they contain whitespace.
  145. def quote
  146. map {|s| s.quote}
  147. end
  148. end
  149. def rm_f(*files)
  150. FileUtils.rm_f(Dir[files.join("\0")])
  151. end
  152. # Returns time stamp of the +target+ file if it exists and is newer
  153. # than or equal to all of +times+.
  154. def modified?(target, times)
  155. (t = File.mtime(target)) rescue return nil
  156. Array === times or times = [times]
  157. t if times.all? {|n| n <= t}
  158. end
  159. def merge_libs(*libs)
  160. libs.inject([]) do |x, y|
  161. xy = x & y
  162. xn = yn = 0
  163. y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
  164. y.each_with_index do |v, yi|
  165. if xy.include?(v)
  166. xi = [x.index(v), xn].max()
  167. x[xi, 1] = y[yn..yi]
  168. xn, yn = xi + (yi - yn + 1), yi + 1
  169. end
  170. end
  171. x.concat(y[yn..-1] || [])
  172. end
  173. end
  174. # This is a custom logging module. It generates an mkmf.log file when you
  175. # run your extconf.rb script. This can be useful for debugging unexpected
  176. # failures.
  177. #
  178. # This module and its associated methods are meant for internal use only.
  179. #
  180. module Logging
  181. @log = nil
  182. @logfile = 'mkmf.log'
  183. @orgerr = $stderr
  184. @orgout = $stdout
  185. @postpone = 0
  186. @quiet = $extmk
  187. def self::open
  188. @log ||= File::open(@logfile, 'w')
  189. @log.sync = true
  190. # MagLev currently does not allow re-opening stdout / stderr
  191. # $stderr.reopen(@log)
  192. # $stdout.reopen(@log)
  193. yield
  194. ensure
  195. # $stderr.reopen(@orgerr)
  196. # $stdout.reopen(@orgout)
  197. end
  198. def self::message(*s)
  199. @log ||= File::open(@logfile, 'w')
  200. @log.sync = true
  201. @log.printf(*s)
  202. end
  203. def self::logfile file
  204. @logfile = file
  205. if @log and not @log.closed?
  206. @log.flush
  207. @log.close
  208. @log = nil
  209. end
  210. end
  211. def self::postpone
  212. tmplog = "mkmftmp#{@postpone += 1}.log"
  213. open do
  214. log, *save = @log, @logfile, @orgout, @orgerr
  215. @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
  216. begin
  217. log.print(open {yield})
  218. @log.close
  219. File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
  220. ensure
  221. @log, @logfile, @orgout, @orgerr = log, *save
  222. @postpone -= 1
  223. rm_f tmplog
  224. end
  225. end
  226. end
  227. class << self
  228. attr_accessor :quiet
  229. end
  230. end
  231. def xsystem command
  232. varpat = /\$\((\w+)\)|\$\{(\w+)\}/
  233. if varpat =~ command
  234. vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
  235. command = command.dup
  236. nil while command.gsub!(varpat) {vars[$1||$2]}
  237. end
  238. Logging::open do
  239. puts command.quote
  240. system(command)
  241. end
  242. end
  243. def xpopen command, *mode, &block
  244. Logging::open do
  245. case mode[0]
  246. when nil, /^r/
  247. puts "#{command} |"
  248. else
  249. puts "| #{command}"
  250. end
  251. IO.popen(command, *mode, &block)
  252. end
  253. end
  254. def log_src(src)
  255. src = src.split(/^/)
  256. fmt = "%#{src.size.to_s.size}d: %s"
  257. Logging::message <<"EOM"
  258. checked program was:
  259. /* begin */
  260. EOM
  261. src.each_with_index {|line, no| Logging::message fmt, no+1, line}
  262. Logging::message <<"EOM"
  263. /* end */
  264. EOM
  265. end
  266. def create_tmpsrc(src)
  267. src = yield(src) if block_given?
  268. src.gsub!(/[ \t]+$/, '')
  269. src.gsub!(/\A\n+|^\n+$/, '')
  270. src.sub!(/[^\n]\z/, "\\&\n")
  271. open(CONFTEST_C, "wb") do |cfile|
  272. cfile.print src
  273. end
  274. src
  275. end
  276. def try_do(src, command, &b)
  277. src = create_tmpsrc(src, &b)
  278. xsystem(command)
  279. ensure
  280. log_src(src)
  281. end
  282. def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
  283. conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote,
  284. 'src' => CONFTEST_C,
  285. 'INCFLAGS' => $INCFLAGS,
  286. 'CPPFLAGS' => $CPPFLAGS,
  287. 'CFLAGS' => "#$CFLAGS",
  288. 'ARCH_FLAG' => "#$ARCH_FLAG",
  289. 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
  290. 'LIBPATH' => libpathflag(libpath),
  291. 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
  292. 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
  293. Config::expand(TRY_LINK.dup, conf)
  294. end
  295. def cc_command(opt="")
  296. conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
  297. Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", conf)
  298. end
  299. def cpp_command(outfile, opt="")
  300. conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
  301. Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}", conf)
  302. end
  303. def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
  304. libpath.map{|x|
  305. case x
  306. when "$(topdir)", /\A\./
  307. LIBPATHFLAG
  308. else
  309. LIBPATHFLAG+RPATHFLAG
  310. end % x.quote
  311. }.join
  312. end
  313. def try_link0(src, opt="", &b)
  314. try_do(src, link_command("", opt), &b)
  315. end
  316. def try_link(src, opt="", &b)
  317. try_link0(src, opt, &b)
  318. ensure
  319. rm_f "conftest*", "c0x32*"
  320. end
  321. def try_compile(src, opt="", &b)
  322. try_do(src, cc_command(opt), &b)
  323. ensure
  324. rm_f "conftest*"
  325. end
  326. def try_cpp(src, opt="", &b)
  327. try_do(src, cpp_command(CPPOUTFILE, opt), &b)
  328. ensure
  329. rm_f "conftest*"
  330. end
  331. def cpp_include(header)
  332. if header
  333. header = [header] unless header.kind_of? Array
  334. header.map {|h| "#include <#{h}>\n"}.join
  335. else
  336. ""
  337. end
  338. end
  339. def with_cppflags(flags)
  340. cppflags = $CPPFLAGS
  341. $CPPFLAGS = flags
  342. ret = yield
  343. ensure
  344. $CPPFLAGS = cppflags unless ret
  345. end
  346. def with_cflags(flags)
  347. cflags = $CFLAGS
  348. $CFLAGS = flags
  349. ret = yield
  350. ensure
  351. $CFLAGS = cflags unless ret
  352. end
  353. def with_ldflags(flags)
  354. ldflags = $LDFLAGS
  355. $LDFLAGS = flags
  356. ret = yield
  357. ensure
  358. $LDFLAGS = ldflags unless ret
  359. end
  360. def try_static_assert(expr, headers = nil, opt = "", &b)
  361. headers = cpp_include(headers)
  362. try_compile(<<SRC, opt, &b)
  363. #{COMMON_HEADERS}
  364. #{headers}
  365. /*top*/
  366. int conftest_const[(#{expr}) ? 1 : -1];
  367. SRC
  368. end
  369. def try_constant(const, headers = nil, opt = "", &b)
  370. includes = cpp_include(headers)
  371. if CROSS_COMPILING
  372. if try_static_assert("#{const} > 0", headers, opt)
  373. # positive constant
  374. elsif try_static_assert("#{const} < 0", headers, opt)
  375. neg = true
  376. const = "-(#{const})"
  377. elsif try_static_assert("#{const} == 0", headers, opt)
  378. return 0
  379. else
  380. # not a constant
  381. return nil
  382. end
  383. upper = 1
  384. lower = 0
  385. until try_static_assert("#{const} <= #{upper}", headers, opt)
  386. lower = upper
  387. upper <<= 1
  388. end
  389. return nil unless lower
  390. while upper > lower + 1
  391. mid = (upper + lower) / 2
  392. if try_static_assert("#{const} > #{mid}", headers, opt)
  393. lower = mid
  394. else
  395. upper = mid
  396. end
  397. end
  398. upper = -upper if neg
  399. return upper
  400. else
  401. src = %{#{COMMON_HEADERS}
  402. #{includes}
  403. #include <stdio.h>
  404. /*top*/
  405. int conftest_const = (int)(#{const});
  406. int main() {printf("%d\\n", conftest_const); return 0;}
  407. }
  408. if try_link0(src, opt, &b)
  409. xpopen("./conftest") do |f|
  410. return Integer(f.gets)
  411. end
  412. end
  413. end
  414. nil
  415. end
  416. def try_func(func, libs, headers = nil, &b)
  417. headers = cpp_include(headers)
  418. try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
  419. #{COMMON_HEADERS}
  420. #{headers}
  421. /*top*/
  422. int main() { return 0; }
  423. int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
  424. SRC
  425. #{headers}
  426. /*top*/
  427. int main() { return 0; }
  428. int t() { #{func}(); return 0; }
  429. SRC
  430. end
  431. def try_var(var, headers = nil, &b)
  432. headers = cpp_include(headers)
  433. try_compile(<<"SRC", &b)
  434. #{COMMON_HEADERS}
  435. #{headers}
  436. /*top*/
  437. int main() { return 0; }
  438. int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
  439. SRC
  440. end
  441. def egrep_cpp(pat, src, opt = "", &b)
  442. src = create_tmpsrc(src, &b)
  443. xpopen(cpp_command('', opt)) do |f|
  444. if Regexp === pat
  445. puts(" ruby -ne 'print if #{pat.inspect}'")
  446. f.grep(pat) {|l|
  447. puts "#{f.lineno}: #{l}"
  448. return true
  449. }
  450. false
  451. else
  452. puts(" egrep '#{pat}'")
  453. begin
  454. stdin = $stdin.dup
  455. $stdin.reopen(f)
  456. system("egrep", pat)
  457. ensure
  458. $stdin.reopen(stdin)
  459. end
  460. end
  461. end
  462. ensure
  463. rm_f "conftest*"
  464. log_src(src)
  465. end
  466. # This is used internally by the have_macro? method.
  467. def macro_defined?(macro, src, opt = "", &b)
  468. src = src.sub(/[^\n]\z/, "\\&\n")
  469. try_compile(src + <<"SRC", opt, &b)
  470. /*top*/
  471. #ifndef #{macro}
  472. # error
  473. >>>>>> #{macro} undefined <<<<<<
  474. #endif
  475. SRC
  476. end
  477. def try_run(src, opt = "", &b)
  478. if try_link0(src, opt, &b)
  479. xsystem("./conftest")
  480. else
  481. nil
  482. end
  483. ensure
  484. rm_f "conftest*"
  485. end
  486. def install_files(mfile, ifiles, map = nil, srcprefix = nil)
  487. ifiles or return
  488. ifiles.empty? and return
  489. srcprefix ||= '$(srcdir)'
  490. Config::expand(srcdir = srcprefix.dup)
  491. dirs = []
  492. path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
  493. ifiles.each do |files, dir, prefix|
  494. dir = map_dir(dir, map)
  495. prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
  496. if /\A\.\// =~ files
  497. # install files which are in current working directory.
  498. files = files[2..-1]
  499. len = nil
  500. else
  501. # install files which are under the $(srcdir).
  502. files = File.join(srcdir, files)
  503. len = srcdir.size
  504. end
  505. f = nil
  506. Dir.glob(files) do |f|
  507. f[0..len] = "" if len
  508. case File.basename(f)
  509. when *$NONINSTALLFILES
  510. next
  511. end
  512. d = File.dirname(f)
  513. d.sub!(prefix, "") if prefix
  514. d = (d.empty? || d == ".") ? dir : File.join(dir, d)
  515. f = File.join(srcprefix, f) if len
  516. path[d] << f
  517. end
  518. unless len or f
  519. d = File.dirname(files)
  520. d.sub!(prefix, "") if prefix
  521. d = (d.empty? || d == ".") ? dir : File.join(dir, d)
  522. path[d] << files
  523. end
  524. end
  525. dirs
  526. end
  527. def install_rb(mfile, dest, srcdir = nil)
  528. install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
  529. end
  530. def append_library(libs, lib) # :no-doc:
  531. format(LIBARG, lib) + " " + libs
  532. end
  533. def message(*s)
  534. unless Logging.quiet and not $VERBOSE
  535. printf(*s)
  536. $stdout.flush
  537. end
  538. end
  539. # This emits a string to stdout that allows users to see the results of the
  540. # various have* and find* methods as they are tested.
  541. #
  542. # Internal use only.
  543. #
  544. def checking_for(m, fmt = nil)
  545. f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
  546. m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
  547. message "%s", m
  548. a = r = nil
  549. Logging::postpone do
  550. r = yield
  551. a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
  552. "#{f}#{m}-------------------- #{a}\n"
  553. end
  554. message(a)
  555. Logging::message "--------------------\n\n"
  556. r
  557. end
  558. def checking_message(target, place = nil, opt = nil)
  559. [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
  560. if noun
  561. [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
  562. if noun.respond_to?(meth)
  563. break noun = noun.send(meth, *args)
  564. end
  565. end
  566. msg << " #{pre} #{noun}" unless noun.empty?
  567. end
  568. msg
  569. end
  570. end
  571. # :startdoc:
  572. # Returns whether or not +macro+ is defined either in the common header
  573. # files or within any +headers+ you provide.
  574. #
  575. # Any options you pass to +opt+ are passed along to the compiler.
  576. #
  577. def have_macro(macro, headers = nil, opt = "", &b)
  578. checking_for checking_message(macro, headers, opt) do
  579. macro_defined?(macro, cpp_include(headers), opt, &b)
  580. end
  581. end
  582. # Returns whether or not the given entry point +func+ can be found within
  583. # +lib+. If +func+ is nil, the 'main()' entry point is used by default.
  584. # If found, it adds the library to list of libraries to be used when linking
  585. # your extension.
  586. #
  587. # If +headers+ are provided, it will include those header files as the
  588. # header files it looks in when searching for +func+.
  589. #
  590. # The real name of the library to be linked can be altered by
  591. # '--with-FOOlib' configuration option.
  592. #
  593. def have_library(lib, func = nil, headers = nil, &b)
  594. func = "main" if !func or func.empty?
  595. lib = with_config(lib+'lib', lib)
  596. checking_for checking_message("#{func}()", LIBARG%lib) do
  597. if COMMON_LIBS.include?(lib)
  598. true
  599. else
  600. libs = append_library($libs, lib)
  601. if try_func(func, libs, headers, &b)
  602. $libs = libs
  603. true
  604. else
  605. false
  606. end
  607. end
  608. end
  609. end
  610. # Returns whether or not the entry point +func+ can be found within the library
  611. # +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.
  612. # If +func+ is nil , then the main() function is used as the entry point.
  613. #
  614. # If +lib+ is found, then the path it was found on is added to the list of
  615. # library paths searched and linked against.
  616. #
  617. def find_library(lib, func, *paths, &b)
  618. func = "main" if !func or func.empty?
  619. lib = with_config(lib+'lib', lib)
  620. paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
  621. checking_for "#{func}() in #{LIBARG%lib}" do
  622. libpath = $LIBPATH
  623. libs = append_library($libs, lib)
  624. begin
  625. until r = try_func(func, libs, &b) or paths.empty?
  626. $LIBPATH = libpath | [paths.shift]
  627. end
  628. if r
  629. $libs = libs
  630. libpath = nil
  631. end
  632. ensure
  633. $LIBPATH = libpath if libpath
  634. end
  635. r
  636. end
  637. end
  638. # Returns whether or not the function +func+ can be found in the common
  639. # header files, or within any +headers+ that you provide. If found, a
  640. # macro is passed as a preprocessor constant to the compiler using the
  641. # function name, in uppercase, prepended with 'HAVE_'.
  642. #
  643. # For example, if have_func('foo') returned true, then the HAVE_FOO
  644. # preprocessor macro would be passed to the compiler.
  645. #
  646. def have_func(func, headers = nil, &b)
  647. checking_for checking_message("#{func}()", headers) do
  648. if egrep_cpp(/.*#{func}.*/, <<"SRC")
  649. #{COMMON_HEADERS}
  650. #{headers}
  651. /* top */
  652. int main() { return 0; }
  653. SRC
  654. $defs.push(format("-DHAVE_%s", func.tr_cpp))
  655. return true
  656. end
  657. if try_func(func, $libs, headers, &b)
  658. $defs.push(format("-DHAVE_%s", func.tr_cpp))
  659. true
  660. else
  661. false
  662. end
  663. end
  664. end
  665. # Returns whether or not the variable +var+ can be found in the common
  666. # header files, or within any +headers+ that you provide. If found, a
  667. # macro is passed as a preprocessor constant to the compiler using the
  668. # variable name, in uppercase, prepended with 'HAVE_'.
  669. #
  670. # For example, if have_var('foo') returned true, then the HAVE_FOO
  671. # preprocessor macro would be passed to the compiler.
  672. #
  673. def have_var(var, headers = nil, &b)
  674. checking_for checking_message(var, headers) do
  675. if try_var(var, headers, &b)
  676. $defs.push(format("-DHAVE_%s", var.tr_cpp))
  677. true
  678. else
  679. false
  680. end
  681. end
  682. end
  683. # Returns whether or not the given +header+ file can be found on your system.
  684. # If found, a macro is passed as a preprocessor constant to the compiler using
  685. # the header file name, in uppercase, prepended with 'HAVE_'.
  686. #
  687. # For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
  688. # preprocessor macro would be passed to the compiler.
  689. #
  690. def have_header(header, &b)
  691. checking_for header do
  692. if try_cpp(cpp_include(header), &b)
  693. $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
  694. true
  695. else
  696. false
  697. end
  698. end
  699. end
  700. # Instructs mkmf to search for the given +header+ in any of the +paths+
  701. # provided, and returns whether or not it was found in those paths.
  702. #
  703. # If the header is found then the path it was found on is added to the list
  704. # of included directories that are sent to the compiler (via the -I switch).
  705. #
  706. def find_header(header, *paths)
  707. message = checking_message(header, paths)
  708. header = cpp_include(header)
  709. checking_for message do
  710. if try_cpp(header)
  711. true
  712. else
  713. found = false
  714. paths.each do |dir|
  715. opt = "-I#{dir}".quote
  716. if try_cpp(header, opt)
  717. $INCFLAGS << " " << opt
  718. found = true
  719. break
  720. end
  721. end
  722. found
  723. end
  724. end
  725. end
  726. # Returns whether or not the struct of type +type+ contains +member+. If
  727. # it does not, or the struct type can't be found, then false is returned. You
  728. # may optionally specify additional +headers+ in which to look for the struct
  729. # (in addition to the common header files).
  730. #
  731. # If found, a macro is passed as a preprocessor constant to the compiler using
  732. # the member name, in uppercase, prepended with 'HAVE_ST_'.
  733. #
  734. # For example, if have_struct_member('struct foo', 'bar') returned true, then the
  735. # HAVE_ST_BAR preprocessor macro would be passed to the compiler.
  736. #
  737. def have_struct_member(type, member, headers = nil, &b)
  738. checking_for checking_message("#{type}.#{member}", headers) do
  739. if try_compile(<<"SRC", &b)
  740. #{COMMON_HEADERS}
  741. #{cpp_include(headers)}
  742. /*top*/
  743. int main() { return 0; }
  744. int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
  745. SRC
  746. $defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
  747. true
  748. else
  749. false
  750. end
  751. end
  752. end
  753. def try_type(type, headers = nil, opt = "", &b)
  754. if try_compile(<<"SRC", opt, &b)
  755. #{COMMON_HEADERS}
  756. #{cpp_include(headers)}
  757. /*top*/
  758. typedef #{type} conftest_type;
  759. int conftestval[sizeof(conftest_type)?1:-1];
  760. SRC
  761. $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
  762. true
  763. else
  764. false
  765. end
  766. end
  767. # Returns whether or not the static type +type+ is defined. You may
  768. # optionally pass additional +headers+ to check against in addition to the
  769. # common header files.
  770. #
  771. # You may also pass additional flags to +opt+ which are then passed along to
  772. # the compiler.
  773. #
  774. # If found, a macro is passed as a preprocessor constant to the compiler using
  775. # the type name, in uppercase, prepended with 'HAVE_TYPE_'.
  776. #
  777. # For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO
  778. # preprocessor macro would be passed to the compiler.
  779. #
  780. def have_type(type, headers = nil, opt = "", &b)
  781. checking_for checking_message(type, headers, opt) do
  782. try_type(type, headers, opt, &b)
  783. end
  784. end
  785. # Returns where the static type +type+ is defined.
  786. #
  787. # You may also pass additional flags to +opt+ which are then passed along to
  788. # the compiler.
  789. #
  790. # See also +have_type+.
  791. #
  792. def find_type(type, opt, *headers, &b)
  793. opt ||= ""
  794. fmt = "not found"
  795. def fmt.%(x)
  796. x ? x.respond_to?(:join) ? x.join(",") : x : self
  797. end
  798. checking_for checking_message(type, nil, opt), fmt do
  799. headers.find do |h|
  800. try_type(type, h, opt, &b)
  801. end
  802. end
  803. end
  804. def try_const(const, headers = nil, opt = "", &b)
  805. const, type = *const
  806. if try_compile(<<"SRC", opt, &b)
  807. #{COMMON_HEADERS}
  808. #{cpp_include(headers)}
  809. /*top*/
  810. typedef #{type || 'int'} conftest_type;
  811. conftest_type conftestval = #{type ? '' : '(int)'}#{const};
  812. SRC
  813. $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
  814. true
  815. else
  816. false
  817. end
  818. end
  819. # Returns whether or not the constant +const+ is defined. You may
  820. # optionally pass the +type+ of +const+ as <code>[const, type]</code>,
  821. # like as:
  822. #
  823. # have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
  824. #
  825. # You may also pass additional +headers+ to check against in addition
  826. # to the common header files, and additional flags to +opt+ which are
  827. # then passed along to the compiler.
  828. #
  829. # If found, a macro is passed as a preprocessor constant to the compiler using
  830. # the type name, in uppercase, prepended with 'HAVE_CONST_'.
  831. #
  832. # For example, if have_const('foo') returned true, then the HAVE_CONST_FOO
  833. # preprocessor macro would be passed to the compiler.
  834. #
  835. def have_const(const, headers = nil, opt = "", &b)
  836. checking_for checking_message([*const].compact.join(' '), headers, opt) do
  837. try_const(const, headers, opt, &b)
  838. end
  839. end
  840. # Returns the size of the given +type+. You may optionally specify additional
  841. # +headers+ to search in for the +type+.
  842. #
  843. # If found, a macro is passed as a preprocessor constant to the compiler using
  844. # the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
  845. # name, followed by '=X' where 'X' is the actual size.
  846. #
  847. # For example, if check_sizeof('mystruct') returned 12, then the
  848. # SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
  849. #
  850. def check_sizeof(type, headers = nil, &b)
  851. expr = "sizeof(#{type})"
  852. fmt = "%d"
  853. def fmt.%(x)
  854. x ? super : "failed"
  855. end
  856. checking_for checking_message("size of #{type}", headers), fmt do
  857. if size = try_constant(expr, headers, &b)
  858. $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
  859. size
  860. end
  861. end
  862. end
  863. # :stopdoc:
  864. # Used internally by the what_type? method to determine if +type+ is a scalar
  865. # pointer.
  866. def scalar_ptr_type?(type, member = nil, headers = nil, &b)
  867. try_compile(<<"SRC", &b) # pointer
  868. #{COMMON_HEADERS}
  869. #{cpp_include(headers)}
  870. /*top*/
  871. volatile #{type} conftestval;
  872. int main() { return 0; }
  873. int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
  874. SRC
  875. end
  876. # Used internally by the what_type? method to determine if +type+ is a scalar
  877. # pointer.
  878. def scalar_type?(type, member = nil, headers = nil, &b)
  879. try_compile(<<"SRC", &b) # pointer
  880. #{COMMON_HEADERS}
  881. #{cpp_include(headers)}
  882. /*top*/
  883. volatile #{type} conftestval;
  884. int main() { return 0; }
  885. int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
  886. SRC
  887. end
  888. def what_type?(type, member = nil, headers = nil, &b)
  889. m = "#{type}"
  890. name = type
  891. if member
  892. m << "." << member
  893. name = "(((#{type} *)0)->#{member})"
  894. end
  895. fmt = "seems %s"
  896. def fmt.%(x)
  897. x ? super : "unknown"
  898. end
  899. checking_for checking_message(m, headers), fmt do
  900. if scalar_ptr_type?(type, member, headers, &b)
  901. if try_static_assert("sizeof(*#{name}) == 1", headers)
  902. "string"
  903. end
  904. elsif scalar_type?(type, member, headers, &b)
  905. if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
  906. "long long"
  907. elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
  908. "long"
  909. elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
  910. "int"
  911. elsif try_static_assert("sizeof(#{name}) > 1", headers)
  912. "short"
  913. else
  914. "char"
  915. end
  916. end
  917. end
  918. end
  919. # This method is used internally by the find_executable method.
  920. #
  921. # Internal use only.
  922. #
  923. def find_executable0(bin, path = nil)
  924. ext = config_string('EXEEXT')
  925. if File.expand_path(bin) == bin
  926. return bin if File.executable?(bin)
  927. ext and File.executable?(file = bin + ext) and return file
  928. return nil
  929. end
  930. if path ||= ENV['PATH']
  931. path = path.split(File::PATH_SEPARATOR)
  932. else
  933. path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
  934. end
  935. file = nil
  936. path.each do |dir|
  937. return file if File.executable?(file = File.join(dir, bin))
  938. return file if ext and File.executable?(file << ext)
  939. end
  940. nil
  941. end
  942. # :startdoc:
  943. # Searches for the executable +bin+ on +path+. The default path is your
  944. # PATH environment variable. If that isn't defined, it will resort to
  945. # searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
  946. #
  947. # If found, it will return the full path, including the executable name,
  948. # of where it was found.
  949. #
  950. # Note that this method does not actually affect the generated Makefile.
  951. #
  952. def find_executable(bin, path = nil)
  953. checking_for checking_message(bin, path) do
  954. find_executable0(bin, path)
  955. end
  956. end
  957. # :stopdoc:
  958. def arg_config(config, *defaults, &block)
  959. $arg_config << [config, *defaults]
  960. defaults << nil if !block and defaults.empty?
  961. $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
  962. end
  963. # :startdoc:
  964. # Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>
  965. # option. Returns true if the with option is given, false if the without
  966. # option is given, and the default value otherwise.
  967. #
  968. # This can be useful for adding custom definitions, such as debug information.
  969. #
  970. # Example:
  971. #
  972. # if with_config("debug")
  973. # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
  974. # end
  975. #
  976. def with_config(config, *defaults)
  977. config = config.sub(/^--with[-_]/, '')
  978. val = arg_config("--with-"+config) do
  979. if arg_config("--without-"+config)
  980. false
  981. elsif block_given?
  982. yield(config, *defaults)
  983. else
  984. break *defaults
  985. end
  986. end
  987. case val
  988. when "yes"
  989. true
  990. when "no"
  991. false
  992. else
  993. val
  994. end
  995. end
  996. # Tests for the presence of an --enable-<tt>config</tt> or
  997. # --disable-<tt>config</tt> option. Returns true if the enable option is given,
  998. # false if the disable option is given, and the default value otherwise.
  999. #
  1000. # This can be useful for adding custom definitions, such as debug information.
  1001. #
  1002. # Example:
  1003. #
  1004. # if enable_config("debug")
  1005. # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
  1006. # end
  1007. #
  1008. def enable_config(config, *defaults)
  1009. if arg_config("--enable-"+config)
  1010. true
  1011. elsif arg_config("--disable-"+config)
  1012. false
  1013. elsif block_given?
  1014. yield(config, *defaults)
  1015. else
  1016. return *defaults
  1017. end
  1018. end
  1019. # Generates a header file consisting of the various macro definitions generated
  1020. # by other methods such as have_func and have_header. These are then wrapped in
  1021. # a custom #ifndef based on the +header+ file name, which defaults to
  1022. # 'extconf.h'.
  1023. #
  1024. # For example:
  1025. #
  1026. # # extconf.rb
  1027. # require 'mkmf'
  1028. # have_func('realpath')
  1029. # have_header('sys/utime.h')
  1030. # create_header
  1031. # create_makefile('foo')
  1032. #
  1033. # The above script would generate the following extconf.h file:
  1034. #
  1035. # #ifndef EXTCONF_H
  1036. # #define EXTCONF_H
  1037. # #define HAVE_REALPATH 1
  1038. # #define HAVE_SYS_UTIME_H 1
  1039. # #endif
  1040. #
  1041. # Given that the create_header method generates a file based on definitions
  1042. # set earlier in your extconf.rb file, you will probably want to make this
  1043. # one of the last methods you call in your script.
  1044. #
  1045. def create_header(header = "extconf.h")
  1046. message "creating %s\n", header
  1047. sym = header.tr("a-z./\055", "A-Z___")
  1048. hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
  1049. for line in $defs
  1050. case line
  1051. when /^-D([^=]+)(?:=(.*))?/
  1052. hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
  1053. when /^-U(.*)/
  1054. hdr << "#undef #$1\n"
  1055. end
  1056. end
  1057. hdr << "#endif\n"
  1058. hdr = hdr.join
  1059. unless (IO.read(header) == hdr rescue false)
  1060. open(header, "w") do |hfile|
  1061. hfile.write(hdr)
  1062. end
  1063. end
  1064. $extconf_h = header
  1065. end
  1066. # Sets a +target+ name that the user can then use to configure various 'with'
  1067. # options with on the command line by using that name. For example, if the
  1068. # target is set to "foo", then the user could use the --with-foo-dir command
  1069. # line option.
  1070. #
  1071. # You may pass along additional 'include' or 'lib' defaults via the +idefault+
  1072. # and +ldefault+ parameters, respectively.
  1073. #
  1074. # Note that dir_config only adds to the list of places to search for libraries
  1075. # and include files. It does not link the libraries into your application.
  1076. #
  1077. def dir_config(target, idefault=nil, ldefault=nil)
  1078. if dir = with_config(target + "-dir", (idefault unless ldefault))
  1079. defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
  1080. idefault = ldefault = nil
  1081. end
  1082. idir = with_config(target + "-include", idefault)
  1083. $arg_config.last[1] ||= "${#{target}-dir}/include"
  1084. ldir = with_config(target + "-lib", ldefault)
  1085. $arg_config.last[1] ||= "${#{target}-dir}/lib"
  1086. idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
  1087. if defaults
  1088. idirs.concat(defaults.collect {|dir| dir + "/include"})
  1089. idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
  1090. end
  1091. unless idirs.empty?
  1092. idirs.collect! {|dir| "-I" + dir}
  1093. idirs -= Shellwords.shellwords($CPPFLAGS)
  1094. unless idirs.empty?
  1095. $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
  1096. end
  1097. end
  1098. ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
  1099. if defaults
  1100. ldirs.concat(defaults.collect {|dir| dir + "/lib"})
  1101. ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
  1102. end
  1103. $LIBPATH = ldirs | $LIBPATH
  1104. [idir, ldir]
  1105. end
  1106. # :stopdoc:
  1107. # Handles meta information about installed libraries. Uses your platform's
  1108. # pkg-config program if it has one.
  1109. def pkg_config(pkg)
  1110. if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
  1111. # iff package specific config command is given
  1112. get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
  1113. elsif ($PKGCONFIG ||=
  1114. (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
  1115. find_executable0(pkgconfig) && pkgconfig) and
  1116. system("#{$PKGCONFIG} --exists #{pkg}")
  1117. # default to pkg-config command
  1118. get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
  1119. elsif find_executable0(pkgconfig = "#{pkg}-config")
  1120. # default to package specific config command, as a last resort.
  1121. get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
  1122. end
  1123. if get
  1124. cflags = get['cflags']
  1125. ldflags = get['libs']
  1126. libs = get['libs-only-l']
  1127. ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
  1128. $CFLAGS += " " << cflags
  1129. $LDFLAGS += " " << ldflags
  1130. $libs += " " << libs
  1131. Logging::message "package configuration for %s\n", pkg
  1132. Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
  1133. cflags, ldflags, libs
  1134. [cflags, ldflags, libs]
  1135. else
  1136. Logging::message "package configuration for %s is not found\n", pkg
  1137. nil
  1138. end
  1139. end
  1140. def with_destdir(dir)
  1141. dir = dir.sub($dest_prefix_pattern, '')
  1142. /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
  1143. end
  1144. # Converts forward slashes to backslashes. Aimed at MS Windows.
  1145. #
  1146. # Internal use only.
  1147. #
  1148. def winsep(s)
  1149. s.tr('/', '\\')
  1150. end
  1151. # Converts native path to format acceptable in Makefile
  1152. #
  1153. # Internal use only.
  1154. #
  1155. if !CROSS_COMPILING
  1156. case CONFIG['build_os']
  1157. when 'mingw32'
  1158. def mkintpath(path)
  1159. # mingw uses make from msys and it needs special care
  1160. # converts from C:\some\path to /C/some/path
  1161. path = path.dup
  1162. path.tr!('\\', '/')
  1163. path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
  1164. path
  1165. end
  1166. end
  1167. end
  1168. unless defined?(mkintpath)
  1169. def mkintpath(path)
  1170. path
  1171. end
  1172. end
  1173. def configuration(srcdir)
  1174. mk = []
  1175. vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
  1176. if !CROSS_COMPILING
  1177. case CONFIG['build_os']
  1178. when 'cygwin'
  1179. if CONFIG['target_os'] != 'cygwin'
  1180. vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
  1181. end
  1182. when 'msdosdjgpp'
  1183. CONFIG['PATH_SEPARATOR'] = ';'
  1184. end
  1185. end
  1186. mk << %{
  1187. SHELL = /bin/sh
  1188. #### Start of system configuration section. ####
  1189. #{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk}
  1190. srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
  1191. topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
  1192. hdrdir = #{mkintpath($extmk ? CONFIG["hdrdir"] : $hdrdir).quote}
  1193. VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
  1194. }
  1195. if $extmk
  1196. mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n"
  1197. end
  1198. if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
  1199. mk << "\nDESTDIR = #{destdir}\n"
  1200. end
  1201. CONFIG.each do |key, var|
  1202. next unless /prefix$/ =~ key
  1203. mk << "#{key} = #{with_destdir(var)}\n"
  1204. end
  1205. CONFIG.each do |key, var|
  1206. next if /^abs_/ =~ key
  1207. next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
  1208. mk << "#{key} = #{with_destdir(var)}\n"
  1209. end
  1210. if !$extmk and !$configure_args.has_key?('--ruby') and
  1211. sep = config_string('BUILD_FILE_SEPARATOR')
  1212. sep = ":/=#{sep}"
  1213. else
  1214. sep = ""
  1215. end
  1216. extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ") << " "
  1217. mk << %{
  1218. CC = #{CONFIG['CC']}
  1219. LIBRUBY = #{CONFIG['LIBRUBY']}
  1220. LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
  1221. LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
  1222. LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
  1223. RUBY_EXTCONF_H = #{$extconf_h}
  1224. CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
  1225. INCFLAGS = -I. #$INCFLAGS
  1226. DEFS = #{CONFIG['DEFS']}
  1227. CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
  1228. CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
  1229. ldflags = #{$LDFLAGS}
  1230. dldflags = #{$DLDFLAGS}
  1231. archflag = #{$ARCH_FLAG}
  1232. DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
  1233. LDSHARED = #{CONFIG['LDSHARED']}
  1234. AR = #{CONFIG['AR']}
  1235. EXEEXT = #{CONFIG['EXEEXT']}
  1236. RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
  1237. RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
  1238. arch = #{CONFIG['arch']}
  1239. sitearch = #{CONFIG['sitearch']}
  1240. ruby_version = #{Config::CONFIG['ruby_version']}
  1241. ruby = #{$ruby}
  1242. RUBY = $(ruby#{sep})
  1243. RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
  1244. MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
  1245. INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
  1246. INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
  1247. INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
  1248. COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
  1249. #### End of system configuration section. ####
  1250. preload = #{$preload ? $preload.join(' ') : ''}
  1251. }
  1252. if $nmake == ?b
  1253. mk.each do |x|
  1254. x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
  1255. "!ifndef " + $1 + "\n" +
  1256. $& +
  1257. "!endif\n"
  1258. end
  1259. end
  1260. end
  1261. mk
  1262. end
  1263. def dummy_makefile(srcdir)
  1264. configuration(srcdir) << <<RULES << CLEANINGS
  1265. CLEANFILES = #{$cleanfiles.join(' ')}
  1266. DISTCLEANFILES = #{$distcleanfiles.join(' ')}
  1267. all install static install-so install-rb: Makefile
  1268. .PHONY: all install static install-so install-rb
  1269. .PHONY: clean clean-so clean-rb
  1270. RULES
  1271. end
  1272. # :startdoc:
  1273. # Generates the Makefile for your extension, passing along any options and
  1274. # preprocessor constants that you may have generated through other methods.
  1275. #
  1276. # The +target+ name should correspond the name of the global function name
  1277. # defined within your C extension, minus the 'Init_'. For example, if your
  1278. # C extension is defined as 'Init_foo', then your target would simply be 'foo'.
  1279. #
  1280. # If any '/' characters are present in the target name, only the last name
  1281. # is interpreted as the target name, and the rest are considered toplevel
  1282. # directory names, and the generated Makefile will be altered accordingly to
  1283. # follow that directory structure.
  1284. #
  1285. # For example, if you pass 'test/foo' as a target name, your extension will
  1286. # be installed under the 'test' directory. This means that in order to
  1287. # load the file within a Ruby program later, that directory structure will
  1288. # have to be followed, e.g. "require 'test/foo'".
  1289. #
  1290. # The +srcprefix+ should be used when your source files are not in the same
  1291. # directory as your build script. This will not only eliminate the need for
  1292. # you to manually copy the source files into the same directory as your build
  1293. # script, but it also sets the proper +target_prefix+ in the generated
  1294. # Makefile.
  1295. #
  1296. # Setting the +target_prefix+ will, in turn, install the generated binary in
  1297. # a directory under your Config::CONFIG['sitearchdir'] that mimics your local
  1298. # filesystem when you run 'make install'.
  1299. #
  1300. # For example, given the following file tree:
  1301. #
  1302. # ext/
  1303. # extconf.rb
  1304. # test/
  1305. # foo.c
  1306. #
  1307. # And given the following code:
  1308. #
  1309. # create_makefile('test/foo', 'test')
  1310. #
  1311. # That will set the +target_prefix+ in the generated Makefile to 'test'. That,
  1312. # in turn, will create the following file tree when installed via the
  1313. # 'make install' command:
  1314. #
  1315. # /path/to/ruby/sitearchdir/test/foo.so
  1316. #
  1317. # It is recommended that you use this approach to generate your makefiles,
  1318. # instead of copying files around manually, because some third party
  1319. # libraries may depend on the +target_prefix+ being set properly.
  1320. #
  1321. # The +srcprefix+ argument can be used to override the default source
  1322. # directory, i.e. the current directory . It is included as part of the VPATH
  1323. # and added to the list of INCFLAGS.
  1324. #
  1325. def create_makefile(target, srcprefix = nil)
  1326. $target = target
  1327. libpath = $DEFLIBPATH|$LIBPATH
  1328. message "creating Makefile\n"
  1329. rm_f "conftest*"
  1330. if CONFIG["DLEXT"] == $OBJEXT
  1331. for lib in libs = $libs.split
  1332. lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
  1333. end
  1334. $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
  1335. end
  1336. if target.include?('/')
  1337. target_prefix, target = File.split(target)
  1338. target_prefix[0,0] = '/'
  1339. else
  1340. target_prefix = ""
  1341. end
  1342. srcprefix ||= '$(srcdir)'
  1343. Config::expand(srcdir = srcprefix.dup)
  1344. if not $objs
  1345. $objs = []
  1346. srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
  1347. for f in srcs
  1348. obj = File.basename(f, ".*") << ".o"
  1349. $objs.push(obj) unless $objs.index(obj)
  1350. end
  1351. elsif !(srcs = $srcs)
  1352. srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
  1353. end
  1354. $srcs = srcs
  1355. for i in $objs
  1356. i.sub!(/\.o\z/, ".#{$OBJEXT}")
  1357. end
  1358. target = nil if $objs.empty?
  1359. if target and EXPORT_PREFIX
  1360. if File.exist?(File.join(srcdir, target + '.def'))
  1361. deffile = "$(srcdir)/$(TARGET).def"
  1362. unless EXPORT_PREFIX.empty?
  1363. makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
  1364. end
  1365. else
  1366. makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
  1367. end
  1368. if makedef
  1369. $distcleanfiles << '$(DEFFILE)'
  1370. origdef = deffile
  1371. deffile = "$(TARGET)-$(arch).def"
  1372. end
  1373. end
  1374. origdef ||= ''
  1375. libpath = libpathflag(libpath)
  1376. dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
  1377. staticlib = target ? "$(TARGET).#$LIBEXT" : ""
  1378. mfile = open("Makefile", "wb")
  1379. mfile.print configuration(srcprefix)
  1380. mfile.print "
  1381. libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
  1382. LIBPATH = #{libpath}
  1383. DEFFILE = #{deffile}
  1384. CLEANFILES = #{$cleanfiles.join(' ')}
  1385. DISTCLEANFILES = #{$distcleanfiles.join(' ')}
  1386. extout = #{$extout && $extout.quote}
  1387. extout_prefix = #{$extout_prefix}
  1388. target_prefix = #{target_prefix}
  1389. LOCAL_LIBS = #{$LOCAL_LIBS}
  1390. LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
  1391. SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
  1392. OBJS = #{$objs.join(" ")}
  1393. TARGET = #{target}
  1394. DLLIB = #{dllib}
  1395. EXTSTATIC = #{$static || ""}
  1396. STATIC_LIB = #{staticlib unless $static.nil?}
  1397. #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
  1398. "
  1399. install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
  1400. n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
  1401. mfile.print "
  1402. TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
  1403. CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
  1404. CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
  1405. all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
  1406. static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
  1407. .PHONY: all install static install-so install-rb
  1408. .PHONY: clean clean-so clean-rb
  1409. "
  1410. mfile.print CLEANINGS
  1411. dirs = []
  1412. mfile.print "install: install-so install-rb\n\n"
  1413. sodir = (dir = "$(RUBYARCHDIR)").dup
  1414. mfile.print("install-so: ")
  1415. if target
  1416. f = "$(DLLIB)"
  1417. dest = "#{dir}/#{f}"
  1418. mfile.puts dir, "install-so: #{dest}"
  1419. unless $extout
  1420. mfile.print "#{dest}: #{f}\n"
  1421. if (sep = config_string('BUILD_FILE_SEPARATOR'))
  1422. f.gsub!("/", sep)
  1423. dir.gsub!("/", sep)
  1424. sep = ":/="+sep
  1425. f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
  1426. f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
  1427. dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
  1428. dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
  1429. end
  1430. mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
  1431. if defined?($installed_list)
  1432. mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
  1433. end
  1434. end
  1435. else
  1436. mfile.puts "Makefile"
  1437. end
  1438. mfile.print("install-rb: pre-install-rb install-rb-default\n")
  1439. mfile.print("install-rb-default: pre-install-rb-default\n")
  1440. mfile.print("pre-install-rb: Makefile\n")
  1441. mfile.print("pre-install-rb-default: Makefile\n")
  1442. for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
  1443. files = install_files(mfile, i, nil, srcprefix) or next
  1444. for dir, *files in files
  1445. unless dirs.include?(dir)
  1446. dirs << dir
  1447. mfile.print "pre-install-rb#{sfx}: #{dir}\n"
  1448. end
  1449. files.each do |f|
  1450. dest = "#{dir}/#{File.basename(f)}"
  1451. mfile.print("install-rb#{sfx}: #{dest}\n")
  1452. mfile.print("#{dest}: #{f} #{dir}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
  1453. sep = config_string('BUILD_FILE_SEPARATOR')
  1454. if sep
  1455. f = f.gsub("/", sep)
  1456. sep = ":/="+sep
  1457. f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
  1458. f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
  1459. else
  1460. sep = ""
  1461. end
  1462. mfile.print("#{f} $(@D#{sep})\n")
  1463. if defined?($installed_list) and !$extout
  1464. mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
  1465. end
  1466. end
  1467. end
  1468. end
  1469. dirs.unshift(sodir) if target and !dirs.include?(sodir)
  1470. dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
  1471. mfile.print <<-SITEINSTALL
  1472. site-install: site-install-so site-install-rb
  1473. site-install-so: install-so
  1474. site-install-rb: install-rb
  1475. SITEINSTALL
  1476. return unless target
  1477. mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
  1478. mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
  1479. mfile.print "\n"
  1480. CXX_EXT.each do |ext|
  1481. COMPILE_RULES.each do |rule|
  1482. mfile.printf(rule, ext, $OBJEXT)
  1483. mfile.printf("\n\t%s\n\n", COMPILE_CXX)
  1484. end
  1485. end
  1486. %w[c].each do |ext|
  1487. COMPILE_RULES.each do |rule|
  1488. mfile.printf(rule, ext, $OBJEXT)
  1489. mfile.printf("\n\t%s\n\n", COMPILE_C)
  1490. end
  1491. end
  1492. mfile.print "$(RUBYARCHDIR)/" if $extout
  1493. mfile.print "$(DLLIB): "
  1494. mfile.print "$(DEFFILE) " if makedef
  1495. mfile.print "$(OBJS) Makefile\n"
  1496. mfile.print "\t@-$(RM) $@\n"
  1497. mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
  1498. link_so = LINK_SO.gsub(/^/, "\t")
  1499. mfile.print link_so, "\n\n"
  1500. unless $static.nil?
  1501. mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
  1502. mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
  1503. config_string('RANLIB') do |ranlib|
  1504. mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
  1505. end
  1506. end
  1507. mfile.print "\n\n"
  1508. if makedef
  1509. mfile.print "$(DEFFILE): #{origdef}\n"
  1510. mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
  1511. end
  1512. depend = File.join(srcdir, "depend")
  1513. if File.exist?(depend)
  1514. suffixes = []
  1515. depout = []
  1516. open(depend, "r") do |dfile|
  1517. mfile.printf "###\n"
  1518. cont = implicit = nil
  1519. impconv = proc do
  1520. COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
  1521. implicit = nil
  1522. end
  1523. ruleconv = proc do |line|
  1524. if implicit
  1525. if /\A\t/ =~ line
  1526. implicit[1] << line
  1527. next
  1528. else
  1529. impconv[]
  1530. end
  1531. end
  1532. if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
  1533. suffixes << m[1] << m[2]
  1534. implicit = [[m[1], m[2]], [m.post_match]]
  1535. next
  1536. elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
  1537. line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
  1538. end
  1539. depout << line
  1540. end
  1541. while line = dfile.gets()
  1542. line.gsub!(/\.o\b/, ".#{$OBJEXT}")
  1543. line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
  1544. if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
  1545. (cont ||= []) << line
  1546. next
  1547. elsif cont
  1548. line = (cont << line).join
  1549. cont = nil
  1550. end
  1551. ruleconv.call(line)
  1552. end
  1553. if cont
  1554. ruleconv.call(cont.join)
  1555. elsif implicit
  1556. impconv.call
  1557. end
  1558. end
  1559. unless suffixes.empty?
  1560. mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
  1561. end
  1562. mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
  1563. mfile.print depout
  1564. else
  1565. headers = []
  1566. if RULE_SUBST
  1567. headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
  1568. end
  1569. headers << $config_h if $config_h
  1570. headers << "$(RUBY_EXTCONF_H)" if $extconf_h
  1571. mfile.print "$(OBJS): ", headers.join(' '), "\n"
  1572. end
  1573. $makefile_created = true
  1574. ensure
  1575. mfile.close if mfile
  1576. end
  1577. # :stopdoc:
  1578. # define MAGLEV_LINT in your enviroment to detect via compile errors,
  1579. # common usage patterns where RTEST macro is likely missing in C code.
  1580. def init_mkmf(config = CONFIG)
  1581. $makefile_created = false
  1582. $arg_config = []
  1583. $enable_shared = config['ENABLE_SHARED'] == 'yes'
  1584. $defs = []
  1585. $defs.push("MAGLEV_LINT") if ENV["MAGLEV_LINT"]
  1586. $extconf_h = nil
  1587. $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"]))
  1588. $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"]))
  1589. $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"]))
  1590. $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"]))
  1591. $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
  1592. $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"]))
  1593. $LIBEXT = config['LIBEXT']
  1594. $OBJEXT = config["OBJEXT"]
  1595. $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
  1596. $LIBRUBYARG = ""
  1597. $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
  1598. $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
  1599. $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
  1600. $DEFLIBPATH.unshift(".")
  1601. $LIBPATH = []
  1602. $INSTALLFILES = []
  1603. $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
  1604. $objs = nil
  1605. $srcs = nil
  1606. $libs = ""
  1607. if $enable_shared or Config.expand(config["LIBRUBY"]) != Config.expand(config["LIBRUBY_A"])
  1608. $LIBRUBYARG = config['LIBRUBYARG']
  1609. end
  1610. $LOCAL_LIBS = ""
  1611. $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
  1612. $cleanfiles << "mkmf.log"
  1613. $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
  1614. $extout ||= nil
  1615. $extout_prefix ||= nil
  1616. $arg_config.clear
  1617. dir_config("opt")
  1618. end
  1619. FailedMessage = <<MESSAGE
  1620. Could not create Makefile due to some reason, probably lack of
  1621. necessary libraries and/or headers. Check the mkmf.log file for more
  1622. details. You may need configuration options.
  1623. Provided configuration options:
  1624. MESSAGE
  1625. # Returns whether or not the Makefile was successfully generated. If not

Large files files are truncated, but you can click here to view the full file