mkmf.rb

Path: lib/mkmf.rb
Last Update: Wed Oct 19 22:21:44 +0000 2011

module to create Makefile for extension modules invoke like: ruby -r mkmf extconf.rb

Required files

rbconfig   fileutils   shellwords  

Methods

Constants

CONFIG = Config::MAKEFILE_CONFIG
ORIG_LIBPATH = ENV['LIB']
CXX_EXT = %w[cc cxx cpp]
SRC_EXT = %w[c m].concat(CXX_EXT)
EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
COMMON_HEADERS = hdr.join("\n")
COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
RULE_SUBST = config_string('RULE_SUBST')
COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<'
COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<'
TRY_LINK = config_string('TRY_LINK') || "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \ "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
LINK_SO = config_string('LINK_SO') || if CONFIG["DLEXT"] == $OBJEXT

Public Instance methods

Returns the size of the given type. You may optionally specify additional headers to search in for the type.

If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with ‘SIZEOF_’, followed by the type name, followed by ’=X’ where ‘X’ is the actual size.

For example, if check_sizeof(‘mystruct’) returned 12, then the SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 922
922: def check_sizeof(type, headers = nil, &b)
923:   expr = "sizeof(#{type})"
924:   fmt = "%d"
925:   def fmt.%(x)
926:     x ? super : "failed"
927:   end
928:   checking_for checking_message("size of #{type}", headers), fmt do
929:     if size = try_constant(expr, headers, &b)
930:       $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
931:       size
932:     end
933:   end
934: end

Generates a header file consisting of the various macro definitions generated by other methods such as have_func and have_header. These are then wrapped in a custom ifndef based on the header file name, which defaults to ‘extconf.h’.

For example:

   # extconf.rb
   require 'mkmf'
   have_func('realpath')
   have_header('sys/utime.h')
   create_header
   create_makefile('foo')

The above script would generate the following extconf.h file:

   #ifndef EXTCONF_H
   #define EXTCONF_H
   #define HAVE_REALPATH 1
   #define HAVE_SYS_UTIME_H 1
   #endif

Given that the create_header method generates a file based on definitions set earlier in your extconf.rb file, you will probably want to make this one of the last methods you call in your script.

[Source]

      # File lib/mkmf.rb, line 1132
1132: def create_header(header = "extconf.h")
1133:   message "creating %s\n", header
1134:   sym = header.tr("a-z./\055", "A-Z___")
1135:   hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1136:   for line in $defs
1137:     case line
1138:     when /^-D([^=]+)(?:=(.*))?/
1139:       hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
1140:     when /^-U(.*)/
1141:       hdr << "#undef #$1\n"
1142:     end
1143:   end
1144:   hdr << "#endif\n"
1145:   hdr = hdr.join
1146:   unless (IO.read(header) == hdr rescue false)
1147:     open(header, "w") do |hfile|
1148:       hfile.write(hdr)
1149:     end
1150:   end
1151:   $extconf_h = header
1152: end

Generates the Makefile for your extension, passing along any options and preprocessor constants that you may have generated through other methods.

The target name should correspond the name of the global function name defined within your C extension, minus the ‘Init_’. For example, if your C extension is defined as ‘Init_foo’, then your target would simply be ‘foo’.

If any ’/’ characters are present in the target name, only the last name is interpreted as the target name, and the rest are considered toplevel directory names, and the generated Makefile will be altered accordingly to follow that directory structure.

For example, if you pass ‘test/foo’ as a target name, your extension will be installed under the ‘test’ directory. This means that in order to load the file within a Ruby program later, that directory structure will have to be followed, e.g. "require ‘test/foo’".

The srcprefix should be used when your source files are not in the same directory as your build script. This will not only eliminate the need for you to manually copy the source files into the same directory as your build script, but it also sets the proper target_prefix in the generated Makefile.

Setting the target_prefix will, in turn, install the generated binary in a directory under your Config::CONFIG[‘sitearchdir’] that mimics your local filesystem when you run ‘make install’.

For example, given the following file tree:

   ext/
      extconf.rb
      test/
         foo.c

And given the following code:

   create_makefile('test/foo', 'test')

That will set the target_prefix in the generated Makefile to ‘test’. That, in turn, will create the following file tree when installed via the ‘make install’ command:

   /path/to/ruby/sitearchdir/test/foo.so

It is recommended that you use this approach to generate your makefiles, instead of copying files around manually, because some third party libraries may depend on the target_prefix being set properly.

The srcprefix argument can be used to override the default source directory, i.e. the current directory . It is included as part of the VPATH and added to the list of INCFLAGS.

[Source]

      # File lib/mkmf.rb, line 1435
1435: def create_makefile(target, srcprefix = nil)
1436:   $target = target
1437:   libpath = $DEFLIBPATH|$LIBPATH
1438:   message "creating Makefile\n"
1439:   rm_f "conftest*"
1440:   if CONFIG["DLEXT"] == $OBJEXT
1441:     for lib in libs = $libs.split
1442:       lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
1443:     end
1444:     $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
1445:   end
1446: 
1447:   if target.include?('/')
1448:     target_prefix, target = File.split(target)
1449:     target_prefix[0,0] = '/'
1450:   else
1451:     target_prefix = ""
1452:   end
1453: 
1454:   srcprefix ||= '$(srcdir)'
1455:   Config::expand(srcdir = srcprefix.dup)
1456: 
1457:   if not $objs
1458:     $objs = []
1459:     srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1460:     for f in srcs
1461:       obj = File.basename(f, ".*") << ".o"
1462:       $objs.push(obj) unless $objs.index(obj)
1463:     end
1464:   elsif !(srcs = $srcs)
1465:     srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
1466:   end
1467:   $srcs = srcs
1468:   for i in $objs
1469:     i.sub!(/\.o\z/, ".#{$OBJEXT}")
1470:   end
1471:   $objs = $objs.join(" ")
1472: 
1473:   target = nil if $objs == ""
1474: 
1475:   if target and EXPORT_PREFIX
1476:     if File.exist?(File.join(srcdir, target + '.def'))
1477:       deffile = "$(srcdir)/$(TARGET).def"
1478:       unless EXPORT_PREFIX.empty?
1479:         makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
1480:       end
1481:     else
1482:       makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
1483:     end
1484:     if makedef
1485:       $distcleanfiles << '$(DEFFILE)'
1486:       origdef = deffile
1487:       deffile = "$(TARGET)-$(arch).def"
1488:     end
1489:   end
1490:   origdef ||= ''
1491: 
1492:   libpath = libpathflag(libpath)
1493: 
1494:   dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1495:   staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1496:   mfile = open("Makefile", "wb")
1497:   mfile.print configuration(srcprefix)
1498:   mfile.print "
1499: libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1500: LIBPATH = #{libpath}
1501: DEFFILE = #{deffile}
1502: 
1503: CLEANFILES = #{$cleanfiles.join(' ')}
1504: DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1505: 
1506: extout = #{$extout}
1507: extout_prefix = #{$extout_prefix}
1508: target_prefix = #{target_prefix}
1509: LOCAL_LIBS = #{$LOCAL_LIBS}
1510: LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1511: SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1512: OBJS = #{$objs}
1513: TARGET = #{target}
1514: DLLIB = #{dllib}
1515: EXTSTATIC = #{$static || ""}
1516: STATIC_LIB = #{staticlib unless $static.nil?}
1517: #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
1518: "
1519:   install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
1520:   n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
1521:   mfile.print "
1522: TARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
1523: CLEANLIBS     = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
1524: CLEANOBJS     = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
1525: 
1526: all:            #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1527: static:         $(STATIC_LIB)#{$extout ? " install-rb" : ""}
1528: "
1529:   mfile.print CLEANINGS
1530:   dirs = []
1531:   mfile.print "install: install-so install-rb\n\n"
1532:   sodir = (dir = "$(RUBYARCHDIR)").dup
1533:   mfile.print("install-so: ")
1534:   if target
1535:     f = "$(DLLIB)"
1536:     dest = "#{dir}/#{f}"
1537:     mfile.puts dir, "install-so: #{dest}"
1538:     unless $extout
1539:       mfile.print "#{dest}: #{f}\n"
1540:       if (sep = config_string('BUILD_FILE_SEPARATOR'))
1541:         f.gsub!("/", sep)
1542:         dir.gsub!("/", sep)
1543:         sep = ":/="+sep
1544:         f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1545:         f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1546:         dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1547:         dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1548:       end
1549:       mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
1550:       if defined?($installed_list)
1551:         mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
1552:       end
1553:     end
1554:   else
1555:     mfile.puts "Makefile"
1556:   end
1557:   mfile.print("install-rb: pre-install-rb install-rb-default\n")
1558:   mfile.print("install-rb-default: pre-install-rb-default\n")
1559:   mfile.print("pre-install-rb: Makefile\n")
1560:   mfile.print("pre-install-rb-default: Makefile\n")
1561:   for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
1562:     files = install_files(mfile, i, nil, srcprefix) or next
1563:     for dir, *files in files
1564:       unless dirs.include?(dir)
1565:         dirs << dir
1566:         mfile.print "pre-install-rb#{sfx}: #{dir}\n"
1567:       end
1568:       files.each do |f|
1569:         dest = "#{dir}/#{File.basename(f)}"
1570:         mfile.print("install-rb#{sfx}: #{dest}\n")
1571:         mfile.print("#{dest}: #{f} #{dir}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
1572:         sep = config_string('BUILD_FILE_SEPARATOR')
1573:         if sep
1574:           f = f.gsub("/", sep)
1575:           sep = ":/="+sep
1576:           f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
1577:           f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
1578:         else
1579:           sep = ""
1580:         end
1581:         mfile.print("#{f} $(@D#{sep})\n")
1582:         if defined?($installed_list) and !$extout
1583:           mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
1584:         end
1585:       end
1586:     end
1587:   end
1588:   dirs.unshift(sodir) if target and !dirs.include?(sodir)
1589:   dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
1590: 
1591:   mfile.print "\nsite-install: site-install-so site-install-rb\nsite-install-so: install-so\nsite-install-rb: install-rb\n\n"
1592: 
1593:   return unless target
1594: 
1595:   mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
1596:   mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
1597:   mfile.print "\n"
1598: 
1599:   CXX_EXT.each do |ext|
1600:     COMPILE_RULES.each do |rule|
1601:       mfile.printf(rule, ext, $OBJEXT)
1602:       mfile.printf("\n\t%s\n\n", COMPILE_CXX)
1603:     end
1604:   end
1605:   %w[c].each do |ext|
1606:     COMPILE_RULES.each do |rule|
1607:       mfile.printf(rule, ext, $OBJEXT)
1608:       mfile.printf("\n\t%s\n\n", COMPILE_C)
1609:     end
1610:   end
1611: 
1612:   mfile.print "$(RUBYARCHDIR)/" if $extout
1613:   mfile.print "$(DLLIB): "
1614:   mfile.print "$(DEFFILE) " if makedef
1615:   mfile.print "$(OBJS) Makefile\n"
1616:   mfile.print "\t@-$(RM) $@\n"
1617:   mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
1618:   link_so = LINK_SO.gsub(/^/, "\t")
1619:   mfile.print link_so, "\n\n"
1620:   unless $static.nil?
1621:     mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
1622:     mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
1623:     config_string('RANLIB') do |ranlib|
1624:       mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
1625:     end
1626:   end
1627:   mfile.print "\n\n"
1628:   if makedef
1629:     mfile.print "$(DEFFILE): #{origdef}\n"
1630:     mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
1631:   end
1632: 
1633:   depend = File.join(srcdir, "depend")
1634:   if File.exist?(depend)
1635:     suffixes = []
1636:     depout = []
1637:     open(depend, "r") do |dfile|
1638:       mfile.printf "###\n"
1639:       cont = implicit = nil
1640:       impconv = proc do
1641:         COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
1642:         implicit = nil
1643:       end
1644:       ruleconv = proc do |line|
1645:         if implicit
1646:           if /\A\t/ =~ line
1647:             implicit[1] << line
1648:             next
1649:           else
1650:             impconv[]
1651:           end
1652:         end
1653:         if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1654:           suffixes << m[1] << m[2]
1655:           implicit = [[m[1], m[2]], [m.post_match]]
1656:           next
1657:         elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1658:           line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1659:         end
1660:         depout << line
1661:       end
1662:       while line = dfile.gets()
1663:         line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1664:         line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
1665:         if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1666:           (cont ||= []) << line
1667:           next
1668:         elsif cont
1669:           line = (cont << line).join
1670:           cont = nil
1671:         end
1672:         ruleconv.call(line)
1673:       end
1674:       if cont
1675:         ruleconv.call(cont.join)
1676:       elsif implicit
1677:         impconv.call
1678:       end
1679:     end
1680:     unless suffixes.empty?
1681:       mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
1682:     end
1683:     mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
1684:     mfile.print depout
1685:   else
1686:     headers = %w[ruby.h defines.h]
1687:     if RULE_SUBST
1688:       headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
1689:     end
1690:     headers << $config_h if $config_h
1691:     headers << "$(RUBY_EXTCONF_H)" if $extconf_h
1692:     mfile.print "$(OBJS): ", headers.join(' '), "\n"
1693:   end
1694: 
1695:   $makefile_created = true
1696: ensure
1697:   mfile.close if mfile
1698: end

Sets a target name that the user can then use to configure various ‘with’ options with on the command line by using that name. For example, if the target is set to "foo", then the user could use the —with-foo-dir command line option.

You may pass along additional ‘include’ or ‘lib’ defaults via the idefault and ldefault parameters, respectively.

Note that dir_config only adds to the list of places to search for libraries and include files. It does not link the libraries into your application.

[Source]

      # File lib/mkmf.rb, line 1165
1165: def dir_config(target, idefault=nil, ldefault=nil)
1166:   if dir = with_config(target + "-dir", (idefault unless ldefault))
1167:     defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
1168:     idefault = ldefault = nil
1169:   end
1170: 
1171:   idir = with_config(target + "-include", idefault)
1172:   $arg_config.last[1] ||= "${#{target}-dir}/include"
1173:   ldir = with_config(target + "-lib", ldefault)
1174:   $arg_config.last[1] ||= "${#{target}-dir}/lib"
1175: 
1176:   idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
1177:   if defaults
1178:     idirs.concat(defaults.collect {|dir| dir + "/include"})
1179:     idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1180:   end
1181:   unless idirs.empty?
1182:     idirs.collect! {|dir| "-I" + dir}
1183:     idirs -= Shellwords.shellwords($CPPFLAGS)
1184:     unless idirs.empty?
1185:       $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1186:     end
1187:   end
1188: 
1189:   ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
1190:   if defaults
1191:     ldirs.concat(defaults.collect {|dir| dir + "/lib"})
1192:     ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1193:   end
1194:   $LIBPATH = ldirs | $LIBPATH
1195: 
1196:   [idir, ldir]
1197: end

Tests for the presence of an —enable-config or —disable-config option. Returns true if the enable option is given, false if the disable option is given, and the default value otherwise.

This can be useful for adding custom definitions, such as debug information.

Example:

   if enable_config("debug")
      $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
   end

[Source]

      # File lib/mkmf.rb, line 1094
1094: def enable_config(config, *defaults)
1095:   if arg_config("--enable-"+config)
1096:     true
1097:   elsif arg_config("--disable-"+config)
1098:     false
1099:   elsif block_given?
1100:     yield(config, *defaults)
1101:   else
1102:     return *defaults
1103:   end
1104: end

Searches for the executable bin on path. The default path is your PATH environment variable. If that isn‘t defined, it will resort to searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.

If found, it will return the full path, including the executable name, of where it was found.

Note that this method does not actually affect the generated Makefile.

[Source]

      # File lib/mkmf.rb, line 1033
1033: def  find_executablefind_executable(bin, path = nil)
1034:   checking_for checking_message(bin, path) do
1035:     find_executable0(bin, path)
1036:   end
1037: end

Instructs mkmf to search for the given header in any of the paths provided, and returns whether or not it was found in those paths.

If the header is found then the path it was found on is added to the list of included directories that are sent to the compiler (via the -I switch).

[Source]

     # File lib/mkmf.rb, line 768
768: def find_header(header, *paths)
769:   message = checking_message(header, paths)
770:   header = cpp_include(header)
771:   checking_for message do
772:     if try_cpp(header)
773:       true
774:     else
775:       found = false
776:       paths.each do |dir|
777:         opt = "-I#{dir}".quote
778:         if try_cpp(header, opt)
779:           $INCFLAGS << " " << opt
780:           found = true
781:           break
782:         end
783:       end
784:       found
785:     end
786:   end
787: end

Returns whether or not the entry point func can be found within the library lib in one of the paths specified, where paths is an array of strings. If func is nil , then the main() function is used as the entry point.

If lib is found, then the path it was found on is added to the list of library paths searched and linked against.

[Source]

     # File lib/mkmf.rb, line 684
684: def find_library(lib, func, *paths, &b)
685:   func = "main" if !func or func.empty?
686:   lib = with_config(lib+'lib', lib)
687:   paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
688:   checking_for "#{func}() in #{LIBARG%lib}" do
689:     libpath = $LIBPATH
690:     libs = append_library($libs, lib)
691:     begin
692:       until r = try_func(func, libs, &b) or paths.empty?
693:         $LIBPATH = libpath | [paths.shift]
694:       end
695:       if r
696:         $libs = libs
697:         libpath = nil
698:       end
699:     ensure
700:       $LIBPATH = libpath if libpath
701:     end
702:     r
703:   end
704: end

Returns where the static type type is defined.

You may also pass additional flags to opt which are then passed along to the compiler.

See also have_type.

[Source]

     # File lib/mkmf.rb, line 860
860: def find_type(type, opt, *headers, &b)
861:   opt ||= ""
862:   fmt = "not found"
863:   def fmt.%(x)
864:     x ? x.respond_to?(:join) ? x.join(",") : x : self
865:   end
866:   checking_for checking_message(type, nil, opt), fmt do
867:     headers.find do |h|
868:       try_type(type, h, opt, &b)
869:     end
870:   end
871: end

Returns whether or not the constant const is defined. You may optionally pass the type of const as [const, type], like as:

  have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")

You may also pass additional headers to check against in addition to the common header files, and additional flags to opt which are then passed along to the compiler.

If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with ‘HAVE_CONST_’.

For example, if have_const(‘foo’) returned true, then the HAVE_CONST_FOO preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 906
906: def have_const(const, headers = nil, opt = "", &b)
907:   checking_for checking_message([*const].compact.join(' '), headers, opt) do
908:     try_const(const, headers, opt, &b)
909:   end
910: end

Returns whether or not the function func can be found in the common header files, or within any headers that you provide. If found, a macro is passed as a preprocessor constant to the compiler using the function name, in uppercase, prepended with ‘HAVE_’.

For example, if have_func(‘foo’) returned true, then the HAVE_FOO preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 714
714: def have_func(func, headers = nil, &b)
715:   checking_for checking_message("#{func}()", headers) do
716:     if try_func(func, $libs, headers, &b)
717:       $defs.push(format("-DHAVE_%s", func.tr_cpp))
718:       true
719:     else
720:       false
721:     end
722:   end
723: end

Returns whether or not the given header file can be found on your system. If found, a macro is passed as a preprocessor constant to the compiler using the header file name, in uppercase, prepended with ‘HAVE_’.

For example, if have_header(‘foo.h’) returned true, then the HAVE_FOO_H preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 751
751: def have_header(header, &b)
752:   checking_for header do
753:     if try_cpp(cpp_include(header), &b)
754:       $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
755:       true
756:     else
757:       false
758:     end
759:   end
760: end

Returns whether or not the given entry point func can be found within lib. If func is nil, the ‘main()’ entry point is used by default. If found, it adds the library to list of libraries to be used when linking your extension.

If headers are provided, it will include those header files as the header files it looks in when searching for func.

The real name of the library to be linked can be altered by ’—with-FOOlib’ configuration option.

[Source]

     # File lib/mkmf.rb, line 659
659: def have_library(lib, func = nil, headers = nil, &b)
660:   func = "main" if !func or func.empty?
661:   lib = with_config(lib+'lib', lib)
662:   checking_for checking_message("#{func}()", LIBARG%lib) do
663:     if COMMON_LIBS.include?(lib)
664:       true
665:     else
666:       libs = append_library($libs, lib)
667:       if try_func(func, libs, headers, &b)
668:         $libs = libs
669:         true
670:       else
671:         false
672:       end
673:     end
674:   end
675: end

Returns whether or not macro is defined either in the common header files or within any headers you provide.

Any options you pass to opt are passed along to the compiler.

[Source]

     # File lib/mkmf.rb, line 642
642: def have_macro(macro, headers = nil, opt = "", &b)
643:   checking_for checking_message(macro, headers, opt) do
644:     macro_defined?(macro, cpp_include(headers), opt, &b)
645:   end
646: end

Returns whether or not the struct of type type contains member. If it does not, or the struct type can‘t be found, then false is returned. You may optionally specify additional headers in which to look for the struct (in addition to the common header files).

If found, a macro is passed as a preprocessor constant to the compiler using the member name, in uppercase, prepended with ‘HAVE_ST_’.

For example, if have_struct_member(‘struct foo’, ‘bar’) returned true, then the HAVE_ST_BAR preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 800
800: def have_struct_member(type, member, headers = nil, &b)
801:   checking_for checking_message("#{type}.#{member}", headers) do
802:     if try_compile("\#{COMMON_HEADERS}\n\#{cpp_include(headers)}\n/*top*/\nint main() { return 0; }\nint s = (char *)&((\#{type}*)0)->\#{member} - (char *)0;\n", &b)
803:       $defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
804:       true
805:     else
806:       false
807:     end
808:   end
809: end

Returns whether or not the static type type is defined. You may optionally pass additional headers to check against in addition to the common header files.

You may also pass additional flags to opt which are then passed along to the compiler.

If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with ‘HAVE_TYPE_’.

For example, if have_type(‘foo’) returned true, then the HAVE_TYPE_FOO preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 847
847: def have_type(type, headers = nil, opt = "", &b)
848:   checking_for checking_message(type, headers, opt) do
849:     try_type(type, headers, opt, &b)
850:   end
851: end

Returns whether or not the variable var can be found in the common header files, or within any headers that you provide. If found, a macro is passed as a preprocessor constant to the compiler using the variable name, in uppercase, prepended with ‘HAVE_’.

For example, if have_var(‘foo’) returned true, then the HAVE_FOO preprocessor macro would be passed to the compiler.

[Source]

     # File lib/mkmf.rb, line 733
733: def have_var(var, headers = nil, &b)
734:   checking_for checking_message(var, headers) do
735:     if try_var(var, headers, &b)
736:       $defs.push(format("-DHAVE_%s", var.tr_cpp))
737:       true
738:     else
739:       false
740:     end
741:   end
742: end

[Source]

     # File lib/mkmf.rb, line 873
873: def  try_consttry_const(const, headers = nil, opt = "", &b)
874:   const, type = *const
875:   if try_compile("\#{COMMON_HEADERS}\n\#{cpp_include(headers)}\n/*top*/\ntypedef \#{type || 'int'} conftest_type;\nconftest_type conftestval = \#{type ? '' : '(int)'}\#{const};\n", opt, &b)
876:     $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
877:     true
878:   else
879:     false
880:   end
881: end

[Source]

     # File lib/mkmf.rb, line 818
818: def try_type(type, headers = nil, opt = "", &b)
819:   if try_compile("\#{COMMON_HEADERS}\n\#{cpp_include(headers)}\n/*top*/\ntypedef \#{type} conftest_type;\nint conftestval[sizeof(conftest_type)?1:-1];\n", opt, &b)
820:     $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
821:     true
822:   else
823:     false
824:   end
825: end

Tests for the presence of a —with-config or —without-config option. Returns true if the with option is given, false if the without option is given, and the default value otherwise.

This can be useful for adding custom definitions, such as debug information.

Example:

   if with_config("debug")
      $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
   end

[Source]

      # File lib/mkmf.rb, line 1061
1061: def with_config(config, *defaults)
1062:   config = config.sub(/^--with[-_]/, '')
1063:   val = arg_config("--with-"+config) do
1064:     if arg_config("--without-"+config)
1065:       false
1066:     elsif block_given?
1067:       yield(config, *defaults)
1068:     else
1069:       break *defaults
1070:     end
1071:   end
1072:   case val
1073:   when "yes"
1074:     true
1075:   when "no"
1076:     false
1077:   else
1078:     val
1079:   end
1080: end

[Validate]