PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/mkmf.rb

https://github.com/EarthJem/ruby
Ruby | 2613 lines | 2071 code | 157 blank | 385 comment | 155 complexity | 3d520450b3ec93643daead441bb9fa00 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause

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

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

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