module MakeMakefile - Documentation for Ruby 4.0
Description: module MakeMakefile: Module \MakeMakefile is used by Ruby C extensions to generate a Makefile which will correctly compile and link the C extension to Ruby and a third-par
Keywords: ruby,module,MakeMakefile

🔍

No recent searches

# module MakeMakefile

Module MakeMakefile is used by Ruby C extensions to generate a Makefile which will correctly compile and link the C extension to Ruby and a third-party library.

### Constants

ASSEMBLE_C

  Command which will translate C files to assembler sources in the generated Makefile

ASSEMBLE_CXX

  Command which will translate C++ files to assembler sources in the generated Makefile

CLEANINGS

  Makefile rules that will clean the extension build directory

COMMON_HEADERS

  Common headers for Ruby C extensions

COMMON_LIBS

  Common libraries for Ruby C extensions

COMPILE_C

  Command which will compile C files in the generated Makefile

COMPILE_CXX

  Command which will compile C++ files in the generated Makefile

COMPILE_RULES

  make compile rules

CONFIG

  The makefile configuration using the defaults from when Ruby was built.

CXX_EXT

  Extensions for files compiled with a C++ compiler

C_EXT

  Extensions for files compiled with a C compiler

EXPORT_PREFIX

  The prefix added to exported symbols automatically

HDR_EXT

  Extensions for header files

LANGUAGE

  The language that this module is for

LIBARG

  Argument which will add a library to the linker

LIBPATHFLAG

  Argument which will add a library path to the linker

LINK_SO

  Command which will link a shared library

MAIN_DOES_NOTHING

  A C main function which does no work

ORIG_LIBPATH

  The saved original value of `LIB` environment variable

RPATHFLAG

  Argument which will add a runtime library path to the linker

RULE_SUBST

  Substitution in rules for NMake

RbConfig

  The module storing Ruby interpreter configurations on building.

  This file was created by mkconfig.rb when ruby was built. It contains build information for ruby which is used e.g. by mkmf to build compatible native extensions. Any changes made to this file will be lost the next time ruby is built.

SRC_EXT

  Extensions for source files

TRY_LINK

  Command which will compile a program in order to test linking a library

UNIVERSAL_INTS

  The type names for `convertible_int`

### Public Class Methods

[] (name)
Source

    # File lib/mkmf.rb, line 2990
    def self.[](name)
      @lang.fetch(name)
    end

Retrieves the module for name language.

[]= (name, mod)
Source

    # File lib/mkmf.rb, line 2996
    def self.[]=(name, mod)
      @lang[name] = mod
    end

Defines the module for name language.

rm_f (*files)
Source

    # File lib/mkmf.rb, line 270
    def rm_f(*files)
      opt = (Hash === files.last ? [files.pop] : [])
      FileUtils.rm_f(Dir[*files.flatten], *opt)
    end

Removes files.

rm_rf (*files)
Source

    # File lib/mkmf.rb, line 277
    def rm_rf(*files)
      opt = (Hash === files.last ? [files.pop] : [])
      FileUtils.rm_rf(Dir[*files.flatten], *opt)
    end

Removes files recursively.

### Public Instance Methods

append_cflags (flags, **opts)
Source

    # File lib/mkmf.rb, line 1106
    def append_cflags(flags, **opts)
      Array(flags).each do |flag|
        if checking_for("whether #{flag} is accepted as CFLAGS") {
             try_cflags(flag, **opts)
           }
          $CFLAGS << " " << flag
        end
      end
    end

Check whether each given C compiler flag is acceptable and append it to `$CFLAGS` if so.

`flags`

  a C compiler flag as a `String` or an `Array` of them

append_ldflags (flags, **opts)
Source

    # File lib/mkmf.rb, line 762
    def append_ldflags(flags, **opts)
      Array(flags).each do |flag|
        if checking_for("whether #{flag} is accepted as LDFLAGS") {
             try_ldflags(flag, **opts)
           }
          $LDFLAGS << " " << flag
        end
      end
    end

Check whether each given linker flag is acceptable and append it to `$LDFLAGS` if so.

`flags`

  a linker flag as a `String` or an `Array` of them

check_signedness (type, headers = nil, opts = nil, &b)
Source

    # File lib/mkmf.rb, line 1509
    def check_signedness(type, headers = nil, opts = nil, &b)
      typedef, member, prelude = typedef_expr(type, headers)
      signed = nil
      checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
        signed = try_signedness(typedef, member, [prelude], opts, &b) or next nil
        $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
        signed < 0 ? "signed" : "unsigned"
      end
      signed
    end

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

If the `type` is found and is a numeric type, a macro is passed as a preprocessor constant to the compiler using the `type` name, in uppercase, prepended with `SIGNEDNESS_OF_`, followed by the `type` name, followed by `=X` where “X” is positive integer if the `type` is unsigned and a negative integer if the `type` is signed.

For example, if `size_t` is defined as unsigned, then `check_signedness('size_t')` would return +1 and the `SIGNEDNESS_OF_SIZE_T=+1` preprocessor macro would be passed to the compiler. The `SIGNEDNESS_OF_INT=-1` macro would be set for `check_signedness('int')`

check_sizeof (type, headers = nil, opts = "", &b)
Source

    # File lib/mkmf.rb, line 1480
    def check_sizeof(type, headers = nil, opts = "", &b)
      typedef, member, prelude = typedef_expr(type, headers)
      prelude << "#{typedef} *rbcv_ptr_;\n"
      prelude = [prelude]
      expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
      fmt = STRING_OR_FAILED_FORMAT
      checking_for checking_message("size of #{type}", headers), fmt do
        if size = try_constant(expr, prelude, opts, &b)
          $defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
          size
        end
      end
    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.

conftest_source ()
Source

    # File lib/mkmf.rb, line 488
    def conftest_source
      CONFTEST_C
    end

Returns the language-dependent source file name for configuration checks.

convertible_int (type, headers = nil, opts = nil, &b)
Source

    # File lib/mkmf.rb, line 1544
    def convertible_int(type, headers = nil, opts = nil, &b)
      type, macname = *type
      checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do
        if UNIVERSAL_INTS.include?(type)
          type
        else
          typedef, member, prelude = typedef_expr(type, headers, &b)
          if member
            prelude << "static rbcv_typedef_ rbcv_var;"
            compat = UNIVERSAL_INTS.find {|t|
              try_static_assert("sizeof(rbcv_var.#{member}) == sizeof(#{t})", [prelude], opts, &b)
            }
          else
            next unless signed = try_signedness(typedef, member, [prelude])
            u = "unsigned " if signed > 0
            prelude << "extern rbcv_typedef_ foo();"
            compat = UNIVERSAL_INTS.find {|t|
              try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, werror: true, &b)
            }
          end
          if compat
            macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
            conv = (compat == "long long" ? "LL" : compat.upcase)
            compat = "#{u}#{compat}"
            typename = type.tr_cpp
            $defs.push(format("-DSIZEOF_%s=SIZEOF_%s", typename, compat.tr_cpp))
            $defs.push(format("-DTYPEOF_%s=%s", typename, compat.quote))
            $defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
            conv = (u ? "U" : "") + conv
            $defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
            $defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
            compat
          end
        end
      end
    end

Returns the convertible integer type of the given `type`. You may optionally specify additional `headers` to search in for the `type`. convertible means actually the same type, or typedef’d from the same type.

If the `type` is an integer type and the convertible type is found, the following macros are passed as preprocessor constants to the compiler using the `type` name, in uppercase.

- `TYPEOF_`, followed by the `type` name, followed by `=X` where “X” is the found convertible type name.

- `TYP2NUM` and `NUM2TYP`, where `TYP` is the `type` name in uppercase with replacing an `_t` suffix with “T”, followed by `=X` where “X” is the macro name to convert `type` to an `Integer` object, and vice versa.

For example, if `foobar_t` is defined as unsigned long, then `convertible_int("foobar_t")` would return “unsigned long”, and define these macros:

    #define TYPEOF_FOOBAR_T unsigned long
    #define FOOBART2NUM ULONG2NUM
    #define NUM2FOOBART NUM2ULONG

create_header (header = "extconf.h")
Source

    # File lib/mkmf.rb, line 1840
    def create_header(header = "extconf.h")
      message "creating %s\n", header
      sym = header.tr_cpp
      hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
      for line in $defs
        case line
        when /^-D([^=]+)(?:=(.*))?/
          hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
        when /^-U(.*)/
          hdr << "#undef #$1\n"
        end
      end
      hdr << "#endif\n"
      hdr = hdr.join("")
      log_src(hdr, "#{header} is")
      unless (File.read(header) == hdr rescue false)
        File.open(header, "wb") do |hfile|
          hfile.write(hdr)
        end
      end
      $extconf_h = header
    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.

create_makefile (target, srcprefix = nil) { |conf| ... }
Source

    # File lib/mkmf.rb, line 2396
      def create_makefile(target, srcprefix = nil)
        $target = target
        libpath = $DEFLIBPATH|$LIBPATH
        message "creating Makefile\n"
        MakeMakefile.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)/#{srcprefix}".chomp('/')
        RbConfig.expand(srcdir = srcprefix.dup)

        ext = ".#{$OBJEXT}"
        orig_srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
        if not $objs
          srcs = $srcs || orig_srcs
          $objs = []
          objs = srcs.inject(Hash.new {[]}) {|h, f|
            h.key?(o = File.basename(f, ".*") << ext) or $objs << o
            h[o] <<= f
            h
          }
          unless objs.delete_if {|b, f| f.size == 1}.empty?
            dups = objs.map {|b, f|
              "#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}"
            }
            abort "source files duplication - #{dups.join(", ")}"
          end
        else
          $objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
          srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
        end
        $srcs = srcs

        hdrs = Dir[File.join(srcdir, "*.{#{HDR_EXT.join(%q{,})}}")]

        target = nil if $objs.empty?

        if target and EXPORT_PREFIX
          if File.exist?(File.join(srcdir, target + '.def'))
            deffile = "$(srcdir)/$(TARGET).def"
            unless EXPORT_PREFIX.empty?
              makedef = %{$(RUBY) -pe "$$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i" #{deffile}}
            end
          else
            makedef = %{(echo EXPORTS && echo $(TARGET_ENTRY))}
          end
          if makedef
            $cleanfiles << '$(DEFFILE)'
            origdef = deffile
            deffile = "$(TARGET)-$(arch).def"
          end
        end
        origdef ||= ''

        if $extout and $INSTALLFILES
          $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.delete_prefix('./'))})
          $distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir})
        end

        if $extmk and $static
          $defs << "-DRUBY_EXPORT=1"
        end

        if $extmk and not $extconf_h
          create_header
        end

        libpath = libpathflag(libpath)

        dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
        staticlib = target ? "$(TARGET).#$LIBEXT" : ""
        conf = configuration(srcprefix)
        conf << "\
    libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
    LIBPATH = #{libpath}
    DEFFILE = #{deffile}

    CLEANFILES = #{$cleanfiles.join(' ')}
    DISTCLEANFILES = #{$distcleanfiles.join(' ')}
    DISTCLEANDIRS = #{$distcleandirs.join(' ')}

    extout = #{$extout && $extout.quote}
    extout_prefix = #{$extout_prefix}
    target_prefix = #{target_prefix}
    LOCAL_LIBS = #{$LOCAL_LIBS}
    LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
    ORIG_SRCS = #{orig_srcs.collect(&File.method(:basename)).join(' ')}
    SRCS = $(ORIG_SRCS) #{(srcs - orig_srcs).collect(&File.method(:basename)).join(' ')}
    OBJS = #{$objs.join(" ")}
    HDRS = #{hdrs.map{|h| '$(srcdir)/' + File.basename(h)}.join(' ')}
    LOCAL_HDRS = #{$headers.join(' ')}
    TARGET = #{target}
    TARGET_NAME = #{target && target[/\A\w+/]}
    TARGET_ENTRY = #{EXPORT_PREFIX || ''}Init_$(TARGET_NAME)
    DLLIB = #{dllib}
    EXTSTATIC = #{$static || ""}
    STATIC_LIB = #{staticlib unless $static.nil?}
    #{!$extout && defined?($installed_list) ? %[INSTALLED_LIST = #{$installed_list}\n] : ""}
    TIMESTAMP_DIR = #{$extout && $extmk ? '$(extout)/.timestamp' : '.'}
    " #"
        # TODO: fixme
        install_dirs.each {|d| conf << ("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
        sodir = $extout ? '$(TARGET_SO_DIR)' : '$(RUBYARCHDIR)'
        n = '$(TARGET_SO_DIR)$(TARGET)'
        cleanobjs = ["$(OBJS)"]
        cleanlibs = []
        if $extmk
          %w[bc i s].each {|ex| cleanobjs << "$(OBJS:.#{$OBJEXT}=.#{ex})"}
        end
        if target
          config_string('cleanobjs') {|t| cleanobjs << t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")}
          cleanlibs << '$(TARGET_SO)'
        end
        config_string('cleanlibs') {|t| cleanlibs << t.gsub(/\$\*/) {n}}
        conf << "\
    TARGET_SO_DIR =#{$extout ? " $(RUBYARCHDIR)/" : ''}
    TARGET_SO     = $(TARGET_SO_DIR)$(DLLIB)
    CLEANLIBS     = #{cleanlibs.join(' ')}
    CLEANOBJS     = #{cleanobjs.join(' ')} *.bak
    TARGET_SO_DIR_TIMESTAMP = #{timestamp_file(sodir, target_prefix)}
    " #"

        conf = yield(conf) if block_given?
        mfile = File.open("Makefile", "wb")
        mfile.puts(conf)
        mfile.print "
    all:    #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
    static: #{$extmk && !$static ? "all" : %[$(STATIC_LIB)#{$extout ? " install-rb" : ""}]}
    .PHONY: all install static install-so install-rb
    .PHONY: clean clean-so clean-static clean-rb
    " #"
        mfile.print CLEANINGS
        fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"}
        if fsep
          sep = ":/=#{fsep}"
          fseprepl = proc {|s|
            s = s.gsub("/", fsep)
            s = s.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
            s.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
          }
          rsep = ":#{fsep}=/"
        else
          fseprepl = proc {|s| s}
          sep = ""
          rsep = ""
        end
        dirs = []
        mfile.print "install: install-so install-rb\n\n"
        dir = sodir.dup
        mfile.print("install-so: ")
        if target
          f = "$(DLLIB)"
          dest = "$(TARGET_SO)"
          stamp = '$(TARGET_SO_DIR_TIMESTAMP)'
          if $extout
            mfile.puts dest
            mfile.print "clean-so::\n"
            mfile.print "\t-$(Q)$(RM) #{fseprepl[dest]} #{fseprepl[stamp]}\n"
            mfile.print "\t-$(Q)$(RM_RF) #{fseprepl['$(CLEANLIBS)']}\n"
            mfile.print "\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n"
          else
            mfile.print "#{f} #{stamp}\n"
            mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n"
            if defined?($installed_list)
              mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
            end
          end
          mfile.print "clean-static::\n"
          mfile.print "\t-$(Q)$(RM) $(STATIC_LIB)\n"
        else
          mfile.puts "Makefile"
        end
        mfile.print("install-rb: pre-install-rb do-install-rb install-rb-default\n")
        mfile.print("install-rb-default: pre-install-rb-default do-install-rb-default\n")
        mfile.print("pre-install-rb: Makefile\n")
        mfile.print("pre-install-rb-default: Makefile\n")
        mfile.print("do-install-rb:\n")
        mfile.print("do-install-rb-default:\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}: #{timestamp_file(dir, target_prefix)}\n"
            end
            for f in files
              dest = "#{dir}/#{File.basename(f)}"
              mfile.print("do-install-rb#{sfx}: #{dest}\n")
              mfile.print("#{dest}: #{f} #{timestamp_file(dir, target_prefix)}\n")
              mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $@\n")
              if defined?($installed_list) and !$extout
                mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
              end
              if $extout
                mfile.print("clean-rb#{sfx}::\n")
                mfile.print("\t-$(Q)$(RM) #{fseprepl[dest]}\n")
              end
            end
          end
          mfile.print "pre-install-rb#{sfx}:\n"
          if files.empty?
            mfile.print("\t@$(NULLCMD)\n")
          else
            q = "$(MAKE) -q do-install-rb#{sfx}"
            if $nmake
              mfile.print "!if \"$(Q)\" == \"@\"\n\t@#{q} || \\\n!endif\n\t"
            else
              mfile.print "\t$(Q1:0=@#{q} || )"
            end
            mfile.print "$(ECHO1:0=echo) installing#{sfx.sub(/^-/, " ")} #{target} libraries\n"
          end
          if $extout
            dirs.uniq!
            unless dirs.empty?
              mfile.print("clean-rb#{sfx}::\n")
              for dir in dirs.sort_by {|d| -d.count('/')}
                stamp = timestamp_file(dir, target_prefix)
                mfile.print("\t-$(Q)$(RM) #{fseprepl[stamp]}\n")
                mfile.print("\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n")
              end
            end
          end
        end
        if target and !dirs.include?(sodir)
          mfile.print "$(TARGET_SO_DIR_TIMESTAMP):\n\t$(Q) $(MAKEDIRS) $(@D) #{sodir}\n\t$(Q) $(TOUCH) $@\n"
        end
        dirs.each do |d|
          t = timestamp_file(d, target_prefix)
          mfile.print "#{t}:\n\t$(Q) $(MAKEDIRS) $(@D) #{d}\n\t$(Q) $(TOUCH) $@\n"
        end

        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.print ".SUFFIXES: .#{(SRC_EXT + [$OBJEXT, $ASMEXT]).compact.join(' .')}\n"
        mfile.print "\n"

        compile_command = "\n\t$(ECHO) compiling $(<#{rsep})\n\t$(Q) %s\n\n"
        command = compile_command % COMPILE_CXX
        asm_command = compile_command.sub(/compiling/, 'translating') % ASSEMBLE_CXX
        CXX_EXT.each do |e|
          each_compile_rules do |rule|
            mfile.printf(rule, e, $OBJEXT)
            mfile.print(command)
            mfile.printf(rule, e, $ASMEXT)
            mfile.print(asm_command)
          end
        end
        command = compile_command % COMPILE_C
        asm_command = compile_command.sub(/compiling/, 'translating') % ASSEMBLE_C
        C_EXT.each do |e|
          each_compile_rules do |rule|
            mfile.printf(rule, e, $OBJEXT)
            mfile.print(command)
            mfile.printf(rule, e, $ASMEXT)
            mfile.print(asm_command)
          end
        end

        mfile.print "$(TARGET_SO): "
        mfile.print "$(DEFFILE) " if makedef
        mfile.print "$(OBJS) Makefile"
        mfile.print " $(TARGET_SO_DIR_TIMESTAMP)" if $extout
        mfile.print "\n"
        mfile.print "\t$(ECHO) linking shared-object #{target_prefix.sub(/\A\/(.*)/, '\1/')}$(DLLIB)\n"
        mfile.print "\t-$(Q)$(RM) $(@#{sep})\n"
        link_so = LINK_SO.gsub(/^/, "\t$(Q) ")
        if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===))
          link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
        end
        mfile.print link_so, "\n\n"
        unless $static.nil?
          mfile.print "$(STATIC_LIB): $(OBJS)\n\t-$(Q)$(RM) $(@#{sep})\n\t"
          mfile.print "$(ECHO) linking static-library $(@#{rsep})\n\t$(Q) "
          mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
          config_string('RANLIB') do |ranlib|
            mfile.print "\n\t-$(Q)#{ranlib} $(@)#{$ignore_error}"
          end
        end
        mfile.print "\n\n"
        if makedef
          mfile.print "$(DEFFILE): #{origdef}\n"
          mfile.print "\t$(ECHO) generating $(@#{rsep})\n"
          mfile.print "\t$(Q) #{makedef} > $@\n\n"
        end

        depend = File.join(srcdir, "depend")
        if File.exist?(depend)
          mfile.print("###\n", *depend_rules(File.read(depend)))
        else
          mfile.print "$(OBJS): $(HDRS) $(ruby_headers)\n"
        end

        $makefile_created = true
      ensure
        mfile.close if mfile
      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 `RbConfig::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`.

Yields the configuration part of the makefile to be generated, as an array of strings, if the block is given. The returned value will be used the new configuration part.

    create_makefile('foo') {|conf|
      [
        *conf,
        "MACRO_YOU_NEED = something",
      ]
    }

If “depend” file exist in the source directory, that content will be included in the generated makefile, with formatted by `depend_rules` method.

create_tmpsrc (src) { |src| ... }
Source

    # File lib/mkmf.rb, line 495
    def create_tmpsrc(src)
      src = "#{COMMON_HEADERS}\n#{src}"
      src = yield(src) if block_given?
      src.gsub!(/[ \t]+$/, '')
      src.gsub!(/\A\n+|^\n+$/, '')
      src.sub!(/[^\n]\z/, "\\&\n")
      count = 0
      begin
        File.open(conftest_source, "wb") do |cfile|
          cfile.print src
        end
      rescue Errno::EACCES
        if (count += 1) < 5
          sleep 0.2
          retry
        end
      end
      src
    end

Creats temporary source file from `COMMON_HEADERS` and src. Yields the created source string and uses the returned string as the source code, if the block is given.

depend_rules (depend)
Source

    # File lib/mkmf.rb, line 2268
    def depend_rules(depend)
      suffixes = []
      depout = []
      cont = implicit = nil
      impconv = proc do
        each_compile_rules {|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.sub!(/\s*\#.*$/, '')
          comment = $&
          line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
          line = line.chomp + comment + "\n" if comment
        end
        depout << line
      end
      depend.each_line do |line|
        line.gsub!(/\.o\b/, ".#{$OBJEXT}")
        line.gsub!(/\{\$\(VPATH\)\}/, "") unless $nmake
        line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
        if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
          line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")}
          line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\')
        end
        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
      unless suffixes.empty?
        depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
      end
      if $extconf_h
        depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n")
        depout.unshift("$(OBJS): $(hdrdir)/ruby/win32.h\n\n") if $mswin or $mingw
      end
      depout.flatten!
      depout
    end

Processes the data contents of the “depend” file. Each line of this file is expected to be a file name.

Returns the output of findings, in Makefile format.

dir_config(target)
dir_config(target, prefix)
dir_config(target, idefault, ldefault)
Source

    # File lib/mkmf.rb, line 1890
    def dir_config(target, idefault=nil, ldefault=nil)
      key = [target, idefault, ldefault].compact.join("\0")
      if conf = $config_dirs[key]
        return conf
      end

      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)
      if conf = $arg_config.assoc("--with-#{target}-include")
        conf[1] ||= "${#{target}-dir}/include"
      end
      ldir = with_config(target + "-lib", ldefault)
      if conf = $arg_config.assoc("--with-#{target}-lib")
        conf[1] ||= "${#{target}-dir}/#{_libdir_basename}"
      end

      idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
      if defaults
        idirs.concat(defaults.collect {|d| d + "/include"})
        idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
      end
      unless idirs.empty?
        idirs.collect! {|d| "-I" + d}
        idirs -= Shellwords.shellwords($CPPFLAGS)
        unless idirs.empty?
          $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
        end
      end

      ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : []
      if defaults
        ldirs.concat(defaults.collect {|d| "#{d}/#{_libdir_basename}"})
        ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
      end
      $LIBPATH = ldirs | $LIBPATH

      $config_dirs[key] = [idir, ldir]
    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=prefix`, `--with-foo-include=dir` and `--with-foo-lib=dir` command line options to tell where to search for header/library files.

You may pass along additional parameters to specify default values. If one is given it is taken as default `prefix`, and if two are given they are taken as “include” and “lib” defaults in that order.

In any case, the return value will be an array of determined “include” and “lib” directories, either of which can be nil if no corresponding command line option is given when no default value is specified.

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.

dummy_makefile (srcdir)
Source

    # File lib/mkmf.rb, line 2237
      def dummy_makefile(srcdir)
        configuration(srcdir) << <<RULES << CLEANINGS
    CLEANFILES = #{$cleanfiles.join(' ')}
    DISTCLEANFILES = #{$distcleanfiles.join(' ')}

    all install static install-so install-rb: Makefile
            @$(NULLCMD)
    .PHONY: all install static install-so install-rb
    .PHONY: clean clean-so clean-static clean-rb

    RULES
      end

Creates a stub Makefile.

egrep_cpp (pat, src, opt = "", &b)
Source

    # File lib/mkmf.rb, line 923
    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
      MakeMakefile.rm_f "#{CONFTEST}*"
      log_src(src)
    end

Returns whether or not the `src` can be preprocessed with the C preprocessor and matches with `pat`.

If a block given, it is called with the source before compilation. You can modify the source in the block.

`pat`

  a `Regexp` or a `String`

`src`

  a `String` which contains a C source

`opt`

  a `String` which contains preprocessor options

NOTE: When pat is a `Regexp` the matching will be checked in process, otherwise egrep(1) will be invoked to check it.

enable_config (config, default=nil) { |config, default| ... }
Source

    # File lib/mkmf.rb, line 1802
    def enable_config(config, default=nil)
      if arg_config("--enable-"+config)
        true
      elsif arg_config("--disable-"+config)
        false
      elsif block_given?
        yield(config, default)
      else
        return default
      end
    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

find_header (header, *paths)
Source

    # File lib/mkmf.rb, line 1290
    def find_header(header, *paths)
      message = checking_message(header, paths)
      header = cpp_include(header)
      checking_for message do
        if try_header(header)
          true
        else
          found = false
          paths.each do |dir|
            opt = "-I#{dir}".quote
            if try_header(header, opt)
              $INCFLAGS << " " << opt
              found = true
              break
            end
          end
          found
        end
      end
    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).

find_library (lib, func, *paths, &b)
Source

    # File lib/mkmf.rb, line 1164
    def find_library(lib, func, *paths, &b)
      dir_config(lib)
      lib = with_config(lib+'lib', lib)
      paths = paths.flat_map {|path| path.split(File::PATH_SEPARATOR)}
      checking_for checking_message(func && func.funcall_style, 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 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.

have_framework (fw, &b)
Source

    # File lib/mkmf.rb, line 1261
    def have_framework(fw, &b)
      if Array === fw
        fw, header = *fw
      else
        header = "#{fw}.h"
      end
      checking_for fw do
        src = cpp_include("#{fw}/#{header}") << "\n" "int main(void){return 0;}"
        opt = " -framework #{fw}"
        if try_link(src, opt, &b) or (objc = try_link(src, "-ObjC#{opt}", &b))
          $defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp))
          # TODO: non-worse way than this hack, to get rid of separating
          # option and its argument.
          $LDFLAGS << " -ObjC" if objc and /(\A|\s)-ObjC(\s|\z)/ !~ $LDFLAGS
          $LIBS << opt
          true
        else
          false
        end
      end
    end

Returns whether or not the given `framework` can be found on your system. If found, a macro is passed as a preprocessor constant to the compiler using the framework name, in uppercase, prepended with `HAVE_FRAMEWORK_`.

For example, if `have_framework('Ruby')` returned true, then the `HAVE_FRAMEWORK_RUBY` preprocessor macro would be passed to the compiler.

If `fw` is a pair of the framework name and its header file name that header file is checked, instead of the normally used header file which is named same as the framework.

have_func (func, headers = nil, opt = "", &b)
Source

    # File lib/mkmf.rb, line 1198
    def have_func(func, headers = nil, opt = "", &b)
      checking_for checking_message(func.funcall_style, headers, opt) do
        if try_func(func, $libs, headers, opt, &b)
          $defs << "-DHAVE_#{func.sans_arguments.tr_cpp}"
          true
        else
          false
        end
      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_`.

To check functions in an additional library, you need to check that library first using `have_library()`. The `func` shall be either mere function name or function name with arguments.

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

have_header (header, preheaders = nil, opt = "", &b)
Source

    # File lib/mkmf.rb, line 1238
    def have_header(header, preheaders = nil, opt = "", &b)
      dir_config(header[/.*?(?=\/)|.*?(?=\.)/])
      checking_for header do
        if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
          $defs.push(format("-DHAVE_%s", header.tr_cpp))
          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.

have_library (lib, func = nil, headers = nil, opt = "", &b)
Source

    # File lib/mkmf.rb, line 1138
    def have_library(lib, func = nil, headers = nil, opt = "", &b)
      dir_config(lib)
      lib = with_config(lib+'lib', lib)
      checking_for checking_message(func && func.funcall_style, LIBARG%lib, opt) do
        if COMMON_LIBS.include?(lib)
          true
        else
          libs = append_library($libs, lib)
          if try_func(func, libs, headers, opt, &b)
            $libs = libs
            true
          else
            false
          end
        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`.

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

have_macro (macro, headers = nil, opt = "", &b)
Source

    # File lib/mkmf.rb, line 1121
    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 `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.

have_struct_member (type, member, headers = nil, opt = "", &b)
Source

    # File lib/mkmf.rb, line 1326
      def have_struct_member(type, member, headers = nil, opt = "", &b)
        checking_for checking_message("#{type}.#{member}", headers) do
          if try_compile(<<"SRC", opt, &b)
    #{cpp_include(headers)}
    /*top*/
    int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
    #{MAIN_DOES_NOTHING}
    SRC
            $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
            $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility
            true
          else
            false
          end
        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 type name and the member name, in uppercase, prepended with `HAVE_`.

For example, if `have_struct_member('struct foo', 'bar')` returned true, then the `HAVE_STRUCT_FOO_BAR` preprocessor macro would be passed to the compiler.

`HAVE_ST_BAR` is also defined for backward compatibility.

have_var (var, headers = nil, opt = "", &b)
Source

    # File lib/mkmf.rb, line 1220
    def have_var(var, headers = nil, opt = "", &b)
      checking_for checking_message(var, headers, opt) do
        if try_var(var, headers, opt, &b)
          $defs.push(format("-DHAVE_%s", var.tr_cpp))
          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_`.

To check variables in an additional library, you need to check that library first using `have_library()`.

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

log_src (src, heading="checked program was")
Source

    # File lib/mkmf.rb, line 472
      def log_src(src, heading="checked program was")
        src = src.split(/^/)
        fmt = "%#{src.size.to_s.size}d: %s"
        Logging::message <<"EOM"
    #{heading}:
    /* begin */
    EOM
        src.each_with_index {|line, no| Logging::message fmt, no+1, line}
        Logging::message <<"EOM"
    /* end */

    EOM
      end

Logs src

modified? (target, times)
Source

    # File lib/mkmf.rb, line 285
    def modified?(target, times)
      (t = File.mtime(target)) rescue return nil
      Array === times or times = [times]
      t if times.all? {|n| n <= t}
    end

Returns time stamp of the `target` file if it exists and is newer than or equal to all of `times`.

pkg_config (pkg, *options)
Source

    # File lib/mkmf.rb, line 1952
    def pkg_config(pkg, *options)
      fmt = "not found"
      def fmt.%(x)
        x ? x.inspect : self
      end

      checking_for "pkg-config for #{pkg}", fmt do
        _, ldir = dir_config(pkg)
        if ldir
          pkg_config_path = "#{ldir}/pkgconfig"
          if File.directory?(pkg_config_path)
            Logging.message("PKG_CONFIG_PATH = %s\n", pkg_config_path)
            envs = ["PKG_CONFIG_PATH"=>[pkg_config_path, ENV["PKG_CONFIG_PATH"]].compact.join(File::PATH_SEPARATOR)]
          end
        end
        if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
        # if and only if package specific config command is given
        elsif ($PKGCONFIG ||=
               (pkgconfig = with_config("pkg-config") {config_string("PKG_CONFIG") || ENV["PKG_CONFIG"] || "pkg-config"}) &&
               find_executable0(pkgconfig) && pkgconfig) and
             xsystem([*envs, $PKGCONFIG, "--exists", pkg])
          # default to pkg-config command
          pkgconfig = $PKGCONFIG
          args = [pkg]
        elsif find_executable0(pkgconfig = "#{pkg}-config")
        # default to package specific config command, as a last resort.
        else
          pkgconfig = nil
        end
        if pkgconfig
          get = proc {|opts|
            opts = Array(opts).map { |o| "--#{o}" }
            opts = xpopen([*envs, pkgconfig, *opts, *args], err:[:child, :out], &:read)
            Logging.open {puts opts.each_line.map{|s|"=> #{s.inspect}"}}
            if $?.success?
              opts = opts.strip
              libarg, libpath = LIBARG, LIBPATHFLAG.strip
              opts = opts.shellsplit.map { |s|
                if s.start_with?('-l')
                  libarg % s[2..]
                elsif s.start_with?('-L')
                  libpath % s[2..]
                else
                  s
                end
              }.quote.join(" ")
              opts
            end
          }
        end
        orig_ldflags = $LDFLAGS
        if get and !options.empty?
          get[options]
        elsif get and try_ldflags(ldflags = get['libs'])
          if incflags = get['cflags-only-I']
            $INCFLAGS << " " << incflags
            cflags = get['cflags-only-other']
          else
            cflags = get['cflags']
          end
          libs = get['libs-only-l']
          if cflags
            $CFLAGS += " " << cflags
            $CXXFLAGS += " " << cflags
          end
          if libs
            ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
          else
            libs, ldflags = Shellwords.shellwords(ldflags).partition {|s| s =~ /-l([^ ]+)/ }.map {|l|l.quote.join(" ")}
          end
          $libs += " " << libs

          $LDFLAGS = [orig_ldflags, ldflags].join(' ')
          Logging::message "package configuration for %s\n", pkg
          Logging::message "incflags: %s\ncflags: %s\nldflags: %s\nlibs: %s\n\n",
                           incflags, cflags, ldflags, libs
          [[incflags, cflags].join(' '), ldflags, libs]
        else
          Logging::message "package configuration for %s is not found\n", pkg
          nil
        end
      end
    end

Returns compile/link information about an installed library in a tuple of `[cflags, ldflags, libs]`, by using the command found first in the following commands:

1. If `--with-{pkg}-config={command}` is given via command line option: `{command} {options}`

2. `{pkg}-config {options}`

3. `pkg-config {options} {pkg}`

Where `options` is the option name without dashes, for instance `"cflags"` for the `--cflags` flag.

The values obtained are appended to `$INCFLAGS`, `$CFLAGS`, `$LDFLAGS` and `$libs`.

If one or more `options` argument is given, the config command is invoked with the options and a stripped output string is returned without modifying any of the global values mentioned above.

what_type? (type, member = nil, headers = nil, &b)
Source

    # File lib/mkmf.rb, line 1624
    def what_type?(type, member = nil, headers = nil, &b)
      m = "#{type}"
      var = val = "*rbcv_var_"
      func = "rbcv_func_(void)"
      if member
        m << "." << member
      else
        type, member = type.split('.', 2)
      end
      if member
        val = "(#{var}).#{member}"
      end
      prelude = [cpp_include(headers).split(/^/)]
      prelude << ["typedef #{type} rbcv_typedef_;\n",
                  "extern rbcv_typedef_ *#{func};\n",
                  "rbcv_typedef_ #{var};\n",
                 ]
      type = "rbcv_typedef_"
      fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s"
      if typeof
        var = "*rbcv_member_"
        func = "rbcv_mem_func_(void)"
        member = nil
        type = "rbcv_mem_typedef_"
        prelude[-1] << "typedef #{typeof}(#{val}) #{type};\n"
        prelude[-1] << "extern #{type} *#{func};\n"
        prelude[-1] << "#{type} #{var};\n"
        val = var
      end
      def fmt.%(x)
        x ? super : "unknown"
      end
      checking_for checking_message(m, headers), fmt do
        if scalar_ptr_type?(type, member, prelude, &b)
          if try_static_assert("sizeof(*#{var}) == 1", prelude)
            return "string"
          end
          ptr = "*"
        elsif scalar_type?(type, member, prelude, &b)
          unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude)
            unsigned = "unsigned"
          end
          ptr = ""
        else
          next
        end
        type = UNIVERSAL_INTS.find do |t|
          pre = prelude
          unless member
            pre += [["#{unsigned} #{t} #{ptr}#{var};\n",
                     "extern #{unsigned} #{t} #{ptr}*#{func};\n"]]
          end
          try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre)
        end
        type or next
        [unsigned, type, ptr].join(" ").strip
      end
    end

Returns a string represents the type of type, or member of type if member is not `nil`.

with_config (config, default=nil) { |config, default| ... }
Source

    # File lib/mkmf.rb, line 1767
    def with_config(config, default=nil)
      config = config.sub(/^--with[-_]/, '')
      val = arg_config("--with-"+config) do
        if arg_config("--without-"+config)
          false
        elsif block_given?
          yield(config, default)
        else
          break default
        end
      end
      case val
      when "yes"
        true
      when "no"
        false
      else
        val
      end
    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

with_cppflags (flags) { || ... }
Source

    # File lib/mkmf.rb, line 695
    def with_cppflags(flags)
      cppflags = $CPPFLAGS
      $CPPFLAGS = flags.dup
      ret = yield
    ensure
      $CPPFLAGS = cppflags unless ret
    end

Sets `$CPPFLAGS` to flags and yields. If the block returns a falsy value, `$CPPFLAGS` is reset to its previous value, remains set to flags otherwise.

`flags`

  a C preprocessor flag as a `String`

xpopen (command, *mode, &block)
Source

    # File lib/mkmf.rb, line 457
    def xpopen command, *mode, &block
      env, commands = expand_command(command)
      command = [env_quote(env), command].join(' ')
      Logging::open do
        case mode[0]
        when nil, Hash, /^r/
          puts "#{command} |"
        else
          puts "| #{command}"
        end
        IO.popen(env, commands, *mode, &block)
      end
    end

Executes command similarly to xsystem, but yields opened pipe.

xsystem(command, werror: false) → true or false
Source

    # File lib/mkmf.rb, line 438
    def xsystem(command, werror: false)
      env, command = expand_command(command)
      Logging::open do
        puts [env_quote(env), command.quote].join(' ')
        if werror
          result = nil
          Logging.postpone do |log|
            output = IO.popen(env, command, &:read)
            result = ($?.success? and File.zero?(log.path))
            output
          end
          result
        else
          system(env, *command)
        end
      end
    end

Executes command with expanding variables, and returns the exit status like as `Kernel#system`. If werror is true and the error output is not empty, returns `false`. The output will logged.

### Private Instance Methods

rm_f (*files)
Source

    # File lib/mkmf.rb, line 270
    def rm_f(*files)
      opt = (Hash === files.last ? [files.pop] : [])
      FileUtils.rm_f(Dir[*files.flatten], *opt)
    end

Removes files.

rm_rf (*files)
Source

    # File lib/mkmf.rb, line 277
    def rm_rf(*files)
      opt = (Hash === files.last ? [files.pop] : [])
      FileUtils.rm_rf(Dir[*files.flatten], *opt)
    end

Removes files recursively.