summaryrefslogtreecommitdiff
path: root/lib/mkmf.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mkmf.rb')
-rw-r--r--lib/mkmf.rb338
1 files changed, 260 insertions, 78 deletions
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 245b0a44ce..37ee4a70d9 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -40,10 +40,27 @@ class Array # :nodoc:
end
##
-# mkmf.rb is used by Ruby C extensions to generate a Makefile which will
+# \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.
module MakeMakefile
+
+ target_rbconfig = nil
+ ARGV.delete_if do |arg|
+ opt = arg.delete_prefix("--target-rbconfig=")
+ unless opt == arg
+ target_rbconfig = opt
+ end
+ end
+ if target_rbconfig
+ # Load the RbConfig for the target platform into this module.
+ # Cross-compiling needs the same version of Ruby.
+ Kernel.load target_rbconfig, self
+ else
+ # The RbConfig for the target platform where the built extension runs.
+ RbConfig = ::RbConfig
+ end
+
#### defer until this module become global-state free.
# def self.extended(obj)
# obj.init_mkmf
@@ -59,6 +76,9 @@ module MakeMakefile
# The makefile configuration using the defaults from when Ruby was built.
CONFIG = RbConfig::MAKEFILE_CONFIG
+
+ ##
+ # The saved original value of +LIB+ environment variable
ORIG_LIBPATH = ENV['LIB']
##
@@ -245,12 +265,16 @@ MESSAGE
CSRCFLAG = CONFIG['CSRCFLAG']
CPPOUTFILE = config_string('CPPOUTFILE') {|str| str.sub(/\bconftest\b/, CONFTEST)}
+ # :startdoc:
+
+ # Removes _files_.
def rm_f(*files)
opt = (Hash === files.last ? [files.pop] : [])
FileUtils.rm_f(Dir[*files.flatten], *opt)
end
module_function :rm_f
+ # Removes _files_ recursively.
def rm_rf(*files)
opt = (Hash === files.last ? [files.pop] : [])
FileUtils.rm_rf(Dir[*files.flatten], *opt)
@@ -265,6 +289,8 @@ MESSAGE
t if times.all? {|n| n <= t}
end
+ # :stopdoc:
+
def split_libs(*strs)
sep = $mswin ? /\s+/ : /\s+(?=-|\z)/
strs.flat_map {|s| s.lstrip.split(sep)}
@@ -390,6 +416,11 @@ MESSAGE
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['LSAN_OPTIONS'] = "detect_leaks=0" unless ENV.key?('LSAN_OPTIONS')
+
return envs, expand[commands]
end
@@ -397,11 +428,19 @@ MESSAGE
envs.map {|e, v| "#{e}=#{v.quote}"}
end
- def xsystem command, opts = nil
+ # :startdoc:
+
+ # call-seq:
+ # xsystem(command, werror: false) -> true or false
+ #
+ # 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.
+ def xsystem(command, werror: false)
env, command = expand_command(command)
Logging::open do
puts [env_quote(env), command.quote].join(' ')
- if opts and opts[:werror]
+ if werror
result = nil
Logging.postpone do |log|
output = IO.popen(env, command, &:read)
@@ -415,6 +454,7 @@ MESSAGE
end
end
+ # Executes _command_ similarly to xsystem, but yields opened pipe.
def xpopen command, *mode, &block
env, commands = expand_command(command)
command = [env_quote(env), command].join(' ')
@@ -429,6 +469,7 @@ MESSAGE
end
end
+ # Logs _src_
def log_src(src, heading="checked program was")
src = src.split(/^/)
fmt = "%#{src.size.to_s.size}d: %s"
@@ -443,10 +484,15 @@ EOM
EOM
end
+ # Returns the language-dependent source file name for configuration
+ # checks.
def conftest_source
CONFTEST_C
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.
def create_tmpsrc(src)
src = "#{COMMON_HEADERS}\n#{src}"
src = yield(src) if block_given?
@@ -467,6 +513,8 @@ EOM
src
end
+ # :stopdoc:
+
def have_devel?
unless defined? $have_devel
$have_devel = true
@@ -475,7 +523,7 @@ EOM
$have_devel
end
- def try_do(src, command, *opts, &b)
+ def try_do(src, command, **opts, &b)
unless have_devel?
raise <<MSG
The compiler failed to generate an executable file.
@@ -484,7 +532,7 @@ MSG
end
begin
src = create_tmpsrc(src, &b)
- xsystem(command, *opts)
+ xsystem(command, **opts)
ensure
log_src(src)
end
@@ -525,52 +573,57 @@ MSG
conf)
end
- def cpp_command(outfile, opt="")
+ def cpp_config(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
+ conf
+ end
+
+ def cpp_command(outfile, opt="")
+ conf = cpp_config(opt)
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
conf)
end
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
+ libpathflags = nil
libpath.map{|x|
case x
when "$(topdir)", /\A\./
LIBPATHFLAG
else
- LIBPATHFLAG+RPATHFLAG
+ libpathflags ||= [LIBPATHFLAG, RPATHFLAG].grep(/\S/).join(" ")
end % x.quote
- }.join
+ }.join(" ")
+ end
+
+ def werror_flag(opt = nil)
+ config_string("WERRORFLAG") {|flag| opt = opt && !opt.empty? ? "#{opt} #{flag}" : flag}
+ opt
end
def with_werror(opt, opts = nil)
- if opts
- if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
- (opts = opts.dup).delete(:werror)
- end
- yield(opt, opts)
- else
- yield(opt)
- end
+ opt = werror_flag(opt) if opts and (opts = opts.dup).delete(:werror)
+ yield(opt, opts)
end
- def try_link0(src, opt="", *opts, &b) # :nodoc:
+ def try_link0(src, opt = "", ldflags: "", **opts, &b) # :nodoc:
exe = CONFTEST+$EXEEXT
- cmd = link_command("", opt)
+ cmd = link_command(ldflags, opt)
if $universal
require 'tmpdir'
Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
begin
ENV["TMPDIR"] = tmpdir
- try_do(src, cmd, *opts, &b)
+ try_do(src, cmd, **opts, &b)
ensure
ENV["TMPDIR"] = oldtmpdir
end
end
else
- try_do(src, cmd, *opts, &b)
+ try_do(src, cmd, **opts, &b)
end and File.executable?(exe) or return nil
exe
ensure
@@ -579,31 +632,32 @@ MSG
# 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.
+ # as options. Note that <tt>$CFLAGS</tt> and <tt>$LDFLAGS</tt> 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.
#
# [+src+] a String which contains a C source
# [+opt+] a String which contains linker options
- def try_link(src, opt="", *opts, &b)
- exe = try_link0(src, opt, *opts, &b) or return false
+ def try_link(src, opt = "", **opts, &b)
+ exe = try_link0(src, opt, **opts, &b) or return false
MakeMakefile.rm_f exe
true
end
# 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.
+ # passed to the C compiler as options. Note that <tt>$CFLAGS</tt> 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.
#
# [+src+] a String which contains a C source
# [+opt+] a String which contains compiler options
- def try_compile(src, opt="", *opts, &b)
- with_werror(opt, *opts) {|_opt, *| try_do(src, cc_command(_opt), *opts, &b)} and
+ 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}*"
@@ -611,15 +665,15 @@ MSG
# 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.
+ # <tt>$CFLAGS</tt> 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.
#
# [+src+] a String which contains a C source
# [+opt+] a String which contains preprocessor options
- def try_cpp(src, opt="", *opts, &b)
- try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b) and
+ 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}*"
@@ -636,6 +690,14 @@ MSG
end
end
+ # :startdoc:
+
+ # Sets <tt>$CPPFLAGS</tt> to _flags_ and yields. If the block returns a
+ # falsy value, <tt>$CPPFLAGS</tt> is reset to its previous value, remains
+ # set to _flags_ otherwise.
+ #
+ # [+flags+] a C preprocessor flag as a +String+
+ #
def with_cppflags(flags)
cppflags = $CPPFLAGS
$CPPFLAGS = flags.dup
@@ -644,20 +706,29 @@ MSG
$CPPFLAGS = cppflags unless ret
end
- def try_cppflags(flags, opts = {})
- try_header(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
+ # :nodoc:
+ def try_cppflags(flags, werror: true, **opts)
+ try_header(MAIN_DOES_NOTHING, flags, werror: werror, **opts)
end
- def append_cppflags(flags, *opts)
+ # Check whether each given C preprocessor flag is acceptable and append it
+ # to <tt>$CPPFLAGS</tt> if so.
+ #
+ # [+flags+] a C preprocessor flag as a +String+ or an +Array+ of them
+ #
+ def append_cppflags(flags, **opts)
Array(flags).each do |flag|
if checking_for("whether #{flag} is accepted as CPPFLAGS") {
- try_cppflags(flag, *opts)
+ try_cppflags(flag, **opts)
}
$CPPFLAGS << " " << flag
end
end
end
+ # Sets <tt>$CFLAGS</tt> to _flags_ and yields. If the block returns a falsy
+ # value, <tt>$CFLAGS</tt> is reset to its previous value, remains set to
+ # _flags_ otherwise.
def with_cflags(flags)
cflags = $CFLAGS
$CFLAGS = flags.dup
@@ -666,10 +737,14 @@ MSG
$CFLAGS = cflags unless ret
end
- def try_cflags(flags, opts = {})
- try_compile(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
+ # :nodoc:
+ def try_cflags(flags, werror: true, **opts)
+ try_compile(MAIN_DOES_NOTHING, flags, werror: werror, **opts)
end
+ # Sets <tt>$LDFLAGS</tt> to _flags_ and yields. If the block returns a
+ # falsy value, <tt>$LDFLAGS</tt> is reset to its previous value, remains set
+ # to _flags_ otherwise.
def with_ldflags(flags)
ldflags = $LDFLAGS
$LDFLAGS = flags.dup
@@ -678,21 +753,30 @@ MSG
$LDFLAGS = ldflags unless ret
end
- def try_ldflags(flags, opts = {})
- opts = {:werror => true}.update(opts) if $mswin
- try_link(MAIN_DOES_NOTHING, flags, opts)
+ # :nodoc:
+ def try_ldflags(flags, werror: $mswin, **opts)
+ try_link(MAIN_DOES_NOTHING, "", ldflags: flags, werror: werror, **opts)
end
- def append_ldflags(flags, *opts)
+ # :startdoc:
+
+ # Check whether each given linker flag is acceptable and append it to
+ # <tt>$LDFLAGS</tt> if so.
+ #
+ # [+flags+] a linker flag as a +String+ or an +Array+ of them
+ #
+ def append_ldflags(flags, **opts)
Array(flags).each do |flag|
if checking_for("whether #{flag} is accepted as LDFLAGS") {
- try_ldflags(flag, *opts)
+ try_ldflags(flag, **opts)
}
$LDFLAGS << " " << flag
end
end
end
+ # :stopdoc:
+
def try_static_assert(expr, headers = nil, opt = "", &b)
headers = cpp_include(headers)
try_compile(<<SRC, opt, &b)
@@ -781,7 +865,7 @@ int main() {printf("%"PRI_CONFTEST_PREFIX"#{neg ? 'd' : 'u'}\\n", conftest_const
v
}
unless strvars.empty?
- prepare << "char " << strvars.map {|v| "#{v}[1024]"}.join(", ") << "; "
+ prepare << "char " << strvars.map {|v| %[#{v}[1024] = ""]}.join(", ") << "; "
end
when nil
call = ""
@@ -828,6 +912,8 @@ int t(void) { const volatile void *volatile p; p = &(&#{var})[0]; return !p; }
SRC
end
+ # :startdoc:
+
# Returns whether or not the +src+ can be preprocessed with the C
# preprocessor and matches with +pat+.
#
@@ -845,20 +931,12 @@ SRC
xpopen(cpp_command('', opt)) do |f|
if Regexp === pat
puts(" ruby -ne 'print if #{pat.inspect}'")
- f.grep(pat) {|l|
+ !f.grep(pat) {|l|
puts "#{f.lineno}: #{l}"
- return true
- }
- false
+ }.empty?
else
puts(" egrep '#{pat}'")
- begin
- stdin = $stdin.dup
- $stdin.reopen(f)
- system("egrep", pat)
- ensure
- $stdin.reopen(stdin)
- end
+ system("egrep", pat, in: f)
end
end
ensure
@@ -866,6 +944,8 @@ SRC
log_src(src)
end
+ # :stopdoc:
+
# This is used internally by the have_macro? method.
def macro_defined?(macro, src, opt = "", &b)
src = src.sub(/[^\n]\z/, "\\&\n")
@@ -885,8 +965,8 @@ SRC
# * 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.
+ # +opt+ is passed to the linker as options. Note that <tt>$CFLAGS</tt> and
+ # <tt>$LDFLAGS</tt> 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.
@@ -958,6 +1038,10 @@ SRC
format(LIBARG, lib) + " " + libs
end
+ # Prints messages to $stdout, if verbose mode.
+ #
+ # Internal use only.
+ #
def message(*s)
unless Logging.quiet and not $VERBOSE
printf(*s)
@@ -989,6 +1073,10 @@ SRC
r
end
+ # Build a message for checking.
+ #
+ # Internal use only.
+ #
def checking_message(target, place = nil, opt = nil)
[["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
if noun
@@ -1013,10 +1101,10 @@ SRC
#
# [+flags+] a C compiler flag as a +String+ or an +Array+ of them
#
- def append_cflags(flags, *opts)
+ def append_cflags(flags, **opts)
Array(flags).each do |flag|
if checking_for("whether #{flag} is accepted as CFLAGS") {
- try_cflags(flag, *opts)
+ try_cflags(flag, **opts)
}
$CFLAGS << " " << flag
end
@@ -1250,6 +1338,7 @@ SRC
end
end
+ # :nodoc:
# Returns whether or not the static type +type+ is defined.
#
# See also +have_type+
@@ -1307,6 +1396,7 @@ SRC
end
end
+ # :nodoc:
# Returns whether or not the constant +const+ is defined.
#
# See also +have_const+
@@ -1466,7 +1556,7 @@ SRC
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)
+ try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, werror: true, &b)
}
end
if compat
@@ -1490,7 +1580,7 @@ SRC
# Used internally by the what_type? method to determine if +type+ is a scalar
# pointer.
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
- try_compile(<<"SRC", &b) # pointer
+ try_compile(<<"SRC", &b)
#{cpp_include(headers)}
/*top*/
volatile #{type} conftestval;
@@ -1503,7 +1593,7 @@ SRC
# Used internally by the what_type? method to determine if +type+ is a scalar
# pointer.
def scalar_type?(type, member = nil, headers = nil, &b)
- try_compile(<<"SRC", &b) # pointer
+ try_compile(<<"SRC", &b)
#{cpp_include(headers)}
/*top*/
volatile #{type} conftestval;
@@ -1525,6 +1615,10 @@ SRC
end
end
+ # :startdoc:
+
+ # Returns a string represents the type of _type_, or _member_ of
+ # _type_ if _member_ is not +nil+.
def what_type?(type, member = nil, headers = nil, &b)
m = "#{type}"
var = val = "*rbcv_var_"
@@ -1584,6 +1678,8 @@ SRC
end
end
+ # :nodoc:
+ #
# This method is used internally by the find_executable method.
#
# Internal use only.
@@ -1622,8 +1718,6 @@ SRC
nil
end
- # :startdoc:
-
# 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.
@@ -1792,7 +1886,8 @@ SRC
# application.
#
def dir_config(target, idefault=nil, ldefault=nil)
- if conf = $config_dirs[target]
+ key = [target, idefault, ldefault].compact.join("\0")
+ if conf = $config_dirs[key]
return conf
end
@@ -1802,9 +1897,13 @@ SRC
end
idir = with_config(target + "-include", idefault)
- $arg_config.last[1] ||= "${#{target}-dir}/include"
+ if conf = $arg_config.assoc("--with-#{target}-include")
+ conf[1] ||= "${#{target}-dir}/include"
+ end
ldir = with_config(target + "-lib", ldefault)
- $arg_config.last[1] ||= "${#{target}-dir}/#{_libdir_basename}"
+ 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
@@ -1826,7 +1925,7 @@ SRC
end
$LIBPATH = ldirs | $LIBPATH
- $config_dirs[target] = [idir, ldir]
+ $config_dirs[key] = [idir, ldir]
end
# Returns compile/link information about an installed library in a tuple of <code>[cflags,
@@ -1866,7 +1965,7 @@ SRC
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"}) &&
+ (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
@@ -1882,7 +1981,20 @@ SRC
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?
+ 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
@@ -1965,14 +2077,14 @@ SRC
def configuration(srcdir)
mk = []
- CONFIG['MKMF_VERBOSE'] ||= "0"
+ 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 = #{CONFIG['MKMF_VERBOSE']}
+V = #{verbose}
V0 = $(V:0=)
Q1 = $(V:1=)
Q = $(Q1:0=@)
@@ -2064,7 +2176,9 @@ 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']}
}
@@ -2264,6 +2378,19 @@ RULES
# 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.
def create_makefile(target, srcprefix = nil)
$target = target
libpath = $DEFLIBPATH|$LIBPATH
@@ -2372,7 +2499,7 @@ 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" : ""}
+#{!$extout && defined?($installed_list) ? %[INSTALLED_LIST = #{$installed_list}\n] : ""}
TIMESTAMP_DIR = #{$extout && $extmk ? '$(extout)/.timestamp' : '.'}
" #"
# TODO: fixme
@@ -2380,16 +2507,19 @@ TIMESTAMP_DIR = #{$extout && $extmk ? '$(extout)/.timestamp' : '.'}
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 = #{'$(TARGET_SO) ' if target}#{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
+CLEANLIBS = #{cleanlibs.join(' ')}
CLEANOBJS = #{cleanobjs.join(' ')} *.bak
TARGET_SO_DIR_TIMESTAMP = #{timestamp_file(sodir, target_prefix)}
" #"
@@ -2399,7 +2529,7 @@ TARGET_SO_DIR_TIMESTAMP = #{timestamp_file(sodir, target_prefix)}
mfile.puts(conf)
mfile.print "
all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
-static: #{$extmk && !$static ? "all" : "$(STATIC_LIB)#{$extout ? " install-rb" : ""}"}
+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
" #"
@@ -2430,6 +2560,7 @@ static: #{$extmk && !$static ? "all" : "$(STATIC_LIB)#{$extout ? " install-rb" :
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"
@@ -2460,7 +2591,7 @@ static: #{$extmk && !$static ? "all" : "$(STATIC_LIB)#{$extout ? " install-rb" :
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} $(@D)\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
@@ -2699,7 +2830,7 @@ MESSAGE
when $mswin
$nmake = ?m if /nmake/i =~ make
end
- $ignore_error = $nmake ? '' : ' 2> /dev/null || true'
+ $ignore_error = " 2> #{File::NULL} || #{$mswin ? 'exit /b0' : 'true'}"
RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
$srcdir = arg_config("--srcdir", File.dirname($0))
@@ -2722,6 +2853,9 @@ MESSAGE
split = Shellwords.method(:shellwords).to_proc
+ ##
+ # The prefix added to exported symbols automatically
+
EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
hdr = ['#include "ruby.h"' "\n"]
@@ -2751,6 +2885,10 @@ MESSAGE
# make compile rules
COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
+
+ ##
+ # Substitution in rules for NMake
+
RULE_SUBST = config_string('RULE_SUBST')
##
@@ -2795,7 +2933,11 @@ MESSAGE
##
# Argument which will add a library path to the linker
- LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L%s'
+ LIBPATHFLAG = config_string('LIBPATHFLAG') || '-L%s'
+
+ ##
+ # Argument which will add a runtime library path to the linker
+
RPATHFLAG = config_string('RPATHFLAG') || ''
##
@@ -2807,6 +2949,10 @@ MESSAGE
# A C main function which does no work
MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return !!argv[argc];\n}"
+
+ ##
+ # The type names for convertible_int
+
UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
%w[int short long long\ long]
@@ -2837,18 +2983,32 @@ realclean: distclean
@lang = Hash.new(self)
+ ##
+ # Retrieves the module for _name_ language.
def self.[](name)
@lang.fetch(name)
end
+ ##
+ # Defines the module for _name_ language.
def self.[]=(name, mod)
@lang[name] = mod
end
- self["C++"] = Module.new do
+ ##
+ # The language that this module is for
+ LANGUAGE = -"C"
+
+ self[self::LANGUAGE] = self
+
+ cxx = Module.new do
+ # Module for C++
+
include MakeMakefile
extend self
+ # :stopdoc:
+
CONFTEST_CXX = "#{CONFTEST}.#{config_string('CXX_EXT') || CXX_EXT[0]}"
TRY_LINK_CXX = config_string('TRY_LINK_CXX') ||
@@ -2870,15 +3030,37 @@ realclean: distclean
def cc_command(opt="")
conf = cc_config(opt)
+ cxx_command(opt, conf)
RbConfig::expand("$(CXX) #$INCFLAGS #$CPPFLAGS #$CXXFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_CXX}",
conf)
end
+ def cpp_command(outfile, opt="")
+ conf = cpp_config(opt)
+ cxx = cxx_command(opt, conf)
+ cpp = conf['CPP'].sub(/(\A|\s)#{Regexp.quote(conf['CC'])}(?=\z|\s)/) {
+ "#$1#{cxx}"
+ }
+ RbConfig::expand("#{cpp} #$INCFLAGS #$CPPFLAGS #$CXXFLAGS #{opt} #{CONFTEST_CXX} #{outfile}",
+ conf)
+ end
+
def link_command(ldflags, *opts)
conf = link_config(ldflags, *opts)
RbConfig::expand(TRY_LINK_CXX.dup, conf)
end
+
+ def cxx_command(opt="", conf = cc_config(opt))
+ cxx = conf['CXX']
+ raise Errno::ENOENT, "C++ compiler not found" if !cxx or cxx == 'false'
+ cxx
+ end
+
+ # :startdoc:
end
+
+ cxx::LANGUAGE = -"C++"
+ self[cxx::LANGUAGE] = cxx
end
# MakeMakefile::Global = #