Path: | lib/mkmf.rb |
Last Update: | Tue Oct 30 10:14:43 +0000 2012 |
module to create Makefile for extension modules invoke like: ruby -r mkmf extconf.rb
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 |
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.
# 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.
# 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.
# 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.
# 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
# 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.
# 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).
# 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.
# 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.
# 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.
# 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.
# 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.
# 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.
# 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.
# 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.
# 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.
# 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.
# 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
# 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
# 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
# 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