Module: MakeMakefile
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Defined in: | lib/mkmf.rb |
Overview
mkmf.rb 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.
Constant Summary
-
ASSEMBLE_C =
Command which will translate C files to assembler sources in the generated Makefile
config_string('ASSEMBLE_C') || COMPILE_C.sub(/(?<=\s)-c(?=\s)/, '-S')
-
ASSEMBLE_CXX =
Command which will translate C++ files to assembler sources in the generated Makefile
config_string('ASSEMBLE_CXX') || COMPILE_CXX.sub(/(?<=\s)-c(?=\s)/, '-S')
-
CLEANINGS =
Makefile rules that will clean the extension build directory
" clean-static:: clean-rb-default:: clean-rb:: clean-so:: clean: clean-so clean-static clean-rb-default clean-rb \t\t-$(Q)$(RM_RF) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) .*.time distclean-rb-default:: distclean-rb:: distclean-so:: distclean-static:: distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb \t\t-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) #{CONFTEST}.* mkmf.log#{' exts.mk' if $extmk} \t\t-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep}) \t\t-$(Q)$(RMDIRS) $(DISTCLEANDIRS#{sep})#{$ignore_error} realclean: distclean "
-
COMMON_HEADERS =
Common headers for Ruby C extensions
hdr.join("\n")
-
COMMON_LIBS =
Common libraries for Ruby C extensions
config_string('COMMON_LIBS', &split) || []
-
COMPILE_C =
Command which will compile C files in the generated Makefile
config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<'
-
COMPILE_CXX =
Command which will compile C++ files in the generated Makefile
config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<'
-
COMPILE_RULES =
make compile rules
config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
-
CONFIG =
The makefile configuration using the defaults from when Ruby was built.
RbConfig::MAKEFILE_CONFIG
-
CONFTEST =
Internal use only
# File 'lib/mkmf.rb', line 260"conftest".freeze
-
CONFTEST_C =
Internal use only
# File 'lib/mkmf.rb', line 261"#{CONFTEST}.c"
-
COUTFLAG =
Internal use only
# File 'lib/mkmf.rb', line 264 -
CPPOUTFILE =
Internal use only
# File 'lib/mkmf.rb', line 266config_string('CPPOUTFILE') {|str| str.sub(/\bconftest\b/, CONFTEST)}
-
CSRCFLAG =
Internal use only
# File 'lib/mkmf.rb', line 265 -
CXX_EXT =
Extensions for files compiled with a C++ compiler
%w[cc mm cxx cpp]
-
C_EXT =
Extensions for files compiled with a C compiler
%w[c m]
-
EXPORT_PREFIX =
The prefix added to exported symbols automatically
config_string('EXPORT_PREFIX') {|s| s.strip}
-
FailedMessage =
Internal use only
# File 'lib/mkmf.rb', line 2757<<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
-
HDR_EXT =
Extensions for header files
%w[h hpp]
-
INSTALL_DIRS =
Internal use only
# File 'lib/mkmf.rb', line 169[ [dir_re('commondir'), "$(RUBYCOMMONDIR)"], [dir_re('sitedir'), "$(RUBYCOMMONDIR)"], [dir_re('vendordir'), "$(RUBYCOMMONDIR)"], [dir_re('rubylibdir'), "$(RUBYLIBDIR)"], [dir_re('archdir'), "$(RUBYARCHDIR)"], [dir_re('sitelibdir'), "$(RUBYLIBDIR)"], [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"], [dir_re('sitearchdir'), "$(RUBYARCHDIR)"], [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"], [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"], [dir_re('sitehdrdir'), "$(SITEHDRDIR)"], [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"], [dir_re('bindir'), "$(BINDIR)"], ]
-
LANGUAGE =
The language that this module is for
-"C"
-
LIBARG =
Argument which will add a library to the linker
config_string('LIBARG') || '-l%s'
-
LIBPATHFLAG =
Argument which will add a library path to the linker
config_string('LIBPATHFLAG') || '-L%s'
-
LINK_SO =
Command which will link a shared library
(config_string('LINK_SO') || "").sub(/^$/) do if CONFIG["DLEXT"] == $OBJEXT "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n" else "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \ "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)" end end
-
MAIN_DOES_NOTHING =
A C main function which does no work
config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return !!argv[argc];\n}"
-
ORIG_LIBPATH =
The saved original value of
LIB
environment variableENV['LIB']
-
OUTFLAG =
Internal use only
# File 'lib/mkmf.rb', line 263 -
RPATHFLAG =
Argument which will add a runtime library path to the linker
config_string('RPATHFLAG') || ''
-
RULE_SUBST =
Substitution in rules for NMake
config_string('RULE_SUBST')
-
RbConfig =
The RbConfig for the target platform where the built extension runs.
::RbConfig
-
SRC_EXT =
Extensions for source files
C_EXT + CXX_EXT
-
STRING_OR_FAILED_FORMAT =
Internal use only
# File 'lib/mkmf.rb', line 1445"%s"
-
TRY_LINK =
Command which will compile a program in order to test linking a library
config_string('TRY_LINK') || "$(CC) #{OUTFLAG}#{CONFTEST}#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \ "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
-
UNIVERSAL_INTS =
The type names for convertible_int
config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} || %w[int short long long\ long]
Class Method Summary
-
.rm_f(*files)
mod_func
Removes files.
-
.rm_rf(*files)
mod_func
Removes files recursively.
-
.[](name)
private
Retrieves the module for name language.
-
.[]=(name, mod)
private
Defines the module for name language.
- .config_string(key, config = CONFIG) mod_func Internal use only
- .dir_re(dir) mod_func Internal use only
Instance Attribute Summary
- #have_devel? ⇒ Boolean readonly Internal use only
-
#have_typeof? ⇒ Boolean
readonly
Internal use only
Used internally by the what_type? method to check if the typeof GCC extension is available.
Instance Method Summary
-
#append_cflags(flags, **opts)
Check whether each given C compiler flag is acceptable and append it to
$CFLAGS
if so. -
#append_cppflags(flags, **opts)
Check whether each given C preprocessor flag is acceptable and append it to
$CPPFLAGS
if so. -
#append_ldflags(flags, **opts)
Check whether each given linker flag is acceptable and append it to
$LDFLAGS
if so. -
#check_signedness(type, headers = nil, opts = nil, &b)
Returns the signedness of the given
type
. -
#check_sizeof(type, headers = nil, opts = "", &b)
Returns the size of the given
type
. -
#conftest_source
Returns the language-dependent source file name for configuration checks.
-
#convertible_int(type, headers = nil, opts = nil, &b)
Returns the convertible integer type of the given
type
. -
#create_header(header = "extconf.h")
Generates a header file consisting of the various macro definitions generated by other methods such as have_func and have_header.
-
#create_makefile(target, srcprefix = nil)
Generates the Makefile for your extension, passing along any options and preprocessor constants that you may have generated through other methods.
-
#create_tmpsrc(src)
Creats temporary source file from COMMON_HEADERS and src.
-
#depend_rules(depend)
Processes the data contents of the “depend” file.
-
#dir_config(target)
Sets a
target
name that the user can then use to configure various “with” options with on the command line by using that name. -
#dummy_makefile(srcdir)
Creates a stub Makefile.
-
#egrep_cpp(pat, src, opt = "", &b)
Returns whether or not the
src
can be preprocessed with the C preprocessor and matches withpat
. -
#enable_config(config, default = nil)
Tests for the presence of an
--enable-
config or--disable-
config option. -
#find_executable(bin, path = nil)
Searches for the executable
bin
onpath
. -
#find_header(header, *paths)
Instructs mkmf to search for the given
header
in any of thepaths
provided, and returns whether or not it was found in those paths. -
#find_library(lib, func, *paths, &b)
Returns whether or not the entry point
func
can be found within the librarylib
in one of thepaths
specified, wherepaths
is an array of strings. -
#find_type(type, opt, *headers, &b)
Returns where the static type
type
is defined. -
#have_const(const, headers = nil, opt = "", &b)
Returns whether or not the constant
const
is defined. -
#have_framework(fw, &b)
Returns whether or not the given
framework
can be found on your system. -
#have_func(func, headers = nil, opt = "", &b)
Returns whether or not the function
func
can be found in the common header files, or within anyheaders
that you provide. -
#have_header(header, preheaders = nil, opt = "", &b)
Returns whether or not the given
header
file can be found on your system. -
#have_library(lib, func = nil, headers = nil, opt = "", &b)
Returns whether or not the given entry point
func
can be found withinlib
. -
#have_macro(macro, headers = nil, opt = "", &b)
Returns whether or not
macro
is defined either in the common header files or within anyheaders
you provide. -
#have_struct_member(type, member, headers = nil, opt = "", &b)
Returns whether or not the struct of type
type
containsmember
. -
#have_type(type, headers = nil, opt = "", &b)
Returns whether or not the static type
type
is defined. -
#have_var(var, headers = nil, opt = "", &b)
Returns whether or not the variable
var
can be found in the common header files, or within anyheaders
that you provide. -
#log_src(src, heading = "checked program was")
Logs src.
-
#modified?(target, times) ⇒ Boolean
Returns time stamp of the
target
file if it exists and is newer than or equal to all oftimes
. -
#pkg_config(pkg, *options)
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: -
#what_type?(type, member = nil, headers = nil, &b) ⇒ Boolean
Returns a string represents the type of type, or member of type if member is not
nil
. -
#with_cflags(flags)
Sets
$CFLAGS
to flags and yields. -
#with_config(config, default = nil)
Tests for the presence of a
--with-
config or--without-
config option. -
#with_cppflags(flags)
Sets
$CPPFLAGS
to flags and yields. -
#with_ldflags(flags)
Sets
$LDFLAGS
to flags and yields. -
#xpopen(command, *mode, &block)
Executes command similarly to xsystem, but yields opened pipe.
-
#xsystem(command, werror: false) ⇒ Boolean
Executes command with expanding variables, and returns the exit status like as
Kernel.system
. -
#append_library(libs, lib)
Internal use only
:no-doc:
- #arg_config(config, default = nil, &block) Internal use only
- #cc_command(opt = "") Internal use only
- #cc_config(opt = "") Internal use only
-
#checking_for(m, fmt = nil)
Internal use only
This emits a string to stdout that allows users to see the results of the various have* and find* methods as they are tested.
-
#checking_message(target, place = nil, opt = nil)
Internal use only
Build a message for checking.
- #configuration(srcdir) Internal use only
- #cpp_command(outfile, opt = "") Internal use only
- #cpp_include(header) Internal use only
- #each_compile_rules Internal use only
- #env_quote(envs) Internal use only
- #expand_command(commands, envs = libpath_env) Internal use only
-
#find_executable0(bin, path = nil)
Internal use only
This method is used internally by the find_executable method.
- #init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG) Internal use only
- #install_dirs(target_prefix = nil) Internal use only
- #install_files(mfile, ifiles, map = nil, srcprefix = nil) Internal use only
- #install_rb(mfile, dest, srcdir = nil) Internal use only
- #libpath_env Internal use only
- #libpathflag(libpath = $DEFLIBPATH|$LIBPATH) Internal use only
- #link_command(ldflags, *opts) Internal use only
- #link_config(ldflags, opt = "", libpath = $DEFLIBPATH|$LIBPATH) Internal use only
-
#macro_defined?(macro, src, opt = "", &b) ⇒ Boolean
Internal use only
This is used internally by the have_macro? method.
- #map_dir(dir, map = nil) Internal use only
- #merge_libs(*libs) Internal use only
-
#message(*s)
Internal use only
Prints messages to $stdout, if verbose mode.
- #mkintpath(path) Internal use only
-
#mkmf_failed(path)
Internal use only
Returns whether or not the Makefile was successfully generated.
- #relative_from(path, base) Internal use only
-
#scalar_ptr_type?(type, member = nil, headers = nil, &b) ⇒ Boolean
Internal use only
Used internally by the what_type? method to determine if
type
is a scalar pointer. -
#scalar_type?(type, member = nil, headers = nil, &b) ⇒ Boolean
Internal use only
Used internally by the what_type? method to determine if
type
is a scalar pointer. - #split_libs(*strs) Internal use only
- #timestamp_file(name, target_prefix = nil) Internal use only
- #try_cflags(flags, werror: true, **opts) Internal use only
-
#try_compile(src, opt = "", werror: nil, **opts, &b)
(also: #try_header)
Internal use only
Returns whether or not the
src
can be compiled as a C source. -
#try_const(const, headers = nil, opt = "", &b)
Internal use only
Returns whether or not the constant
const
is defined. - #try_constant(const, headers = nil, opt = "", &b) Internal use only
-
#try_cpp(src, opt = "", **opts, &b)
Internal use only
Returns whether or not the
src
can be preprocessed with the C preprocessor. - #try_cppflags(flags, werror: true, **opts) Internal use only
- #try_do(src, command, **opts, &b) Internal use only
-
#try_func(func, libs, headers = nil, opt = "", &b)
Internal use only
You should use #have_func rather than #try_func.
-
#try_header(src, opt = "", werror: nil, **opts, &b)
Internal use only
Alias for #try_compile.
- #try_ldflags(flags, werror: $mswin, **opts) Internal use only
-
#try_link(src, opt = "", **opts, &b)
Internal use only
Returns whether or not the
src
can be compiled as a C source and linked with its depending libraries successfully. - #try_link0(src, opt = "", **opts, &b) Internal use only
-
#try_run(src, opt = "", &b)
Internal use only
Returns whether or not: * the
src
can be compiled as a C source, * the result object can be linked with its depending libraries. - #try_signedness(type, member, headers = nil, opts = nil) Internal use only
- #try_static_assert(expr, headers = nil, opt = "", &b) Internal use only
-
#try_type(type, headers = nil, opt = "", &b)
Internal use only
Returns whether or not the static type
type
is defined. - #try_var(var, headers = nil, opt = "", &b) Internal use only
- #typedef_expr(type, headers) Internal use only
- #werror_flag(opt = nil) Internal use only
-
#winsep(s)
Internal use only
Converts forward slashes to backslashes.
- #with_destdir(dir) Internal use only
- #with_werror(opt, opts = nil) {|opt, opts| ... } Internal use only
- #_libdir_basename private Internal use only
- MAIN_DOES_NOTHING(*refs) private Internal use only
Class Method Details
.[](name) (private)
Retrieves the module for name language.
# File 'lib/mkmf.rb', line 2962
def self.[](name) @lang.fetch(name) end
.[]=(name, mod) (private)
Defines the module for name language.
# File 'lib/mkmf.rb', line 2968
def self.[]=(name, mod) @lang[name] = mod end
.config_string(key, config = CONFIG) (mod_func)
# File 'lib/mkmf.rb', line 150
def config_string(key, config = CONFIG) s = config[key] and !s.empty? and block_given? ? yield(s) : s end
.dir_re(dir) (mod_func)
# File 'lib/mkmf.rb', line 155
def dir_re(dir) Regexp.new('\$(?:\('dir'\)|\{'dir'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?') end
.rm_f(*files) (mod_func)
Removes files.
# File 'lib/mkmf.rb', line 271
def rm_f(*files) opt = (Hash === files.last ? [files.pop] : []) FileUtils.rm_f(Dir[*files.flatten], *opt) end
.rm_rf(*files) (mod_func)
Removes files recursively.
# File 'lib/mkmf.rb', line 278
def rm_rf(*files) opt = (Hash === files.last ? [files.pop] : []) FileUtils.rm_rf(Dir[*files.flatten], *opt) end
Instance Attribute Details
#have_devel? ⇒ Boolean
(readonly)
# File 'lib/mkmf.rb', line 518
def have_devel? unless defined? $have_devel $have_devel = true $have_devel = try_link(MAIN_DOES_NOTHING) end $have_devel end
#have_typeof? ⇒ Boolean
(readonly)
Used internally by the what_type? method to check if the typeof GCC extension is available.
# File 'lib/mkmf.rb', line 1611
def have_typeof? return $typeof if defined?($typeof) $typeof = %w[__typeof__ typeof].find do |t| try_compile(<<SRC) int rbcv_foo; #{t}(rbcv_foo) rbcv_bar; SRC end end
Instance Method Details
#_libdir_basename (private)
# File 'lib/mkmf.rb', line 2779
def _libdir_basename @libdir_basename ||= config_string("libdir") {|name| name[/\A\$\(exec_prefix\)\/(.*)/, 1]} || "lib" end
#append_cflags(flags, **opts)
# File 'lib/mkmf.rb', line 1107
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
#append_cppflags(flags, **opts)
# File 'lib/mkmf.rb', line 714
def append_cppflags(flags, **opts) Array(flags).each do |flag| if checking_for("whether #{flag} is accepted as CPPFLAGS") { try_cppflags(flag, **opts) } $CPPFLAGS << " " << flag end end end
#append_ldflags(flags, **opts)
# File 'lib/mkmf.rb', line 763
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
#append_library(libs, lib)
:no-doc:
# File 'lib/mkmf.rb', line 1040
def append_library(libs, lib) # :no-doc: format(LIBARG, lib) + " " + libs end
#arg_config(config, default = nil, &block)
# File 'lib/mkmf.rb', line 1741
def arg_config(config, default=nil, &block) $arg_config << [config, default] defaults = [] if default defaults << default elsif !block defaults << nil end $configure_args.fetch(config.tr('_', '-'), *defaults, &block) end
#cc_command(opt = "")
# File 'lib/mkmf.rb', line 570
def cc_command(opt="") conf = cc_config(opt) RbConfig:: ("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", conf) end
#cc_config(opt = "")
#check_signedness(type, headers = nil, opts = nil, &b)
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</code> preprocessor macro would be passed to the compiler. The SIGNEDNESS_OF_INT=-1
macro would be set for check_signedness('int')
# File 'lib/mkmf.rb', line 1510
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
#check_sizeof(type, headers = nil, opts = "", &b)
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 1481
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 ("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
#checking_for(m, fmt = nil)
This emits a string to stdout that allows users to see the results of the various have* and find* methods as they are tested.
Internal use only.
# File 'lib/mkmf.rb', line 1060
def checking_for(m, fmt = nil) if f = caller_locations(1, 1).first.base_label and /\A\w/ =~ f f += ": " else f = "" end m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... " "%s", m a = r = nil Logging::postpone do r = yield a = (fmt ? "#{fmt % r}" : r ? "yes" : "no") "#{f}#{m}-------------------- #{a}\n\n" end "%s\n", a Logging:: "--------------------\n\n" r end
#checking_message(target, place = nil, opt = nil)
Build a message for checking.
Internal use only.
# File 'lib/mkmf.rb', line 1083
def (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 unless noun.empty? msg << " #{pre} " unless msg.empty? msg << noun end end msg end end
#configuration(srcdir)
# File 'lib/mkmf.rb', line 2068
def configuration(srcdir) mk = [] verbose = with_config('verbose') ? "1" : (CONFIG['MKMF_VERBOSE'] || "0") vpath = $VPATH.dup CONFIG["hdrdir"] ||= $hdrdir mk << %{ SHELL = /bin/sh # V=0 quiet, V=1 verbose. other values don't work. V = #{verbose} V0 = $(V:0=) Q1 = $(V:1=) Q = $(Q1:0=@) ECHO1 = $(V:1=@ #{CONFIG['NULLCMD']}) ECHO = $(ECHO1:0=@ echo) NULLCMD = #{CONFIG['NULLCMD']} #### Start of system configuration section. #### #{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk} srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2]).unspace}} topdir = #{mkintpath(topdir = $extmk ? CONFIG["topdir"] : $topdir).unspace} hdrdir = #{(hdrdir = CONFIG["hdrdir"]) == topdir ? "$(topdir)" : mkintpath(hdrdir).unspace} arch_hdrdir = #{mkintpath($arch_hdrdir).unspace} PATH_SEPARATOR = #{CONFIG['PATH_SEPARATOR']} VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])} } if $extmk mk << "RUBYLIB =\n""RUBYOPT = -\n" end prefix = mkintpath(CONFIG["prefix"]) if destdir = prefix[$dest_prefix_pattern, 1] mk << "\nDESTDIR = #{destdir}\n" prefix = prefix[destdir.size..-1] end mk << "prefix = #{with_destdir(prefix).unspace}\n" CONFIG.each do |key, var| mk << "#{key} = #{with_destdir(mkintpath(var)).unspace}\n" if /.prefix$/ =~ key end CONFIG.each do |key, var| next if /^abs_/ =~ key next if /^(?:src|top(?:_src)?|build|hdr)dir$/ =~ key next unless /dir$/ =~ key 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 possible_command = (proc {|s| s if /top_srcdir|tooldir/ !~ s} unless $extmk) extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ") << " " headers = %w[ $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h ] headers += $headers if RULE_SUBST headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))} end headers << $config_h headers << '$(RUBY_EXTCONF_H)' if $extconf_h mk << %{ CC_WRAPPER = #{CONFIG['CC_WRAPPER']} CC = #{CONFIG['CC']} CXX = #{CONFIG['CXX']} LIBRUBY = #{CONFIG['LIBRUBY']} LIBRUBY_A = #{CONFIG['LIBRUBY_A']} LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC empty = OUTFLAG = #{OUTFLAG}$(empty) COUTFLAG = #{COUTFLAG}$(empty) CSRCFLAG = #{CSRCFLAG}$(empty) RUBY_EXTCONF_H = #{$extconf_h} cflags = #{CONFIG['cflags']} cxxflags = #{CONFIG['cxxflags']} optflags = #{CONFIG['optflags']} debugflags = #{CONFIG['debugflags']} warnflags = #{$warnflags} cppflags = #{CONFIG['cppflags']} CCDLFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} CFLAGS = $(CCDLFLAGS) #$CFLAGS $(ARCH_FLAG) INCFLAGS = -I. #$INCFLAGS DEFS = #{CONFIG['DEFS']} CPPFLAGS = #{extconf_h}#{$CPPFLAGS} CXXFLAGS = $(CCDLFLAGS) #$CXXFLAGS $(ARCH_FLAG) ldflags = #{$LDFLAGS} dldflags = #{$DLDFLAGS} #{CONFIG['EXTDLDFLAGS']} ARCH_FLAG = #{$ARCH_FLAG} DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) LDSHARED = #{CONFIG['LDSHARED']} LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'} POSTLINK = #{config_string('POSTLINK', RbConfig::CONFIG)} AR = #{CONFIG['AR']} LD = #{CONFIG['LD']} EXEEXT = #{CONFIG['EXEEXT']} } CONFIG.each do |key, val| mk << "#{key} = #{val}\n" if /^RUBY.*NAME/ =~ key end mk << %{ arch = #{CONFIG['arch']} sitearch = #{CONFIG['sitearch']} ruby_version = #{RbConfig::CONFIG['ruby_version']} ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}} RUBY = $(ruby#{sep}) BUILTRUBY = #{if defined?($builtruby) && $builtruby $builtruby else File.join('$(bindir)', CONFIG["RUBY_INSTALL_NAME"] + CONFIG['EXEEXT']) end} ruby_headers = #{headers.join(' ')} RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'} RM_RF = #{config_string('RMALL', &possible_command) || '$(RUBY) -run -e rm -- -rf'} RMDIRS = #{config_string('RMDIRS', &possible_command) || '$(RUBY) -run -e rmdir -- -p'} MAKEDIRS = #{config_string('MAKEDIRS', &possible_command) || '@$(RUBY) -run -e mkdir -- -p'} INSTALL = #{config_string('INSTALL', &possible_command) || '@$(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', &possible_command) || '@$(RUBY) -run -e cp -- -v'} TOUCH = exit > #### End of system configuration section. #### preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''} } mk end
#conftest_source
Returns the language-dependent source file name for configuration checks.
# File 'lib/mkmf.rb', line 489
def conftest_source CONFTEST_C end
#convertible_int(type, headers = nil, opts = nil, &b)
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 thetype
name, followed by=X
where “X” is the found convertible type name. -
TYP2NUM
andNUM2TYP
, whereTYP
is thetype
name in uppercase with replacing an_t
suffix with “T”, followed by=X
where “X” is the macro name to converttype
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
# File 'lib/mkmf.rb', line 1545
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
#cpp_command(outfile, opt = "")
# File 'lib/mkmf.rb', line 576
def cpp_command(outfile, opt="") conf = cc_config(opt) if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty? conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s\S/, '') end RbConfig:: ("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}", conf) end
#cpp_include(header)
#create_header(header = "extconf.h")
Generates a header file consisting of the various macro definitions generated by other methods such as have_func and have_header. These are then wrapped in a custom #ifndef
based on the header
file name, which defaults to “extconf.h”.
For example:
# extconf.rb
require 'mkmf'
have_func('realpath')
have_header('sys/utime.h')
create_header
create_makefile('foo')
The above script would generate the following extconf.h file:
#ifndef EXTCONF_H
#define EXTCONF_H
#define HAVE_REALPATH 1
#define HAVE_SYS_UTIME_H 1
#endif
Given that the create_header method generates a file based on definitions set earlier in your extconf.rb file, you will probably want to make this one of the last methods you call in your script.
# File 'lib/mkmf.rb', line 1841
def create_header(header = "extconf.h") "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
#create_makefile(target, srcprefix = nil)
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
.
# File 'lib/mkmf.rb', line 2371
def create_makefile(target, srcprefix = nil) $target = target libpath = $DEFLIBPATH|$LIBPATH "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. (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)"] 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)': ''}")} end conf << "\ TARGET_SO_DIR =#{$extout ? " $(RUBYARCHDIR)/" : ''} TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) CLEANLIBS = #{'$(TARGET_SO) ' if target}#{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}} CLEANOBJS = #{cleanobjs.join(' ')} *.bak TARGET_SO_DIR_TIMESTAMP = #{ (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+)(\))/) {$1sep$2} s.gsub(/(\$\{\w+)(\})/) {$1sep$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}: #{ (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} #{ (dir, target_prefix)}\n") mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D)\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 = (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 = (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
#create_tmpsrc(src)
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.
# File 'lib/mkmf.rb', line 496
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
#depend_rules(depend)
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.
# File 'lib/mkmf.rb', line 2256
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
#dir_config(target)
#dir_config(target, prefix)
#dir_config(target, idefault, ldefault)
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.
# File 'lib/mkmf.rb', line 1891
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
#dummy_makefile(srcdir)
Creates a stub Makefile.
# File 'lib/mkmf.rb', line 2225
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
#each_compile_rules
# File 'lib/mkmf.rb', line 2238
def each_compile_rules # :nodoc: vpath_splat = /\$\(\*VPATH\*\)/ COMPILE_RULES.each do |rule| if vpath_splat =~ rule $VPATH.each do |path| yield rule.sub(vpath_splat) {path} end else yield rule end end end
#egrep_cpp(pat, src, opt = "", &b)
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.
# File 'lib/mkmf.rb', line 924
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
#enable_config(config, default = nil)
Tests for the presence of an --enable-
config or --disable-
config option. Returns true
if the enable option is given, false
if the disable option is given, and the default value otherwise.
This can be useful for adding custom definitions, such as debug information.
Example:
if enable_config("debug")
$defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
end
# File 'lib/mkmf.rb', line 1803
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
#env_quote(envs)
# File 'lib/mkmf.rb', line 427
def env_quote(envs) envs.map {|e, v| "#{e}=#{v.quote}"} end
#expand_command(commands, envs = libpath_env)
# File 'lib/mkmf.rb', line 397
def (commands, envs = libpath_env) varpat = /\$\((\w)\)|\$\{(\w)\}/ vars = nil = proc do |command| case command when Array command.map(& ) when String if varpat =~ command vars ||= Hash.new {|h, k| h[k] = ENV[k]} command = command.dup nil while command.gsub!(varpat) {vars[$1||$2]} end command else command end end if Array === commands env, *commands = commands if Hash === commands.first envs.merge!(env) if env end # disable ASAN leak reporting - conftest programs almost always don't bother # to free their memory. envs['ASAN_OPTIONS'] = "detect_leaks=0" unless ENV.key?('ASAN_OPTIONS') return envs, [commands] end
#find_executable(bin, path = nil)
Searches for the executable bin
on path
. The default path is your PATH
environment variable. If that isn’t defined, it will resort to searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
If found, it will return the full path, including the executable name, of where it was found.
Note that this method does not actually affect the generated Makefile.
# File 'lib/mkmf.rb', line 1733
def find_executable(bin, path = nil) checking_for (bin, path) do find_executable0(bin, path) end end
#find_executable0(bin, path = nil)
This method is used internally by the find_executable method.
Internal use only.
# File 'lib/mkmf.rb', line 1690
def find_executable0(bin, path = nil) executable_file = proc do |name| begin stat = File.stat(name) rescue SystemCallError else next name if stat.file? and stat.executable? end end exts = config_string('EXECUTABLE_EXTS') {|s| s.split} || config_string('EXEEXT') {|s| [s]} if File. (bin) == bin return bin if executable_file.call(bin) if exts exts.each {|ext| executable_file.call(file = bin + ext) and return file} end 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| dir.sub!(/\A"(.*)"\z/m, '\1') if $mswin or $mingw return file if executable_file.call(file = File.join(dir, bin)) if exts exts.each {|ext| executable_file.call(ext = file + ext) and return ext} end end nil end
#find_header(header, *paths)
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 1291
def find_header(header, *paths) = (header, paths) header = cpp_include(header) checking_for 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
#find_library(lib, func, *paths, &b)
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 1165
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 (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
#find_type(type, opt, *headers, &b)
Returns where the static type type
is defined.
You may also pass additional flags to opt
which are then passed along to the compiler.
See also #have_type.
# File 'lib/mkmf.rb', line 1389
def find_type(type, opt, *headers, &b) opt ||= "" fmt = "not found" def fmt.%(x) x ? x.respond_to?(:join) ? x.join(",") : x : self end checking_for (type, nil, opt), fmt do headers.find do |h| try_type(type, h, opt, &b) end end end
#have_const(const, headers = nil, opt = "", &b)
Returns whether or not the constant const
is defined. You may optionally pass the type
of const
as [const, type]
, such as:
have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
You may also pass additional headers
to check against in addition to the common header files, and additional flags to opt
which are then passed along to the compiler.
If found, a macro is passed as a preprocessor constant to the compiler using the type name, in uppercase, prepended with HAVE_CONST_
.
For example, if have_const('foo')
returned true, then the HAVE_CONST_FOO
preprocessor macro would be passed to the compiler.
# File 'lib/mkmf.rb', line 1438
def have_const(const, headers = nil, opt = "", &b) checking_for ([*const].compact.join(' '), headers, opt) do try_const(const, headers, opt, &b) end end
#have_framework(fw, &b)
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.
# File 'lib/mkmf.rb', line 1262
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
#have_func(func, headers = nil, opt = "", &b)
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.
# File 'lib/mkmf.rb', line 1199
def have_func(func, headers = nil, opt = "", &b) checking_for (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
#have_header(header, preheaders = nil, opt = "", &b)
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 1239
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
#have_library(lib, func = nil, headers = nil, opt = "", &b)
Returns whether or not the given entry point func
can be found within lib
. If func
is nil
, the main()
entry point is used by default. If found, it adds the library to list of libraries to be used when linking your extension.
If headers
are provided, it will include those header files as the header files it looks in when searching for func
.
The real name of the library to be linked can be altered by --with-FOOlib
configuration option.
# File 'lib/mkmf.rb', line 1139
def have_library(lib, func = nil, headers = nil, opt = "", &b) dir_config(lib) lib = with_config(lib+'lib', lib) checking_for (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
#have_macro(macro, headers = nil, opt = "", &b)
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 1122
def have_macro(macro, headers = nil, opt = "", &b) checking_for (macro, headers, opt) do macro_defined?(macro, cpp_include(headers), opt, &b) end end
#have_struct_member(type, member, headers = nil, opt = "", &b)
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.
# File 'lib/mkmf.rb', line 1327
def have_struct_member(type, member, headers = nil, opt = "", &b) checking_for ("#{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
#have_type(type, headers = nil, opt = "", &b)
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 1376
def have_type(type, headers = nil, opt = "", &b) checking_for (type, headers, opt) do try_type(type, headers, opt, &b) end end
#have_var(var, headers = nil, opt = "", &b)
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.
# File 'lib/mkmf.rb', line 1221
def have_var(var, headers = nil, opt = "", &b) checking_for (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
#init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG)
# File 'lib/mkmf.rb', line 2686
def init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG) $makefile_created = false $arg_config = [] $enable_shared = config['ENABLE_SHARED'] == 'yes' $defs = [] $extconf_h = nil $config_dirs = {} if $warnflags = CONFIG['warnflags'] and CONFIG['GCC'] == 'yes' # turn warnings into errors only for bundled extensions. config['warnflags'] = $warnflags.gsub(/(?:\A|\s)-W\Kerror[-=](?!implicit-function-declaration)/, '') if /icc\z/ =~ config['CC'] config['warnflags'].gsub!(/(\A|\s)-W(?:division-by-zero|deprecated-declarations)/, '\1') end RbConfig. (rbconfig['warnflags'] = config['warnflags'].dup) config.each do |key, val| RbConfig. (rbconfig[key] = val.dup) if /warnflags/ =~ val end $warnflags = config['warnflags'] unless $extmk end if (w = rbconfig['CC_WRAPPER']) and !w.empty? and !File.executable?(w) rbconfig['CC_WRAPPER'] = config['CC_WRAPPER'] = '' end $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup $CXXFLAGS = (with_config("cxxflags", arg_config("CXXFLAGS", config["CXXFLAGS"]))||'').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$(arch_hdrdir)" $INCFLAGS << " -I$(hdrdir)/ruby/backward" unless $extmk $INCFLAGS << " -I$(hdrdir) -I$(srcdir)" $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup config_string("ADDITIONAL_DLDFLAGS") {|flags| $DLDFLAGS << " " << flags} unless $extmk $LIBEXT = config['LIBEXT'].dup $OBJEXT = config["OBJEXT"].dup $EXEEXT = config["EXEEXT"].dup $ASMEXT = config_string('ASMEXT', &:dup) || 'S' $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}" $LIBRUBYARG = "" $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC'] $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED'] $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(#{config["libdirname"] || "libdir"})"] $DEFLIBPATH.unshift(".") $LIBPATH = [] $INSTALLFILES = [] $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/] $VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby] $objs = nil $srcs = nil $headers = [] $libs = "" if $enable_shared or RbConfig. (config["LIBRUBY"].dup) != RbConfig. (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)} || [] $distcleandirs = config_string('DISTCLEANDIRS') {|s| Shellwords.shellwords(s)} || [] $extout ||= nil $extout_prefix ||= nil $arg_config.clear $config_dirs.clear dir_config("opt") end
#install_dirs(target_prefix = nil)
# File 'lib/mkmf.rb', line 185
def install_dirs(target_prefix = nil) if $extout and $extmk dirs = [ ['BINDIR', '$(extout)/bin'], ['RUBYCOMMONDIR', '$(extout)/common'], ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'], ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'], ['HDRDIR', '$(extout)/include/ruby$(target_prefix)'], ['ARCHHDRDIR', '$(extout)/include/$(arch)/ruby$(target_prefix)'], ['extout', "#$extout"], ['extout_prefix', "#$extout_prefix"], ] elsif $extmk dirs = [ ['BINDIR', '$(bindir)'], ['RUBYCOMMONDIR', '$(rubylibdir)'], ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'], ['RUBYARCHDIR', '$(archdir)$(target_prefix)'], ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'], ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'], ] elsif $configure_args.has_key?('--vendor') dirs = [ ['BINDIR', '$(bindir)'], ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'], ['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'], ['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'], ['HDRDIR', '$(vendorhdrdir)$(target_prefix)'], ['ARCHHDRDIR', '$(vendorarchhdrdir)$(target_prefix)'], ] else dirs = [ ['BINDIR', '$(bindir)'], ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'], ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'], ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'], ['HDRDIR', '$(sitehdrdir)$(target_prefix)'], ['ARCHHDRDIR', '$(sitearchhdrdir)$(target_prefix)'], ] end dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")] dirs end
#install_files(mfile, ifiles, map = nil, srcprefix = nil)
# File 'lib/mkmf.rb', line 993
def install_files(mfile, ifiles, map = nil, srcprefix = nil) ifiles or return ifiles.empty? and return srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/') RbConfig:: (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 /\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 |fx| f = fx f[0..len] = "" if len case File.basename(f) when *$NONINSTALLFILES next end 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
#install_rb(mfile, dest, srcdir = nil)
# File 'lib/mkmf.rb', line 1036
def install_rb(mfile, dest, srcdir = nil) install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir) end
#libpath_env
# File 'lib/mkmf.rb', line 386
def libpath_env # used only if native compiling if libpathenv = config_string("LIBPATHENV") pathenv = ENV[libpathenv] libpath = RbConfig. ($DEFLIBPATH.join(File::PATH_SEPARATOR)) {libpathenv => [libpath, pathenv].compact.join(File::PATH_SEPARATOR)} else {} end end
#libpathflag(libpath = $DEFLIBPATH|$LIBPATH)
# File 'lib/mkmf.rb', line 585
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH) libpathflags = nil libpath.map{|x| case x when "$(topdir)", /\A\./ LIBPATHFLAG else libpathflags ||= [LIBPATHFLAG, RPATHFLAG].grep(/\S/).join(" ") end % x.quote }.join(" ") end
#link_command(ldflags, *opts)
# File 'lib/mkmf.rb', line 558
def link_command(ldflags, *opts) conf = link_config(ldflags, *opts) RbConfig:: (TRY_LINK.dup, conf) end
#link_config(ldflags, opt = "", libpath = $DEFLIBPATH|$LIBPATH)
# File 'lib/mkmf.rb', line 541
def link_config(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH) librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)" conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'src' => "#{conftest_source}", 'arch_hdrdir' => $arch_hdrdir.quote, 'top_srcdir' => $top_srcdir.quote, 'INCFLAGS' => "#$INCFLAGS", 'CPPFLAGS' => "#$CPPFLAGS", 'CFLAGS' => "#$CFLAGS", 'ARCH_FLAG' => "#$ARCH_FLAG", 'LDFLAGS' => "#$LDFLAGS #{ldflags}", 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs", 'LIBS' => "#{librubyarg} #{opt} #$LIBS") conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig:: (s.dup, conf)}) conf end
#log_src(src, heading = "checked program was")
Logs src
#macro_defined?(macro, src, opt = "", &b) ⇒ Boolean
This is used internally by the have_macro? method.
# File 'lib/mkmf.rb', line 953
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
MAIN_DOES_NOTHING(*refs) (private)
# File 'lib/mkmf.rb', line 2783
def MAIN_DOES_NOTHING(*refs) src = MAIN_DOES_NOTHING unless refs.empty? src = src.sub(/\{/) do $& + "\n if (argc > 1000000) {\n" + refs.map {|n|" int (* volatile #{n}p)(void)=(int (*)(void))&#{n};\n"}.join("") + refs.map {|n|" printf(\"%d\", (*#{n}p)());\n"}.join("") + " }\n" end end src end
#map_dir(dir, map = nil)
# File 'lib/mkmf.rb', line 229
def map_dir(dir, map = nil) map ||= INSTALL_DIRS map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)} end
#merge_libs(*libs)
# File 'lib/mkmf.rb', line 299
def merge_libs(*libs) libs.inject([]) do |x, y| y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e} y.each_with_index do |v, yi| if xi = x.rindex(v) x[(xi+1)..-1] = merge_libs(y[(yi+1)..-1], x[(xi+1)..-1]) x[xi, 0] = y[0...yi] break end end and x.concat(y) x end end
#message(*s)
Prints messages to $stdout, if verbose mode.
Internal use only.
#mkintpath(path)
# File 'lib/mkmf.rb', line 2063
def mkintpath(path) path end
#mkmf_failed(path)
Returns whether or not the Makefile was successfully generated. If not, the script will abort with an error message.
Internal use only.
# File 'lib/mkmf.rb', line 2770
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
#modified?(target, times) ⇒ Boolean
Returns time stamp of the target
file if it exists and is newer than or equal to all of times
.
# File 'lib/mkmf.rb', line 286
def modified?(target, times) (t = File.mtime(target)) rescue return nil Array === times or times = [times] t if times.all? {|n| n <= t} end
#pkg_config(pkg, *options)
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:
-
If
--with-{pkg}-config={command}
is given via command line option:{command} {options}
-
{pkg}-config {options}
-
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.
# File 'lib/mkmf.rb', line 1953
def pkg_config(pkg, * ) 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. ("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") || "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}"}} opts.strip if $?.success? } end orig_ldflags = $LDFLAGS if get and ! .empty? get[ ] 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:: "package configuration for %s\n", pkg Logging:: "incflags: %s\ncflags: %s\nldflags: %s\nlibs: %s\n\n", incflags, cflags, ldflags, libs [[incflags, cflags].join(' '), ldflags, libs] else Logging:: "package configuration for %s is not found\n", pkg nil end end end
#relative_from(path, base)
# File 'lib/mkmf.rb', line 160
def relative_from(path, base) dir = File.join(path, "") if File. (dir) == File. (dir, base) path else File.join(base, path) end end
#scalar_ptr_type?(type, member = nil, headers = nil, &b) ⇒ Boolean
Used internally by the what_type? method to determine if type
is a scalar pointer.
# File 'lib/mkmf.rb', line 1585
def scalar_ptr_type?(type, member = nil, headers = nil, &b) try_compile(<<"SRC", &b) #{cpp_include(headers)} /*top*/ volatile #{type} conftestval; extern int t(void); #{MAIN_DOES_NOTHING 't'} int t(void) {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));} SRC end
#scalar_type?(type, member = nil, headers = nil, &b) ⇒ Boolean
Used internally by the what_type? method to determine if type
is a scalar pointer.
# File 'lib/mkmf.rb', line 1598
def scalar_type?(type, member = nil, headers = nil, &b) try_compile(<<"SRC", &b) #{cpp_include(headers)} /*top*/ volatile #{type} conftestval; extern int t(void); #{MAIN_DOES_NOTHING 't'} int t(void) {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));} SRC end
#split_libs(*strs)
# File 'lib/mkmf.rb', line 294
def split_libs(*strs) sep = $mswin ? /\s+/ : /\s+(?=-|\z)/ strs.flat_map {|s| s.lstrip.split(sep)} end
#timestamp_file(name, target_prefix = nil)
# File 'lib/mkmf.rb', line 2208
def (name, target_prefix = nil) pat = {} name = '$(RUBYARCHDIR)' if name == '$(TARGET_SO_DIR)' install_dirs.each do |n, d| pat[n] = $` if /\$\(target_prefix\)\z/ =~ d end name = name.gsub(/\$\((#{pat.keys.join("|")})\)/) {pat[$1]+target_prefix} name.sub!(/(\$\((?:site)?arch\))\/*/, '') arch = $1 || '' name.chomp!('/') name = name.gsub(/(\$[({]|[})])|(\/)|[^-.\w]/) {$1 ? "" : $2 ? ".-." : "_"} File.join("$(TIMESTAMP_DIR)", arch, "#{name.sub(/\A(?=.)/, '.')}.time") end
#try_cflags(flags, werror: true, **opts)
# File 'lib/mkmf.rb', line 736
def try_cflags(flags, werror: true, **opts) try_compile(MAIN_DOES_NOTHING, flags, werror: werror, **opts) end
#try_compile(src, opt = "", werror: nil, **opts, &b) Also known as: #try_header
Returns whether or not the src
can be compiled as a C source. opt
is passed to the C compiler as options. Note that $CFLAGS
is also passed to the compiler.
If a block given, it is called with the source before compilation. You can modify the source in the block.
# File 'lib/mkmf.rb', line 653
def try_compile(src, opt = "", werror: nil, **opts, &b) opt = werror_flag(opt) if werror try_do(src, cc_command(opt), werror: werror, **opts, &b) and File.file?("#{CONFTEST}.#{$OBJEXT}") ensure MakeMakefile.rm_f "#{CONFTEST}*" end
#try_const(const, headers = nil, opt = "", &b)
Returns whether or not the constant const
is defined.
See also #have_const
# File 'lib/mkmf.rb', line 1407
def try_const(const, headers = nil, opt = "", &b) const, type = *const if try_compile(<<"SRC", opt, &b) #{cpp_include(headers)} /*top*/ typedef #{type || 'int'} conftest_type; conftest_type conftestval = #{type ? '' : '(int)'}#{const}; SRC $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp)) true else false end end
#try_constant(const, headers = nil, opt = "", &b)
# File 'lib/mkmf.rb', line 784
def try_constant(const, headers = nil, opt = "", &b) includes = cpp_include(headers) neg = try_static_assert("#{const} < 0", headers, opt) if CROSS_COMPILING if neg const = "-(#{const})" elsif try_static_assert("#{const} > 0", headers, opt) # positive constant elsif try_static_assert("#{const} == 0", headers, opt) return 0 else # not a constant return nil end upper = 1 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 = %{#{includes} #include <stdio.h> /*top*/ typedef#{neg ? '' : ' unsigned'} #ifdef PRI_LL_PREFIX #define PRI_CONFTEST_PREFIX PRI_LL_PREFIX LONG_LONG #else #define PRI_CONFTEST_PREFIX "l" long #endif conftest_type; conftest_type conftest_const = (conftest_type)(#{const}); int main() {printf("%"PRI_CONFTEST_PREFIX"#{neg ? 'd' : 'u'}\\n", conftest_const); return 0;} } begin if try_link0(src, opt, &b) xpopen("./#{CONFTEST}") do |f| return Integer(f.gets) end end ensure MakeMakefile.rm_f "#{CONFTEST}#{$EXEEXT}" end end nil end
#try_cpp(src, opt = "", **opts, &b)
Returns whether or not the src
can be preprocessed with the C preprocessor. opt
is passed to the preprocessor as options. Note that $CFLAGS
is also passed to the preprocessor.
If a block given, it is called with the source before preprocessing. You can modify the source in the block.
# File 'lib/mkmf.rb', line 670
def try_cpp(src, opt = "", **opts, &b) try_do(src, cpp_command(CPPOUTFILE, opt), **opts, &b) and File.file?("#{CONFTEST}.i") ensure MakeMakefile.rm_f "#{CONFTEST}*" end
#try_cppflags(flags, werror: true, **opts)
# File 'lib/mkmf.rb', line 705
def try_cppflags(flags, werror: true, **opts) try_header(MAIN_DOES_NOTHING, flags, werror: werror, **opts) end
#try_do(src, command, **opts, &b)
# File 'lib/mkmf.rb', line 526
def try_do(src, command, **opts, &b) unless have_devel? raise <<MSG The compiler failed to generate an executable file. You have to install development tools first. MSG end begin src = create_tmpsrc(src, &b) xsystem(command, **opts) ensure log_src(src) end end
#try_func(func, libs, headers = nil, opt = "", &b)
You should use #have_func rather than try_func
.
# File 'lib/mkmf.rb', line 849
def try_func(func, libs, headers = nil, opt = "", &b) headers = cpp_include(headers) prepare = String.new case func when /^&/ decltype = proc {|x|"const volatile void *#{x}"} when /\)$/ strvars = [] call = func.gsub(/""/) { v = "s#{strvars.size + 1}" strvars << v v } unless strvars.empty? prepare << "char " << strvars.map {|v| "#{v}[1024]"}.join(", ") << "; " end when nil call = "" else call = "#{func}()" decltype = proc {|x| "void ((*#{x})())"} end if opt and !opt.empty? [[:to_str], [:join, " "], [:to_s]].each do |meth, *args| if opt.respond_to?(meth) break opt = opt.__send__(meth, *args) end end opt = "#{opt} #{libs}" else opt = libs end decltype && try_link(<<"SRC", opt, &b) or #{headers} /*top*/ extern int t(void); #{MAIN_DOES_NOTHING 't'} int t(void) { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return !p; } SRC call && try_link(<<"SRC", opt, &b) #{headers} /*top*/ extern int t(void); #{MAIN_DOES_NOTHING 't'} #{"extern void #{call};" if decltype} int t(void) { #{prepare}#{call}; return 0; } SRC end
#try_header(src, opt = "", werror: nil, **opts, &b)
Alias for #try_compile.
# File 'lib/mkmf.rb', line 677
alias try_header try_compile
#try_ldflags(flags, werror: $mswin, **opts)
# File 'lib/mkmf.rb', line 752
def try_ldflags(flags, werror: $mswin, **opts) try_link(MAIN_DOES_NOTHING, flags, werror: werror, **opts) end
#try_link(src, opt = "", **opts, &b)
Returns whether or not the src
can be compiled as a C source and linked with its depending libraries successfully. opt
is passed to the linker as options. Note that $CFLAGS
and $LDFLAGS
are also passed to the linker.
If a block given, it is called with the source before compilation. You can modify the source in the block.
#try_link0(src, opt = "", **opts, &b)
# File 'lib/mkmf.rb', line 607
def try_link0(src, opt = "", **opts, &b) # :nodoc: exe = CONFTEST+$EXEEXT cmd = link_command("", opt) if $universal require 'tmpdir' Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir| begin ENV["TMPDIR"] = tmpdir try_do(src, cmd, **opts, &b) ensure ENV["TMPDIR"] = oldtmpdir end end else try_do(src, cmd, **opts, &b) end and File.executable?(exe) or return nil exe ensure MakeMakefile.rm_rf(*Dir["#{CONFTEST}*"]-[exe]) end
#try_run(src, opt = "", &b)
Returns whether or not:
-
the
src
can be compiled as a C source, -
the result object can be linked with its depending libraries successfully,
-
the linked file can be invoked as an executable
-
and the executable exits successfully
opt
is passed to the linker as options. Note that $CFLAGS
and $LDFLAGS
are also passed to the linker.
If a block given, it is called with the source before compilation. You can modify the source in the block.
Returns true when the executable exits successfully, false when it fails, or nil when preprocessing, compilation or link fails.
#try_signedness(type, member, headers = nil, opts = nil)
# File 'lib/mkmf.rb', line 1459
def try_signedness(type, member, headers = nil, opts = nil) raise ArgumentError, "don't know how to tell signedness of members" if member if try_static_assert("(#{type})-1 < 0", headers, opts) return -1 elsif try_static_assert("(#{type})-1 > 0", headers, opts) return +1 end end
#try_static_assert(expr, headers = nil, opt = "", &b)
# File 'lib/mkmf.rb', line 775
def try_static_assert(expr, headers = nil, opt = "", &b) headers = cpp_include(headers) try_compile(<<SRC, opt, &b) #{headers} /*top*/ int conftest_const[(#{expr}) ? 1 : -1]; SRC end
#try_type(type, headers = nil, opt = "", &b)
Returns whether or not the static type type
is defined.
See also #have_type
# File 'lib/mkmf.rb', line 1349
def try_type(type, headers = nil, opt = "", &b) if try_compile(<<"SRC", opt, &b) #{cpp_include(headers)} /*top*/ typedef #{type} conftest_type; int conftestval[sizeof(conftest_type)?1:-1]; SRC $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp)) true else false end end
#try_var(var, headers = nil, opt = "", &b)
You should use #have_var rather than try_var
.
# File 'lib/mkmf.rb', line 899
def try_var(var, headers = nil, opt = "", &b) headers = cpp_include(headers) try_compile(<<"SRC", opt, &b) #{headers} /*top*/ extern int t(void); #{MAIN_DOES_NOTHING 't'} int t(void) { const volatile void *volatile p; p = &(&#{var})[0]; return !p; } SRC end
#typedef_expr(type, headers)
# File 'lib/mkmf.rb', line 1452
def typedef_expr(type, headers) typename, member = type.split('.', 2) prelude = cpp_include(headers).split(/$/) prelude << "typedef #{typename} rbcv_typedef_;\n" return "rbcv_typedef_", member, prelude end
#werror_flag(opt = nil)
# File 'lib/mkmf.rb', line 597
def werror_flag(opt = nil) config_string("WERRORFLAG") {|flag| opt = opt && !opt.empty? ? "#{opt} #{flag}" : flag} opt end
#what_type?(type, member = nil, headers = nil, &b) ⇒ Boolean
Returns a string represents the type of type, or member of type if member is not nil
.
# File 'lib/mkmf.rb', line 1625
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 (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
#winsep(s)
Converts forward slashes to backslashes. Aimed at MS Windows.
Internal use only.
# File 'lib/mkmf.rb', line 2035
def winsep(s) s.tr('/', '\\') end
#with_cflags(flags)
Sets $CFLAGS
to flags and yields. If the block returns a falsy value, $CFLAGS
is reset to its previous value, remains set to flags otherwise.
# File 'lib/mkmf.rb', line 727
def with_cflags(flags) cflags = $CFLAGS $CFLAGS = flags.dup ret = yield ensure $CFLAGS = cflags unless ret end
#with_config(config, default = nil)
Tests for the presence of a --with-
config or --without-
config option. Returns true
if the with option is given, false
if the without option is given, and the default value otherwise.
This can be useful for adding custom definitions, such as debug information.
Example:
if with_config("debug")
$defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
end
# File 'lib/mkmf.rb', line 1768
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
#with_cppflags(flags)
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
# File 'lib/mkmf.rb', line 696
def with_cppflags(flags) cppflags = $CPPFLAGS $CPPFLAGS = flags.dup ret = yield ensure $CPPFLAGS = cppflags unless ret end
#with_destdir(dir)
# File 'lib/mkmf.rb', line 2026
def with_destdir(dir) dir = dir.sub($dest_prefix_pattern, '') /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir end
#with_ldflags(flags)
Sets $LDFLAGS
to flags and yields. If the block returns a falsy value, $LDFLAGS
is reset to its previous value, remains set to flags otherwise.
# File 'lib/mkmf.rb', line 743
def with_ldflags(flags) ldflags = $LDFLAGS $LDFLAGS = flags.dup ret = yield ensure $LDFLAGS = ldflags unless ret end
#with_werror(opt, opts = nil) {|opt, opts| ... }
# File 'lib/mkmf.rb', line 602
def with_werror(opt, opts = nil) opt = werror_flag(opt) if opts and (opts = opts.dup).delete(:werror) yield(opt, opts) end
#xpopen(command, *mode, &block)
Executes command similarly to xsystem, but yields opened pipe.
#xsystem(command, werror: false) ⇒ Boolean
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.
# File 'lib/mkmf.rb', line 439
def xsystem(command, werror: false) env, 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