| Path: | lib/mkmf.rb |
| Last Update: | Tue Nov 28 02:24:36 +0000 2006 |
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] << CXX_EXT |
| INSTALL_DIRS | = | [ [dir_re('commondir'), "$(RUBYCOMMONDIR)"], [dir_re("sitedir"), "$(RUBYCOMMONDIR)"], [dir_re('rubylibdir'), "$(RUBYLIBDIR)"], [dir_re('archdir'), "$(RUBYARCHDIR)"], [dir_re('sitelibdir'), "$(RUBYLIBDIR)"], [dir_re('sitearchdir'), "$(RUBYARCHDIR)"] |
| OUTFLAG | = | CONFIG['OUTFLAG'] |
| CPPOUTFILE | = | CONFIG['CPPOUTFILE'] |
| CONFTEST_C | = | "conftest.c" |
| FailedMessage | = | <<MESSAGE Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: MESSAGE |
| EXPORT_PREFIX | = | config_string('EXPORT_PREFIX') {|s| s.strip} |
| COMMON_HEADERS | = | (hdr.join("\n") unless hdr.empty?) |
| 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 |
# File lib/mkmf.rb, line 542
542: def append_library(libs, lib)
543: format(LIBARG, lib) + " " + libs
544: end
# File lib/mkmf.rb, line 894
894: def arg_config(config, *defaults, &block)
895: $arg_config << [config, *defaults]
896: defaults << nil if !block and defaults.empty?
897: $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
898: end
# File lib/mkmf.rb, line 287
287: def cc_command(opt="")
288: Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
289: CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote))
290: end
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 797
797: def check_sizeof(type, headers = nil, &b)
798: expr = "sizeof(#{type})"
799: fmt = "%d"
800: def fmt.%(x)
801: x ? super : "failed"
802: end
803: checking_for("size of #{type}", fmt) do
804: if size = try_constant(expr, headers, &b)
805: $defs.push(format("-DSIZEOF_%s=%d", type.upcase.tr_s("^A-Z0-9_", "_"), size))
806: size
807: end
808: end
809: end
# File lib/mkmf.rb, line 553
553: def checking_for(m, fmt = nil)
554: f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
555: m = "checking #{'for ' if /\Acheck/ !~ f}#{m}... "
556: message "%s", m
557: a = r = nil
558: Logging::postpone do
559: r = yield
560: a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
561: "#{f}#{m}-------------------- #{a}\n"
562: end
563: message(a)
564: Logging::message "--------------------\n\n"
565: r
566: end
# File lib/mkmf.rb, line 69
69: def config_string(key, config = CONFIG)
70: s = config[key] and !s.empty? and block_given? ? yield(s) : s
71: end
# File lib/mkmf.rb, line 1041
1041: def configuration(srcdir)
1042: mk = []
1043: vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
1044: if !CROSS_COMPILING
1045: case CONFIG['build_os']
1046: when 'cygwin'
1047: if CONFIG['target_os'] != 'cygwin'
1048: vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
1049: end
1050: when 'msdosdjgpp', 'mingw32'
1051: CONFIG['PATH_SEPARATOR'] = ';'
1052: end
1053: end
1054: mk << %{
1055: SHELL = /bin/sh
1056:
1057: #### Start of system configuration section. ####
1058:
1059: srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {CONFIG[$1||$2]}.quote}
1060: topdir = #{($extmk ? CONFIG["topdir"] : $topdir).quote}
1061: hdrdir = #{$extmk ? CONFIG["hdrdir"].quote : '$(topdir)'}
1062: VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
1063: }
1064: if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
1065: mk << "\nDESTDIR = #{destdir}\n"
1066: end
1067: CONFIG.each do |key, var|
1068: next unless /prefix$/ =~ key
1069: mk << "#{key} = #{with_destdir(var)}\n"
1070: end
1071: CONFIG.each do |key, var|
1072: next if /^abs_/ =~ key
1073: next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
1074: mk << "#{key} = #{with_destdir(var)}\n"
1075: end
1076: if !$extmk and !$configure_args.has_key?('--ruby') and
1077: sep = config_string('BUILD_FILE_SEPARATOR')
1078: sep = ":/=#{sep}"
1079: else
1080: sep = ""
1081: end
1082: extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" "
1083: mk << %{
1084: CC = #{CONFIG['CC']}
1085: LIBRUBY = #{CONFIG['LIBRUBY']}
1086: LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
1087: LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
1088: LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
1089:
1090: RUBY_EXTCONF_H = #{$extconf_h}
1091: CFLAGS = #{CONFIG['CCDLFLAGS'] unless $static} #$CFLAGS #$ARCH_FLAG
1092: INCFLAGS = -I. #$INCFLAGS
1093: CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
1094: CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
1095: DLDFLAGS = #$LDFLAGS #$DLDFLAGS #$ARCH_FLAG
1096: LDSHARED = #{CONFIG['LDSHARED']}
1097: AR = #{CONFIG['AR']}
1098: EXEEXT = #{CONFIG['EXEEXT']}
1099:
1100: RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
1101: RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
1102: arch = #{CONFIG['arch']}
1103: sitearch = #{CONFIG['sitearch']}
1104: vendorarch = #{CONFIG['vendorarch']}
1105: ruby_version = #{Config::CONFIG['ruby_version']}
1106: ruby = #{$ruby}
1107: RUBY = $(ruby#{sep})
1108: RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
1109: MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
1110: INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
1111: INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
1112: INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
1113: COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
1114:
1115: #### End of system configuration section. ####
1116:
1117: preload = #{$preload.join(" ") if $preload}
1118: }
1119: if $nmake == ?b
1120: mk.each do |x|
1121: x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
1122: "!ifndef " + $1 + "\n" +
1123: $& +
1124: "!endif\n"
1125: end
1126: end
1127: end
1128: mk
1129: end
# File lib/mkmf.rb, line 292
292: def cpp_command(outfile, opt="")
293: Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
294: CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote))
295: end
# File lib/mkmf.rb, line 325
325: def cpp_include(header)
326: if header
327: header = [header] unless header.kind_of? Array
328: header.map {|h| "#include <#{h}>\n"}.join
329: else
330: ""
331: end
332: end
# File lib/mkmf.rb, line 933
933: def create_header(header = "extconf.h")
934: message "creating %s\n", header
935: sym = header.tr("a-z./\055", "A-Z___")
936: hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
937: for line in $defs
938: case line
939: when /^-D([^=]+)(?:=(.*))?/
940: hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
941: when /^-U(.*)/
942: hdr << "#undef #$1\n"
943: end
944: end
945: hdr << "#endif\n"
946: hdr = hdr.join
947: unless (IO.read(header) == hdr rescue false)
948: open(header, "w") do |hfile|
949: hfile.write(hdr)
950: end
951: end
952: $extconf_h = header
953: 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’".
# File lib/mkmf.rb, line 1159
1159: def create_makefile(target, srcprefix = nil)
1160: $target = target
1161: libpath = $LIBPATH
1162: message "creating Makefile\n"
1163: rm_f "conftest*"
1164: if CONFIG["DLEXT"] == $OBJEXT
1165: for lib in libs = $libs.split
1166: lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
1167: end
1168: $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
1169: end
1170:
1171: if target.include?('/')
1172: target_prefix, target = File.split(target)
1173: target_prefix[0,0] = '/'
1174: else
1175: target_prefix = ""
1176: end
1177:
1178: srcprefix ||= '$(srcdir)'
1179: Config::expand(srcdir = srcprefix.dup)
1180:
1181: if not $objs
1182: $objs = []
1183: srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1184: for f in srcs
1185: obj = File.basename(f, ".*") << ".o"
1186: $objs.push(obj) unless $objs.index(obj)
1187: end
1188: elsif !(srcs = $srcs)
1189: srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
1190: end
1191: for i in $objs
1192: i.sub!(/\.o\z/, ".#{$OBJEXT}")
1193: end
1194: $objs = $objs.join(" ")
1195:
1196: target = nil if $objs == ""
1197:
1198: if target and EXPORT_PREFIX
1199: if File.exist?(File.join(srcdir, target + '.def'))
1200: deffile = "$(srcdir)/$(TARGET).def"
1201: unless EXPORT_PREFIX.empty?
1202: makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
1203: end
1204: else
1205: makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
1206: end
1207: if makedef
1208: $distcleanfiles << '$(DEFFILE)'
1209: origdef = deffile
1210: deffile = "$(TARGET)-$(arch).def"
1211: end
1212: end
1213:
1214: libpath = libpathflag(libpath)
1215:
1216: dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1217: staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1218: mfile = open("Makefile", "wb")
1219: mfile.print configuration(srcprefix)
1220: mfile.print %{
1221: libpath = #{$LIBPATH.join(" ")}
1222: LIBPATH = #{libpath}
1223: DEFFILE = #{deffile}
1224:
1225: CLEANFILES = #{$cleanfiles.join(' ')}
1226: DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1227:
1228: extout = #{$extout}
1229: extout_prefix = #{$extout_prefix}
1230: target_prefix = #{target_prefix}
1231: LOCAL_LIBS = #{$LOCAL_LIBS}
1232: LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1233: SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1234: OBJS = #{$objs}
1235: TARGET = #{target}
1236: DLLIB = #{dllib}
1237: EXTSTATIC = #{$static || ""}
1238: STATIC_LIB = #{staticlib unless $static.nil?}
1239:
1240: }
1241: install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
1242: n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
1243: mfile.print %{
1244: TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
1245: CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
1246: CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
1247:
1248: all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1249: static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
1250: }
1251: mfile.print CLEANINGS
1252: dirs = []
1253: mfile.print "install: install-so install-rb\n\n"
1254: sodir = (dir = "$(RUBYARCHDIR)").dup
1255: mfile.print("install-so: #{dir}\n")
1256: if target
1257: f = "$(DLLIB)"
1258: dest = "#{dir}/#{f}"
1259: mfile.print "install-so: #{dest}\n"
1260: unless $extout
1261: mfile.print "#{dest}: #{f}\n"
1262: if (sep = config_string('BUILD_FILE_SEPARATOR'))
1263: f.gsub!("/", sep)
1264: dir.gsub!("/", sep)
1265: sep = ":/="+sep
1266: f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1267: f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1268: dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1269: dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1270: end
1271: mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
1272: end
1273: end
1274: mfile.print("install-rb: pre-install-rb install-rb-default\n")
1275: mfile.print("install-rb-default: pre-install-rb-default\n")
1276: mfile.print("pre-install-rb: Makefile\n")
1277: mfile.print("pre-install-rb-default: Makefile\n")
1278: for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
1279: files = install_files(mfile, i, nil, srcprefix) or next
1280: for dir, *files in files
1281: unless dirs.include?(dir)
1282: dirs << dir
1283: mfile.print "pre-install-rb#{sfx}: #{dir}\n"
1284: end
1285: files.each do |f|
1286: dest = "#{dir}/#{File.basename(f)}"
1287: mfile.print("install-rb#{sfx}: #{dest}\n")
1288: mfile.print("#{dest}: #{f}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
1289: sep = config_string('BUILD_FILE_SEPARATOR')
1290: if sep
1291: f = f.gsub("/", sep)
1292: sep = ":/="+sep
1293: f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
1294: f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
1295: else
1296: sep = ""
1297: end
1298: mfile.print("#{f} $(@D#{sep})\n")
1299: end
1300: end
1301: end
1302: dirs.unshift(sodir) if target and !dirs.include?(sodir)
1303: dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
1304:
1305: mfile.print "\nsite-install: site-install-so site-install-rb\nsite-install-so: install-so\nsite-install-rb: install-rb\n\n"
1306:
1307: return unless target
1308:
1309: mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
1310: mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
1311: mfile.print "\n"
1312:
1313: CXX_EXT.each do |ext|
1314: COMPILE_RULES.each do |rule|
1315: mfile.printf(rule, ext, $OBJEXT)
1316: mfile.printf("\n\t%s\n\n", COMPILE_CXX)
1317: end
1318: end
1319: %w[c].each do |ext|
1320: COMPILE_RULES.each do |rule|
1321: mfile.printf(rule, ext, $OBJEXT)
1322: mfile.printf("\n\t%s\n\n", COMPILE_C)
1323: end
1324: end
1325:
1326: mfile.print "$(RUBYARCHDIR)/" if $extout
1327: mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n"
1328: mfile.print "\t@-$(RM) $@\n"
1329: mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
1330: link_so = LINK_SO.gsub(/^/, "\t")
1331: mfile.print link_so, "\n\n"
1332: unless $static.nil?
1333: mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
1334: mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
1335: config_string('RANLIB') do |ranlib|
1336: mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
1337: end
1338: end
1339: mfile.print "\n\n"
1340: if makedef
1341: mfile.print "$(DEFFILE): #{origdef}\n"
1342: mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
1343: end
1344:
1345: depend = File.join(srcdir, "depend")
1346: if File.exist?(depend)
1347: suffixes = []
1348: depout = []
1349: open(depend, "r") do |dfile|
1350: mfile.printf "###\n"
1351: cont = implicit = nil
1352: impconv = proc do
1353: COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
1354: implicit = nil
1355: end
1356: ruleconv = proc do |line|
1357: if implicit
1358: if /\A\t/ =~ line
1359: implicit[1] << line
1360: next
1361: else
1362: impconv[]
1363: end
1364: end
1365: if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1366: suffixes << m[1] << m[2]
1367: implicit = [[m[1], m[2]], [m.post_match]]
1368: next
1369: elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1370: line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1371: end
1372: depout << line
1373: end
1374: while line = dfile.gets()
1375: line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1376: line.gsub!(/\$\(hdrdir\)\/config.h/, $config_h) if $config_h
1377: if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1378: (cont ||= []) << line
1379: next
1380: elsif cont
1381: line = (cont << line).join
1382: cont = nil
1383: end
1384: ruleconv.call(line)
1385: end
1386: if cont
1387: ruleconv.call(cont.join)
1388: elsif implicit
1389: impconv.call
1390: end
1391: end
1392: unless suffixes.empty?
1393: mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
1394: end
1395: mfile.print depout
1396: else
1397: headers = %w[ruby.h defines.h]
1398: if RULE_SUBST
1399: headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
1400: end
1401: headers << $config_h if $config_h
1402: headers << "$(RUBY_EXTCONF_H)" if $extconf_h
1403: mfile.print "$(OBJS): ", headers.join(' '), "\n"
1404: end
1405:
1406: $makefile_created = true
1407: ensure
1408: mfile.close if mfile
1409: end
# File lib/mkmf.rb, line 257
257: def create_tmpsrc(src)
258: src = yield(src) if block_given?
259: src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n")
260: open(CONFTEST_C, "wb") do |cfile|
261: cfile.print src
262: end
263: src
264: 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 966
966: def dir_config(target, idefault=nil, ldefault=nil)
967: if dir = with_config(target + "-dir", (idefault unless ldefault))
968: defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
969: idefault = ldefault = nil
970: end
971:
972: idir = with_config(target + "-include", idefault)
973: $arg_config.last[1] ||= "${#{target}-dir}/include"
974: ldir = with_config(target + "-lib", ldefault)
975: $arg_config.last[1] ||= "${#{target}-dir}/lib"
976:
977: idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
978: if defaults
979: idirs.concat(defaults.collect {|dir| dir + "/include"})
980: idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
981: end
982: unless idirs.empty?
983: idirs.collect! {|dir| "-I" + dir}
984: idirs -= Shellwords.shellwords($CPPFLAGS)
985: unless idirs.empty?
986: $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
987: end
988: end
989:
990: ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
991: if defaults
992: ldirs.concat(defaults.collect {|dir| dir + "/lib"})
993: ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
994: end
995: $LIBPATH = ldirs | $LIBPATH
996:
997: [idir, ldir]
998: end
# File lib/mkmf.rb, line 73
73: def dir_re(dir)
74: Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$\(target_prefix\)|\{target_prefix\})?')
75: end
# File lib/mkmf.rb, line 1131
1131: def dummy_makefile(srcdir)
1132: configuration(srcdir) << "CLEANFILES = \#{$cleanfiles.join(' ')}\nDISTCLEANFILES = \#{$distcleanfiles.join(' ')}\n\nall install static install-so install-rb: Makefile\n\n" << CLEANINGS
1133: end
# File lib/mkmf.rb, line 453
453: def egrep_cpp(pat, src, opt = "", &b)
454: src = create_tmpsrc(src, &b)
455: xpopen(cpp_command('', opt)) do |f|
456: if Regexp === pat
457: puts(" ruby -ne 'print if #{pat.inspect}'")
458: f.grep(pat) {|l|
459: puts "#{f.lineno}: #{l}"
460: return true
461: }
462: false
463: else
464: puts(" egrep '#{pat}'")
465: begin
466: stdin = $stdin.dup
467: $stdin.reopen(f)
468: system("egrep", pat)
469: ensure
470: $stdin.reopen(stdin)
471: end
472: end
473: end
474: ensure
475: rm_f "conftest*"
476: log_src(src)
477: end
# File lib/mkmf.rb, line 921
921: def enable_config(config, *defaults)
922: if arg_config("--enable-"+config)
923: true
924: elsif arg_config("--disable-"+config)
925: false
926: elsif block_given?
927: yield(config, *defaults)
928: else
929: return *defaults
930: end
931: end
# File lib/mkmf.rb, line 888
888: def find_executable(bin, path = nil)
889: checking_for bin do
890: find_executable0(bin, path)
891: end
892: end
# File lib/mkmf.rb, line 868
868: def find_executable0find_executable0(bin, path = nil)
869: ext = config_string('EXEEXT')
870: if File.expand_path(bin) == bin
871: return bin if File.executable?(bin)
872: return file if ext and File.executable?(file = bin + ext)
873: return nil
874: end
875: if path ||= ENV['PATH']
876: path = path.split(File::PATH_SEPARATOR)
877: else
878: path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
879: end
880: file = nil
881: path.each do |dir|
882: return file if File.executable?(file = File.join(dir, bin))
883: return file if ext and File.executable?(file << ext)
884: end
885: nil
886: 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 701
701: def find_header(header, *paths)
702: header = cpp_include(header)
703: checking_for header do
704: if try_cpp(header)
705: true
706: else
707: found = false
708: paths.each do |dir|
709: opt = "-I#{dir}".quote
710: if try_cpp(header, opt)
711: $INCFLAGS << " " << opt
712: found = true
713: break
714: end
715: end
716: found
717: end
718: end
719: 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 617
617: def find_library(lib, func, *paths, &b)
618: func = "main" if !func or func.empty?
619: lib = with_config(lib+'lib', lib)
620: paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
621: checking_for "#{func}() in #{LIBARG%lib}" do
622: libpath = $LIBPATH
623: libs = append_library($libs, lib)
624: begin
625: until r = try_func(func, libs, &b) or paths.empty?
626: $LIBPATH = libpath | [paths.shift]
627: end
628: if r
629: $libs = libs
630: libpath = nil
631: end
632: ensure
633: $LIBPATH = libpath if libpath
634: end
635: r
636: end
637: end
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 647
647: def have_func(func, headers = nil, &b)
648: checking_for "#{func}()" do
649: if try_func(func, $libs, headers, &b)
650: $defs.push(format("-DHAVE_%s", func.upcase))
651: true
652: else
653: false
654: end
655: end
656: 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 684
684: def have_header(header, &b)
685: checking_for header do
686: if try_cpp(cpp_include(header), &b)
687: $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
688: true
689: else
690: false
691: end
692: end
693: 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.
Real name of the library to be linked can be altered by ’—with-FOOlib’ configuration option.
# File lib/mkmf.rb, line 592
592: def have_library(lib, func = nil, headers = nil, &b)
593: func = "main" if !func or func.empty?
594: lib = with_config(lib+'lib', lib)
595: checking_for "#{func}() in #{LIBARG%lib}" do
596: if COMMON_LIBS.include?(lib)
597: true
598: else
599: libs = append_library($libs, lib)
600: if try_func(func, libs, headers, &b)
601: $libs = libs
602: true
603: else
604: false
605: end
606: end
607: end
608: 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 573
573: def have_macro(macro, headers = nil, opt = "", &b)
574: m = "#{macro}"
575: m << " in #{headers.inspect}" if headers
576: checking_for m do
577: macro_defined?(macro, cpp_include(headers), opt, &b)
578: end
579: 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(‘foo’, ‘bar’) returned true, then the HAVE_ST_BAR preprocessor macro would be passed to the compiler.
# File lib/mkmf.rb, line 732
732: def have_struct_member(type, member, headers = nil, &b)
733: checking_for "#{type}.#{member}" do
734: 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)
735: $defs.push(format("-DHAVE_ST_%s", member.upcase))
736: true
737: else
738: false
739: end
740: end
741: 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 763
763: def have_type(type, headers = nil, opt = "", &b)
764: checking_for type do
765: headers = cpp_include(headers)
766: if try_compile("\#{COMMON_HEADERS}\n\#{headers}\n/*top*/\nstatic \#{type} t;\n", opt, &b) or (/\A\w+\z/n =~ type && try_compile("\#{COMMON_HEADERS}\n\#{headers}\n/*top*/\nstatic \#{type} *t;\n", opt, &b))
767: $defs.push(format("-DHAVE_TYPE_%s", type.strip.upcase.tr_s("^A-Z0-9_", "_")))
768: true
769: else
770: false
771: end
772: end
773: 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 666
666: def have_var(var, headers = nil, &b)
667: checking_for "#{var}" do
668: if try_var(var, headers, &b)
669: $defs.push(format("-DHAVE_%s", var.upcase))
670: true
671: else
672: false
673: end
674: end
675: end
# File lib/mkmf.rb, line 1418
1418: def init_mkmf(config = CONFIG)
1419: $makefile_created = false
1420: $arg_config = []
1421: $enable_shared = config['ENABLE_SHARED'] == 'yes'
1422: $defs = []
1423: $extconf_h = nil
1424: $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
1425: $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
1426: $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
1427: $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
1428: $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
1429: $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
1430: $LIBEXT = config['LIBEXT'].dup
1431: $OBJEXT = config["OBJEXT"].dup
1432: $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
1433: $LIBRUBYARG = ""
1434: $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
1435: $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
1436: $LIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"]
1437: $INSTALLFILES = nil
1438:
1439: $objs = nil
1440: $srcs = nil
1441: $libs = ""
1442: if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup)
1443: $LIBRUBYARG = config['LIBRUBYARG']
1444: end
1445:
1446: $LOCAL_LIBS = ""
1447:
1448: $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
1449: $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
1450:
1451: $extout ||= nil
1452: $extout_prefix ||= nil
1453:
1454: $arg_config.clear
1455: dir_config("opt")
1456: end
# File lib/mkmf.rb, line 86
86: def install_dirs(target_prefix = nil)
87: if $extout
88: dirs = [
89: ['RUBYCOMMONDIR', '$(extout)'],
90: ['RUBYLIBDIR', '$(extout)$(target_prefix)'],
91: ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
92: ['extout', "#$extout"],
93: ['extout_prefix', "#$extout_prefix"],
94: ]
95: elsif $extmk
96: dirs = [
97: ['RUBYCOMMONDIR', '$(rubylibdir)'],
98: ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
99: ['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
100: ]
101: else
102: dirs = [
103: ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
104: ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
105: ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
106: ]
107: end
108: dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
109: dirs
110: end
# File lib/mkmf.rb, line 501
501: def install_files(mfile, ifiles, map = nil, srcprefix = nil)
502: ifiles or return
503: srcprefix ||= '$(srcdir)'
504: Config::expand(srcdir = srcprefix.dup)
505: dirs = []
506: path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
507: ifiles.each do |files, dir, prefix|
508: dir = map_dir(dir, map)
509: prefix = %r|\A#{Regexp.quote(prefix)}/?| if prefix
510: if /\A\.\// =~ files
511: # install files which are in current working directory.
512: files = files[2..-1]
513: len = nil
514: else
515: # install files which are under the $(srcdir).
516: files = File.join(srcdir, files)
517: len = srcdir.size
518: end
519: f = nil
520: Dir.glob(files) do |f|
521: f[0..len] = "" if len
522: d = File.dirname(f)
523: d.sub!(prefix, "") if prefix
524: d = (d.empty? || d == ".") ? dir : File.join(dir, d)
525: f = File.join(srcprefix, f) if len
526: path[d] << f
527: end
528: unless len or f
529: d = File.dirname(files)
530: d.sub!(prefix, "") if prefix
531: d = (d.empty? || d == ".") ? dir : File.join(dir, d)
532: path[d] << files
533: end
534: end
535: dirs
536: end
# File lib/mkmf.rb, line 538
538: def install_rb(mfile, dest, srcdir = nil)
539: install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
540: end
# File lib/mkmf.rb, line 297
297: def libpathflag(libpath=$LIBPATH)
298: libpath.map{|x|
299: (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x.quote
300: }.join
301: end
# File lib/mkmf.rb, line 273
273: def link_command(ldflags, opt="", libpath=$LIBPATH)
274: Config::expand(TRY_LINK.dup,
275: CONFIG.merge('hdrdir' => $hdrdir.quote,
276: 'src' => CONFTEST_C,
277: 'INCFLAGS' => $INCFLAGS,
278: 'CPPFLAGS' => $CPPFLAGS,
279: 'CFLAGS' => "#$CFLAGS",
280: 'ARCH_FLAG' => "#$ARCH_FLAG",
281: 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
282: 'LIBPATH' => libpathflag(libpath),
283: 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
284: 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS"))
285: end
# File lib/mkmf.rb, line 241
241: def log_src(src)
242: src = src.split(/^/)
243: fmt = "%#{src.size.to_s.size}d: %s"
244: Logging::message "checked program was:\n/* begin */\n"
245: src.each_with_index {|line, no| Logging::message fmt, no+1, line}
246: Logging::message "/* end */\n\n"
247: end
# File lib/mkmf.rb, line 479
479: def macro_defined?(macro, src, opt = "", &b)
480: src = src.sub(/[^\n]\z/, "\\&\n")
481: try_compile(src + "/*top*/\n#ifndef \#{macro}\n# error\n>>>>>> \#{macro} undefined <<<<<<\n#endif\n", opt, &b)
482: end
# File lib/mkmf.rb, line 112
112: def map_dir(dir, map = nil)
113: map ||= INSTALL_DIRS
114: map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
115: end
# File lib/mkmf.rb, line 155
155: def merge_libs(*libs)
156: libs.inject([]) do |x, y|
157: xy = x & y
158: xn = yn = 0
159: y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
160: y.each_with_index do |v, yi|
161: if xy.include?(v)
162: xi = [x.index(v), xn].max()
163: x[xi, 1] = y[yn..yi]
164: xn, yn = xi + (yi - yn + 1), yi + 1
165: end
166: end
167: x.concat(y[yn..-1] || [])
168: end
169: end
# File lib/mkmf.rb, line 546
546: def message(*s)
547: unless $extmk and not $VERBOSE
548: printf(*s)
549: $stdout.flush
550: end
551: end
# File lib/mkmf.rb, line 1467
1467: def mkmf_failed(path)
1468: unless $makefile_created or File.exist?("Makefile")
1469: opts = $arg_config.collect {|t, n| "\t#{t}#{"=#{n}" if n}\n"}
1470: abort "*** #{path} failed ***\n" + FailedMessage + opts.join
1471: end
1472: end
# File lib/mkmf.rb, line 149
149: def modified?(target, times)
150: (t = File.mtime(target)) rescue return nil
151: Array === times or times = [times]
152: t if times.all? {|n| n <= t}
153: end
# File lib/mkmf.rb, line 1000
1000: def pkg_config(pkg)
1001: if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1002: # iff package specific config command is given
1003: get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1004: elsif ($PKGCONFIG ||=
1005: (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1006: find_executable0(pkgconfig) && pkgconfig) and
1007: system("#{$PKGCONFIG} --exists #{pkg}")
1008: # default to pkg-config command
1009: get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
1010: elsif find_executable0(pkgconfig = "#{pkg}-config")
1011: # default to package specific config command, as a last resort.
1012: get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1013: end
1014: if get
1015: cflags = get['cflags']
1016: ldflags = get['libs']
1017: libs = get['libs-only-l']
1018: ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
1019: $CFLAGS += " " << cflags
1020: $LDFLAGS += " " << ldflags
1021: $libs += " " << libs
1022: Logging::message "package configuration for %s\n", pkg
1023: Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
1024: cflags, ldflags, libs
1025: [cflags, ldflags, libs]
1026: else
1027: Logging::message "package configuration for %s is not found\n", pkg
1028: nil
1029: end
1030: end
# File lib/mkmf.rb, line 145
145: def rm_f(*files)
146: FileUtils.rm_f(Dir[files.join("\0")])
147: end
# File lib/mkmf.rb, line 811
811: def scalar_ptr_type?scalar_ptr_type?(type, member = nil, headers = nil, &b)
812: try_compile("\#{COMMON_HEADERS}\n\#{cpp_include(headers)}\n/*top*/\nvolatile \#{type} conftestval;\nint main() { return 0; }\nint t() {return (int)(1-*(conftestval\#{member ? \".\#{member}\" : \"\"}));}\n", &b) # pointer
813: end
# File lib/mkmf.rb, line 823
823: def scalar_type?(type, member = nil, headers = nil, &b)
824: try_compile("\#{COMMON_HEADERS}\n\#{cpp_include(headers)}\n/*top*/\nvolatile \#{type} conftestval;\nint main() { return 0; }\nint t() {return (int)(1-(conftestval\#{member ? \".\#{member}\" : \"\"}));}\n", &b) # pointer
825: end
# File lib/mkmf.rb, line 313
313: def try_compile(src, opt="", &b)
314: try_do(src, cc_command(opt), &b)
315: ensure
316: rm_f "conftest*"
317: end
# File lib/mkmf.rb, line 369
369: def try_constant(const, headers = nil, opt = "", &b)
370: includes = cpp_include(headers)
371: if CROSS_COMPILING
372: if try_static_assert("#{const} > 0", headers, opt)
373: # positive constant
374: elsif try_static_assert("#{const} < 0", headers, opt)
375: neg = true
376: const = "-(#{const})"
377: elsif try_static_assert("#{const} == 0", headers, opt)
378: return 0
379: else
380: # not a constant
381: return nil
382: end
383: upper = 1
384: lower = 0
385: until try_static_assert("#{const} <= #{upper}", headers, opt)
386: lower = upper
387: upper <<= 1
388: end
389: return nil unless lower
390: while upper > lower + 1
391: mid = (upper + lower) / 2
392: if try_static_assert("#{const} > #{mid}", headers, opt)
393: lower = mid
394: else
395: upper = mid
396: end
397: end
398: upper = -upper if neg
399: return upper
400: else
401: src = %{#{COMMON_HEADERS}
402: #{includes}
403: #include <stdio.h>
404: /*top*/
405: int conftest_const = (int)(#{const});
406: int main() {printf("%d\\n", conftest_const); return 0;}
407: }
408: if try_link0(src, opt, &b)
409: xpopen("./conftest") do |f|
410: return Integer(f.gets)
411: end
412: end
413: end
414: nil
415: end
# File lib/mkmf.rb, line 319
319: def try_cpp(src, opt="", &b)
320: try_do(src, cpp_command(CPPOUTFILE, opt), &b)
321: ensure
322: rm_f "conftest*"
323: end
# File lib/mkmf.rb, line 266
266: def try_do(src, command, &b)
267: src = create_tmpsrc(src, &b)
268: xsystem(command)
269: ensure
270: log_src(src)
271: end
# File lib/mkmf.rb, line 417
417: def try_func(func, libs, headers = nil, &b)
418: headers = cpp_include(headers)
419: try_link("\#{headers}\n/*top*/\nint main() { return 0; }\nint t() { \#{func}(); return 0; }\n", libs, &b) or try_link("\#{COMMON_HEADERS}\n\#{headers}\n/*top*/\nint main() { return 0; }\nint t() { void ((*volatile p)()); p = (void ((*)()))\#{func}; return 0; }\n", libs, &b) or try_link("int \#{func}();\n/*top*/\nint main() { return 0; }\nint t() { \#{func}(); return 0; }\n", libs, &b)
420: end
# File lib/mkmf.rb, line 307
307: def try_link(src, opt="", &b)
308: try_link0(src, opt, &b)
309: ensure
310: rm_f "conftest*", "c0x32*"
311: end
# File lib/mkmf.rb, line 303
303: def try_link0(src, opt="", &b)
304: try_do(src, link_command("", opt), &b)
305: end
# File lib/mkmf.rb, line 491
491: def try_run(src, opt = "", &b)
492: if try_link0(src, opt, &b)
493: xsystem("./conftest")
494: else
495: nil
496: end
497: ensure
498: rm_f "conftest*"
499: end
# File lib/mkmf.rb, line 358
358: def try_static_assert(expr, headers = nil, opt = "", &b)
359: headers = cpp_include(headers)
360: try_compile("\#{COMMON_HEADERS}\n\#{headers}\n/*top*/\nint conftest_const[(\#{expr}) ? 1 : -1];\n", opt, &b)
361: end
# File lib/mkmf.rb, line 441
441: def try_var(var, headers = nil, &b)
442: headers = cpp_include(headers)
443: try_compile("\#{COMMON_HEADERS}\n\#{headers}\n/*top*/\nint main() { return 0; }\nint t() { const volatile void *volatile p; p = (void *)&\#{var}; return 0; }\n", &b)
444: end
# File lib/mkmf.rb, line 835
835: def what_type?(type, member = nil, headers = nil, &b)
836: m = "#{type}"
837: name = type
838: if member
839: m << "." << member
840: name = "(((#{type} *)0)->#{member})"
841: end
842: m << " in #{headers.inspect}" if headers
843: fmt = "seems %s"
844: def fmt.%(x)
845: x ? super : "unknown"
846: end
847: checking_for m, fmt do
848: if scalar_ptr_type?(type, member, headers, &b)
849: if try_static_assert("sizeof(*#{name}) == 1", headers)
850: "string"
851: end
852: elsif scalar_type?(type, member, headers, &b)
853: if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
854: "long long"
855: elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
856: "long"
857: elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
858: "int"
859: elsif try_static_assert("sizeof(#{name}) > 1", headers)
860: "short"
861: else
862: "char"
863: end
864: end
865: end
866: end
# File lib/mkmf.rb, line 342
342: def with_cflags(flags)
343: cflags = $CFLAGS
344: $CFLAGS = flags
345: ret = yield
346: ensure
347: $CFLAGS = cflags unless ret
348: end
# File lib/mkmf.rb, line 900
900: def with_config(config, *defaults)
901: config = config.sub(/^--with[-_]/, '')
902: val = arg_config("--with-"+config) do
903: if arg_config("--without-"+config)
904: false
905: elsif block_given?
906: yield(config, *defaults)
907: else
908: break *defaults
909: end
910: end
911: case val
912: when "yes"
913: true
914: when "no"
915: false
916: else
917: val
918: end
919: end
# File lib/mkmf.rb, line 334
334: def with_cppflags(flags)
335: cppflags = $CPPFLAGS
336: $CPPFLAGS = flags
337: ret = yield
338: ensure
339: $CPPFLAGS = cppflags unless ret
340: end
# File lib/mkmf.rb, line 1032
1032: def with_destdir(dir)
1033: dir = dir.sub($dest_prefix_pattern, '')
1034: /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
1035: end
# File lib/mkmf.rb, line 350
350: def with_ldflags(flags)
351: ldflags = $LDFLAGS
352: $LDFLAGS = flags
353: ret = yield
354: ensure
355: $LDFLAGS = ldflags unless ret
356: end
# File lib/mkmf.rb, line 229
229: def xpopen command, *mode, &block
230: Logging::open do
231: case mode[0]
232: when nil, /^r/
233: puts "#{command} |"
234: else
235: puts "| #{command}"
236: end
237: IO.popen(command, *mode, &block)
238: end
239: end