BasicObject
# File mkmf.rb, line 533 def append_library(libs, lib) format(LIBARG, lib) + " " + libs end
# File mkmf.rb, line 887 def arg_config(config, *defaults, &block) $arg_config << [config, *defaults] defaults << nil if !block and defaults.empty? $configure_args.fetch(config.tr('_', '-'), *defaults, &block) end
# File mkmf.rb, line 282 def cc_command(opt="") conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote) Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", conf) 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 mkmf.rb, line 793 def check_sizeof(type, headers = nil, &b) expr = "sizeof(#{type})" fmt = "%d" def fmt.%(x) x ? super : "failed" end checking_for checking_message("size of #{type}", headers), fmt do if size = try_constant(expr, headers, &b) $defs.push(format("-DSIZEOF_%s=%d", type.upcase.tr_s("^A-Z0-9_", "_"), size)) size end end end
# File mkmf.rb, line 544 def checking_for(m, fmt = nil) f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... " message "%s", m a = r = nil Logging::postpone do r = yield a = (fmt ? fmt % r : r ? "yes" : "no") << "\n" "#{f}#{m}-------------------- #{a}\n" end message(a) Logging::message "--------------------\n\n" r end
# File mkmf.rb, line 559 def checking_message(target, place = nil, opt = nil) [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)| if noun [[:to_str], [:join, ","], [:to_s]].each do |meth, *args| if noun.respond_to?(meth) break noun = noun.send(meth, *args) end end msg << " #{pre} #{noun}" unless noun.empty? end msg end end
# File mkmf.rb, line 66 def config_string(key, config = CONFIG) s = config[key] and !s.empty? and block_given? ? yield(s) : s end
# File mkmf.rb, line 1057 def configuration(srcdir) mk = [] vpath = %w[$(srcdir) $(topdir) $(hdrdir)] if !CROSS_COMPILING case CONFIG['build_os'] when 'cygwin' if CONFIG['target_os'] != 'cygwin' vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')} end when 'msdosdjgpp' CONFIG['PATH_SEPARATOR'] = ';' end end mk << %{ SHELL = /bin/sh #### Start of system configuration section. #### srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote} topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote} hdrdir = #{$extmk ? mkintpath(CONFIG["hdrdir"]).quote : '$(topdir)'} VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])} } if $extmk mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n" end if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1] mk << "\nDESTDIR = #{destdir}\n" end CONFIG.each do |key, var| next unless /prefix$/ =~ key mk << "#{key} = #{with_destdir(var)}\n" end CONFIG.each do |key, var| next if /^abs_/ =~ key next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1 mk << "#{key} = #{with_destdir(var)}\n" end if !$extmk and !$configure_args.has_key?('--ruby') and sep = config_string('BUILD_FILE_SEPARATOR') sep = ":/=#{sep}" else sep = "" end extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" " mk << %{ CC = #{CONFIG['CC']} LIBRUBY = #{CONFIG['LIBRUBY']} LIBRUBY_A = #{CONFIG['LIBRUBY_A']} LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC RUBY_EXTCONF_H = #{$extconf_h} CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG INCFLAGS = -I. #$INCFLAGS DEFS = #{CONFIG['DEFS']} CPPFLAGS = #{extconf_h}#{$CPPFLAGS} CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']} DLDFLAGS = #$LDFLAGS #$DLDFLAGS #$ARCH_FLAG LDSHARED = #{CONFIG['LDSHARED']} AR = #{CONFIG['AR']} EXEEXT = #{CONFIG['EXEEXT']} RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']} RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']} arch = #{CONFIG['arch']} sitearch = #{CONFIG['sitearch']} ruby_version = #{Config::CONFIG['ruby_version']} ruby = #{$ruby} RUBY = $(ruby#{sep}) RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'} MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'} INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'} INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'} INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'} COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'} #### End of system configuration section. #### preload = #{$preload ? $preload.join(' ') : ''} } if $nmake == ?b mk.each do |x| x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do "!ifndef " + $1 + "\n" + $& + "!endif\n" end end end mk end
# File mkmf.rb, line 288 def cpp_command(outfile, opt="") conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote) Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}", conf) end
# File mkmf.rb, line 327 def cpp_include(header) if header header = [header] unless header.kind_of? Array header.map {|h| "#include <#{h}>\n"}.join else "" end end
# File mkmf.rb, line 926 def create_header(header = "extconf.h") message "creating %s\n", header sym = header.tr("a-z./\055", "A-Z___") hdr = ["#ifndef #{sym}\n#define #{sym}\n"] for line in $defs case line when /^-D([^=]+)(?:=(.*))?/ hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n" when /^-U(.*)/ hdr << "#undef #$1\n" end end hdr << "#endif\n" hdr = hdr.join unless (IO.read(header) == hdr rescue false) open(header, "w") do |hfile| hfile.write(hdr) end end $extconf_h = header 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 mkmf.rb, line 1177 def create_makefile(target, srcprefix = nil) $target = target libpath = $DEFLIBPATH|$LIBPATH message "creating Makefile\n" rm_f "conftest*" if CONFIG["DLEXT"] == $OBJEXT for lib in libs = $libs.split lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%) end $defs.push(format("-DEXTLIB='%s'", libs.join(","))) end if target.include?('/') target_prefix, target = File.split(target) target_prefix[0,0] = '/' else target_prefix = "" end srcprefix ||= '$(srcdir)' Config::expand(srcdir = srcprefix.dup) if not $objs $objs = [] srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] for f in srcs obj = File.basename(f, ".*") << ".o" $objs.push(obj) unless $objs.index(obj) end elsif !(srcs = $srcs) srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')} end $srcs = srcs for i in $objs i.sub!(/\.o\z/, ".#{$OBJEXT}") end $objs = $objs.join(" ") target = nil if $objs == "" if target and EXPORT_PREFIX if File.exist?(File.join(srcdir, target + '.def')) deffile = "$(srcdir)/$(TARGET).def" unless EXPORT_PREFIX.empty? makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"} end else makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"} end if makedef $distcleanfiles << '$(DEFFILE)' origdef = deffile deffile = "$(TARGET)-$(arch).def" end end origdef ||= '' libpath = libpathflag(libpath) dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : "" staticlib = target ? "$(TARGET).#$LIBEXT" : "" mfile = open("Makefile", "wb") mfile.print configuration(srcprefix) mfile.print " libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")} LIBPATH = #{libpath} DEFFILE = #{deffile} CLEANFILES = #{$cleanfiles.join(' ')} DISTCLEANFILES = #{$distcleanfiles.join(' ')} extout = #{$extout} extout_prefix = #{$extout_prefix} target_prefix = #{target_prefix} LOCAL_LIBS = #{$LOCAL_LIBS} LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS} SRCS = #{srcs.collect(&File.method(:basename)).join(' ')} OBJS = #{$objs} TARGET = #{target} DLLIB = #{dllib} EXTSTATIC = #{$static || ""} STATIC_LIB = #{staticlib unless $static.nil?} #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""} " install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]} n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).' mfile.print " TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB) CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"} static: $(STATIC_LIB)#{$extout ? " install-rb" : ""} " mfile.print CLEANINGS dirs = [] mfile.print "install: install-so install-rb\n\n" sodir = (dir = "$(RUBYARCHDIR)").dup mfile.print("install-so: #{dir}\n") if target f = "$(DLLIB)" dest = "#{dir}/#{f}" mfile.print "install-so: #{dest}\n" unless $extout mfile.print "#{dest}: #{f}\n" if (sep = config_string('BUILD_FILE_SEPARATOR')) f.gsub!("/", sep) dir.gsub!("/", sep) sep = ":/="+sep f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2} f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2} dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2} dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2} end mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n" if defined?($installed_list) mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n" end end end mfile.print("install-rb: pre-install-rb install-rb-default\n") mfile.print("install-rb-default: pre-install-rb-default\n") mfile.print("pre-install-rb: Makefile\n") mfile.print("pre-install-rb-default: Makefile\n") for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]] files = install_files(mfile, i, nil, srcprefix) or next for dir, *files in files unless dirs.include?(dir) dirs << dir mfile.print "pre-install-rb#{sfx}: #{dir}\n" end files.each do |f| dest = "#{dir}/#{File.basename(f)}" mfile.print("install-rb#{sfx}: #{dest}\n") mfile.print("#{dest}: #{f}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ") sep = config_string('BUILD_FILE_SEPARATOR') if sep f = f.gsub("/", sep) sep = ":/="+sep f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2} f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2} else sep = "" end mfile.print("#{f} $(@D#{sep})\n") if defined?($installed_list) and !$extout mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n") end end end end dirs.unshift(sodir) if target and !dirs.include?(sodir) dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"} mfile.print <<-SITEINSTALL site-install: site-install-so site-install-rb site-install-so: install-so site-install-rb: install-rb SITEINSTALL return unless target mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n" mfile.print "\n" CXX_EXT.each do |ext| COMPILE_RULES.each do |rule| mfile.printf(rule, ext, $OBJEXT) mfile.printf("\n\t%s\n\n", COMPILE_CXX) end end %w[c].each do |ext| COMPILE_RULES.each do |rule| mfile.printf(rule, ext, $OBJEXT) mfile.printf("\n\t%s\n\n", COMPILE_C) end end mfile.print "$(RUBYARCHDIR)/" if $extout mfile.print "$(DLLIB): " mfile.print "$(DEFFILE) " if makedef mfile.print "$(OBJS) Makefile\n" mfile.print "\t@-$(RM) $@\n" mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout link_so = LINK_SO.gsub(/^/, "\t") mfile.print link_so, "\n\n" unless $static.nil? mfile.print "$(STATIC_LIB): $(OBJS)\n\t" mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)" config_string('RANLIB') do |ranlib| mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true" end end mfile.print "\n\n" if makedef mfile.print "$(DEFFILE): #{origdef}\n" mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n" end depend = File.join(srcdir, "depend") if File.exist?(depend) suffixes = [] depout = [] open(depend, "r") do |dfile| mfile.printf "###\n" cont = implicit = nil impconv = proc do COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]} implicit = nil end ruleconv = proc do |line| if implicit if /\A\t/ =~ line implicit[1] << line next else impconv[] end end if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line) suffixes << m[1] << m[2] implicit = [[m[1], m[2]], [m.post_match]] next elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2} end depout << line end while line = dfile.gets() line.gsub!(/\.o\b/, ".#{$OBJEXT}") line.gsub!(/\$\(hdrdir\)\/config.h/, $config_h) if $config_h if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line (cont ||= []) << line next elsif cont line = (cont << line).join cont = nil end ruleconv.call(line) end if cont ruleconv.call(cont.join) elsif implicit impconv.call end end unless suffixes.empty? mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n" end mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h mfile.print depout else headers = %w[ruby.h defines.h] if RULE_SUBST headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}} end headers << $config_h if $config_h headers << "$(RUBY_EXTCONF_H)" if $extconf_h mfile.print "$(OBJS): ", headers.join(' '), "\n" end $makefile_created = true ensure mfile.close if mfile end
# File mkmf.rb, line 252 def create_tmpsrc(src) src = yield(src) if block_given? src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n") open(CONFTEST_C, "wb") do |cfile| cfile.print src end src 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 mkmf.rb, line 959 def dir_config(target, idefault=nil, ldefault=nil) if dir = with_config(target + "-dir", (idefault unless ldefault)) defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR) idefault = ldefault = nil end idir = with_config(target + "-include", idefault) $arg_config.last[1] ||= "${#{target}-dir}/include" ldir = with_config(target + "-lib", ldefault) $arg_config.last[1] ||= "${#{target}-dir}/lib" idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : [] if defaults idirs.concat(defaults.collect {|dir| dir + "/include"}) idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR) end unless idirs.empty? idirs.collect! {|dir| "-I" + dir} idirs -= Shellwords.shellwords($CPPFLAGS) unless idirs.empty? $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ") end end ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : [] if defaults ldirs.concat(defaults.collect {|dir| dir + "/lib"}) ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR) end $LIBPATH = ldirs | $LIBPATH [idir, ldir] end
# File mkmf.rb, line 70 def dir_re(dir) Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?') end
# File mkmf.rb, line 1150 def dummy_makefile(srcdir) configuration(srcdir) << <<RULES << CLEANINGS CLEANFILES = #{$cleanfiles.join(' ')} DISTCLEANFILES = #{$distcleanfiles.join(' ')} all install static install-so install-rb: Makefile RULES end
# File mkmf.rb, line 445 def egrep_cpp(pat, src, opt = "", &b) src = create_tmpsrc(src, &b) xpopen(cpp_command('', opt)) do |f| if Regexp === pat puts(" ruby -ne 'print if #{pat.inspect}'") f.grep(pat) {|l| puts "#{f.lineno}: #{l}" return true } false else puts(" egrep '#{pat}'") begin stdin = $stdin.dup $stdin.reopen(f) system("egrep", pat) ensure $stdin.reopen(stdin) end end end ensure rm_f "conftest*" log_src(src) end
# File mkmf.rb, line 914 def enable_config(config, *defaults) if arg_config("--enable-"+config) true elsif arg_config("--disable-"+config) false elsif block_given? yield(config, *defaults) else return *defaults end end
# File mkmf.rb, line 881 def find_executable(bin, path = nil) checking_for checking_message(bin, path) do find_executable0(bin, path) end end
# File mkmf.rb, line 861 def find_executable0(bin, path = nil) ext = config_string('EXEEXT') if File.expand_path(bin) == bin return bin if File.executable?(bin) ext and File.executable?(file = bin + ext) and return file return nil end if path ||= ENV['PATH'] path = path.split(File::PATH_SEPARATOR) else path = %w[/usr/local/bin /usr/ucb /usr/bin /bin] end file = nil path.each do |dir| return file if File.executable?(file = File.join(dir, bin)) return file if ext and File.executable?(file << ext) end nil 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 mkmf.rb, line 704 def find_header(header, *paths) header = cpp_include(header) checking_for header do if try_cpp(header) true else found = false paths.each do |dir| opt = "-I#{dir}".quote if try_cpp(header, opt) $INCFLAGS << " " << opt found = true break end end found end end 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 mkmf.rb, line 620 def find_library(lib, func, *paths, &b) func = "main" if !func or func.empty? lib = with_config(lib+'lib', lib) paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten checking_for "#{func}() in #{LIBARG%lib}" do libpath = $LIBPATH libs = append_library($libs, lib) begin until r = try_func(func, libs, &b) or paths.empty? $LIBPATH = libpath | [paths.shift] end if r $libs = libs libpath = nil end ensure $LIBPATH = libpath if libpath end r end 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 mkmf.rb, line 650 def have_func(func, headers = nil, &b) checking_for checking_message("#{func}()", headers) do if try_func(func, $libs, headers, &b) $defs.push(format("-DHAVE_%s", func.upcase)) true else false end end 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 mkmf.rb, line 687 def have_header(header, &b) checking_for header do if try_cpp(cpp_include(header), &b) $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___"))) true else false end end 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 mkmf.rb, line 595 def have_library(lib, func = nil, headers = nil, &b) func = "main" if !func or func.empty? lib = with_config(lib+'lib', lib) checking_for checking_message("#{func}()", LIBARG%lib) do if COMMON_LIBS.include?(lib) true else libs = append_library($libs, lib) if try_func(func, libs, headers, &b) $libs = libs true else false end end end 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 mkmf.rb, line 578 def have_macro(macro, headers = nil, opt = "", &b) checking_for checking_message(macro, headers, opt) do macro_defined?(macro, cpp_include(headers), opt, &b) end 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 mkmf.rb, line 735 def have_struct_member(type, member, headers = nil, &b) checking_for checking_message("#{type}.#{member}", headers) do if try_compile(<<"SRC", &b) #{COMMON_HEADERS} #{cpp_include(headers)} /*top*/ int main() { return 0; } int s = (char *)&((#{type}*)0)->#{member} - (char *)0; SRC $defs.push(format("-DHAVE_ST_%s", member.upcase)) true else false end end 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 mkmf.rb, line 765 def have_type(type, headers = nil, opt = "", &b) checking_for checking_message(type, headers, opt) do headers = cpp_include(headers) if try_compile(<<"SRC", opt, &b) #{COMMON_HEADERS} #{headers} /*top*/ typedef #{type} conftest_type; static conftest_type conftestval[sizeof(conftest_type)?1:-1]; SRC $defs.push(format("-DHAVE_TYPE_%s", type.strip.upcase.tr_s("^A-Z0-9_", "_"))) true else false end end 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 mkmf.rb, line 669 def have_var(var, headers = nil, &b) checking_for checking_message(var, headers) do if try_var(var, headers, &b) $defs.push(format("-DHAVE_%s", var.upcase)) true else false end end end
# File mkmf.rb, line 1446 def init_mkmf(config = CONFIG) $makefile_created = false $arg_config = [] $enable_shared = config['ENABLE_SHARED'] == 'yes' $defs = [] $extconf_h = nil $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)" $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup $LIBEXT = config['LIBEXT'].dup $OBJEXT = config["OBJEXT"].dup $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}" $LIBRUBYARG = "" $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC'] $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED'] $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"] $DEFLIBPATH.unshift(".") $LIBPATH = [] $INSTALLFILES = nil $objs = nil $srcs = nil $libs = "" if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup) $LIBRUBYARG = config['LIBRUBYARG'] end $LOCAL_LIBS = "" $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || [] $cleanfiles << "mkmf.log" $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || [] $extout ||= nil $extout_prefix ||= nil $arg_config.clear dir_config("opt") end
# File mkmf.rb, line 83 def install_dirs(target_prefix = nil) if $extout dirs = [ ['RUBYCOMMONDIR', '$(extout)/common'], ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'], ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'], ['extout', "#$extout"], ['extout_prefix', "#$extout_prefix"], ] elsif $extmk dirs = [ ['RUBYCOMMONDIR', '$(rubylibdir)'], ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'], ['RUBYARCHDIR', '$(archdir)$(target_prefix)'], ] else dirs = [ ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'], ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'], ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'], ] end dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")] dirs end
# File mkmf.rb, line 492 def install_files(mfile, ifiles, map = nil, srcprefix = nil) ifiles or return srcprefix ||= '$(srcdir)' Config::expand(srcdir = srcprefix.dup) dirs = [] path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]} ifiles.each do |files, dir, prefix| dir = map_dir(dir, map) prefix = %r|\A#{Regexp.quote(prefix)}/?| if prefix if /\A\.\// =~ files # install files which are in current working directory. files = files[2..-1] len = nil else # install files which are under the $(srcdir). files = File.join(srcdir, files) len = srcdir.size end f = nil Dir.glob(files) do |f| f[0..len] = "" if len d = File.dirname(f) d.sub!(prefix, "") if prefix d = (d.empty? || d == ".") ? dir : File.join(dir, d) f = File.join(srcprefix, f) if len path[d] << f end unless len or f d = File.dirname(files) d.sub!(prefix, "") if prefix d = (d.empty? || d == ".") ? dir : File.join(dir, d) path[d] << files end end dirs end
# File mkmf.rb, line 529 def install_rb(mfile, dest, srcdir = nil) install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir) end
# File mkmf.rb, line 294 def libpathflag(libpath=$DEFLIBPATH|$LIBPATH) libpath.map{|x| case x when "$(topdir)", /\A\./ LIBPATHFLAG else LIBPATHFLAG+RPATHFLAG end % x.quote }.join end
# File mkmf.rb, line 268 def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH) conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'src' => CONFTEST_C, 'INCFLAGS' => $INCFLAGS, 'CPPFLAGS' => $CPPFLAGS, 'CFLAGS' => "#$CFLAGS", 'ARCH_FLAG' => "#$ARCH_FLAG", 'LDFLAGS' => "#$LDFLAGS #{ldflags}", 'LIBPATH' => libpathflag(libpath), 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs", 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS") Config::expand(TRY_LINK.dup, conf) end
# File mkmf.rb, line 238 def log_src(src) src = src.split(/^/) fmt = "%#{src.size.to_s.size}d: %s" Logging::message <<"EOM" checked program was: /* begin */ EOM src.each_with_index {|line, no| Logging::message fmt, no+1, line} Logging::message <<"EOM" /* end */ EOM end
# File mkmf.rb, line 471 def macro_defined?(macro, src, opt = "", &b) src = src.sub(/[^\n]\z/, "\\&\n") try_compile(src + <<"SRC", opt, &b) /*top*/ #ifndef #{macro} # error >>>>>> #{macro} undefined <<<<<< #endif SRC end
# File mkmf.rb, line 109 def map_dir(dir, map = nil) map ||= INSTALL_DIRS map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)} end
# File mkmf.rb, line 152 def merge_libs(*libs) libs.inject([]) do |x, y| xy = x & y xn = yn = 0 y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e} y.each_with_index do |v, yi| if xy.include?(v) xi = [x.index(v), xn].max() x[xi, 1] = y[yn..yi] xn, yn = xi + (yi - yn + 1), yi + 1 end end x.concat(y[yn..-1] || []) end end
# File mkmf.rb, line 537 def message(*s) unless $extmk and not $VERBOSE printf(*s) $stdout.flush end end
# File mkmf.rb, line 1041 def mkintpath(path) # mingw uses make from msys and it needs special care # converts from C:\some\path to /C/some/path path = path.dup path.tr!('\\', '/') path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1') path end
# File mkmf.rb, line 1497 def mkmf_failed(path) unless $makefile_created or File.exist?("Makefile") opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"} abort "*** #{path} failed ***\n" + FailedMessage + opts.join end end
# File mkmf.rb, line 146 def modified?(target, times) (t = File.mtime(target)) rescue return nil Array === times or times = [times] t if times.all? {|n| n <= t} end
# File mkmf.rb, line 993 def pkg_config(pkg) if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig) # iff package specific config command is given get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} elsif ($PKGCONFIG ||= (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) && find_executable0(pkgconfig) && pkgconfig) and system("#{$PKGCONFIG} --exists #{pkg}") # default to pkg-config command get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp} elsif find_executable0(pkgconfig = "#{pkg}-config") # default to package specific config command, as a last resort. get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} end if get cflags = get['cflags'] ldflags = get['libs'] libs = get['libs-only-l'] ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") $CFLAGS += " " << cflags $LDFLAGS += " " << ldflags $libs += " " << libs Logging::message "package configuration for %s\n", pkg Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs [cflags, ldflags, libs] else Logging::message "package configuration for %s is not found\n", pkg nil end end
# File mkmf.rb, line 142 def rm_f(*files) FileUtils.rm_f(Dir[files.join("\0")]) end
# File mkmf.rb, line 807 def scalar_ptr_type?(type, member = nil, headers = nil, &b) try_compile(<<"SRC", &b) # pointer #{COMMON_HEADERS} #{cpp_include(headers)} /*top*/ volatile #{type} conftestval; int main() { return 0; } int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));} SRC end
# File mkmf.rb, line 818 def scalar_type?(type, member = nil, headers = nil, &b) try_compile(<<"SRC", &b) # pointer #{COMMON_HEADERS} #{cpp_include(headers)} /*top*/ volatile #{type} conftestval; int main() { return 0; } int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));} SRC end
# File mkmf.rb, line 315 def try_compile(src, opt="", &b) try_do(src, cc_command(opt), &b) ensure rm_f "conftest*" end
# File mkmf.rb, line 370 def try_constant(const, headers = nil, opt = "", &b) includes = cpp_include(headers) if CROSS_COMPILING if try_static_assert("#{const} > 0", headers, opt) # positive constant elsif try_static_assert("#{const} < 0", headers, opt) neg = true const = "-(#{const})" elsif try_static_assert("#{const} == 0", headers, opt) return 0 else # not a constant return nil end upper = 1 lower = 0 until try_static_assert("#{const} <= #{upper}", headers, opt) lower = upper upper <<= 1 end return nil unless lower while upper > lower + 1 mid = (upper + lower) / 2 if try_static_assert("#{const} > #{mid}", headers, opt) lower = mid else upper = mid end end upper = -upper if neg return upper else src = %{#{COMMON_HEADERS} #{includes} #include <stdio.h> /*top*/ int conftest_const = (int)(#{const}); int main() {printf("%d\\n", conftest_const); return 0;} } if try_link0(src, opt, &b) xpopen("./conftest") do |f| return Integer(f.gets) end end end nil end
# File mkmf.rb, line 321 def try_cpp(src, opt="", &b) try_do(src, cpp_command(CPPOUTFILE, opt), &b) ensure rm_f "conftest*" end
# File mkmf.rb, line 261 def try_do(src, command, &b) src = create_tmpsrc(src, &b) xsystem(command) ensure log_src(src) end
# File mkmf.rb, line 418 def try_func(func, libs, headers = nil, &b) headers = cpp_include(headers) try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b) #{COMMON_HEADERS} #{headers} /*top*/ int main() { return 0; } int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; } SRC #{headers} /*top*/ int main() { return 0; } int t() { #{func}(); return 0; } SRC end
# File mkmf.rb, line 309 def try_link(src, opt="", &b) try_link0(src, opt, &b) ensure rm_f "conftest*", "c0x32*" end
# File mkmf.rb, line 305 def try_link0(src, opt="", &b) try_do(src, link_command("", opt), &b) end
# File mkmf.rb, line 482 def try_run(src, opt = "", &b) if try_link0(src, opt, &b) xsystem("./conftest") else nil end ensure rm_f "conftest*" end
# File mkmf.rb, line 360 def try_static_assert(expr, headers = nil, opt = "", &b) headers = cpp_include(headers) try_compile(<<SRC, opt, &b) #{COMMON_HEADERS} #{headers} /*top*/ int conftest_const[(#{expr}) ? 1 : -1]; SRC end
# File mkmf.rb, line 434 def try_var(var, headers = nil, &b) headers = cpp_include(headers) try_compile(<<"SRC", &b) #{COMMON_HEADERS} #{headers} /*top*/ int main() { return 0; } int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; } SRC end
# File mkmf.rb, line 829 def what_type?(type, member = nil, headers = nil, &b) m = "#{type}" name = type if member m << "." << member name = "(((#{type} *)0)->#{member})" end fmt = "seems %s" def fmt.%(x) x ? super : "unknown" end checking_for checking_message(m, headers), fmt do if scalar_ptr_type?(type, member, headers, &b) if try_static_assert("sizeof(*#{name}) == 1", headers) "string" end elsif scalar_type?(type, member, headers, &b) if try_static_assert("sizeof(#{name}) > sizeof(long)", headers) "long long" elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers) "long" elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers) "int" elsif try_static_assert("sizeof(#{name}) > 1", headers) "short" else "char" end end end end
# File mkmf.rb, line 344 def with_cflags(flags) cflags = $CFLAGS $CFLAGS = flags ret = yield ensure $CFLAGS = cflags unless ret end
# File mkmf.rb, line 893 def with_config(config, *defaults) config = config.sub(/^--with[-_]/, '') val = arg_config("--with-"+config) do if arg_config("--without-"+config) false elsif block_given? yield(config, *defaults) else break *defaults end end case val when "yes" true when "no" false else val end end
# File mkmf.rb, line 336 def with_cppflags(flags) cppflags = $CPPFLAGS $CPPFLAGS = flags ret = yield ensure $CPPFLAGS = cppflags unless ret end
# File mkmf.rb, line 1025 def with_destdir(dir) dir = dir.sub($dest_prefix_pattern, '') /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir end
# File mkmf.rb, line 352 def with_ldflags(flags) ldflags = $LDFLAGS $LDFLAGS = flags ret = yield ensure $LDFLAGS = ldflags unless ret end