PageRenderTime 61ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/mkmf.rb

https://github.com/nazy/ruby
Ruby | 2171 lines | 1777 code | 111 blank | 283 comment | 140 complexity | 190eefcc59afc25a15186cee661f411c MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0, 0BSD, Unlicense

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

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

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