154
156
topdir = File.dirname(libdir = File.dirname(__FILE__))
155
157
extdir = File.expand_path("ext", topdir)
156
158
path = File.expand_path($0)
157
$extmk = path[0, topdir.size+1] == topdir+"/" && %r"\A(ext|enc|tool)\z" =~ File.dirname(path[topdir.size+1..-1])
159
$extmk = path[0, topdir.size+1] == topdir+"/"
160
$extmk &&= %r"\A(?:ext|enc|tool|test(?:/.+))\z" =~ File.dirname(path[topdir.size+1..-1])
158
162
if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
159
163
$topdir = $hdrdir
160
164
$top_srcdir = $hdrdir
194
opt = ([files.pop] if Hash === files.last)
195
FileUtils.rm_f(Dir[*files.flatten(1)], *opt)
198
opt = (Hash === files.last ? [files.pop] : [])
199
FileUtils.rm_f(Dir[*files.flatten], *opt)
198
202
def rm_rf(*files)
199
opt = ([files.pop] if Hash === files.last)
200
FileUtils.rm_rf(Dir[*files.flatten(1)], *opt)
203
opt = (Hash === files.last ? [files.pop] : [])
204
FileUtils.rm_rf(Dir[*files.flatten], *opt)
203
207
# Returns time stamp of the +target+ file if it exists and is newer
274
278
@log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
276
280
log.print(open {yield})
278
283
File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
280
284
@log, @logfile, @orgout, @orgerr = log, *save
363
367
You have to install development tools first.
366
src = create_tmpsrc(src, &b)
370
rm_rf 'conftest.dSYM'
371
src = create_tmpsrc(src, &b)
375
rm_rf 'conftest.dSYM'
373
379
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
374
380
conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
381
'src' => "#{CONFTEST_C}",
376
382
'arch_hdrdir' => "#$arch_hdrdir",
377
383
'top_srcdir' => $top_srcdir.quote,
378
384
'INCFLAGS' => "#$INCFLAGS",
416
422
def try_link0(src, opt="", &b)
417
try_do(src, link_command("", opt), &b)
423
cmd = link_command("", opt)
426
Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
428
ENV["TMPDIR"] = tmpdir
431
ENV["TMPDIR"] = oldtmpdir
420
439
def try_link(src, opt="", &b)
806
829
# For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
807
830
# preprocessor macro would be passed to the compiler.
809
def have_header(header, &b)
832
def have_header(header, preheaders = nil, &b)
810
833
checking_for header do
811
if try_cpp(cpp_include(header), &b)
812
$defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
834
if try_header(cpp_include(preheaders)+cpp_include(header), &b)
835
$defs.push(format("-DHAVE_%s", header.tr_cpp))
856
879
# HAVE_STRUCT_FOO_BAR preprocessor macro would be passed to the compiler.
858
881
# HAVE_ST_BAR is also defined for backward compatibility.
860
883
def have_struct_member(type, member, headers = nil, &b)
861
884
checking_for checking_message("#{type}.#{member}", headers) do
862
885
if try_compile(<<"SRC", &b)
974
1004
# For example, if check_sizeof('mystruct') returned 12, then the
975
1005
# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
977
def check_sizeof(type, headers = nil, &b)
978
expr = "sizeof(#{type})"
1007
def check_sizeof(type, headers = nil, opts = "", &b)
1008
typename, member = type.split('.', 2)
1009
prelude = cpp_include(headers).split(/$/)
1010
prelude << "typedef #{typename} rbcv_typedef_;\n"
1011
prelude << "static rbcv_typedef_ *rbcv_ptr_;\n"
1013
expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
1014
fmt = STRING_OR_FAILED_FORMAT
983
1015
checking_for checking_message("size of #{type}", headers), fmt do
984
if size = try_constant(expr, headers, &b)
985
$defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
1016
if UNIVERSAL_INTS.include?(type)
1018
elsif size = UNIVERSAL_INTS.find {|t|
1019
try_static_assert("#{expr} == sizeof(#{t})", prelude, opts, &b)
1021
$defs.push(format("-DSIZEOF_%s=SIZEOF_%s", type.tr_cpp, size.tr_cpp))
1023
elsif size = try_constant(expr, prelude, opts, &b)
1024
$defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
1030
# Returns the signedness of the given +type+. You may optionally
1031
# specify additional +headers+ to search in for the +type+.
1033
# If the +type+ is found and is a numeric type, a macro is passed as a
1034
# preprocessor constant to the compiler using the +type+ name, in
1035
# uppercase, prepended with 'SIGNEDNESS_OF_', followed by the +type+
1036
# name, followed by '=X' where 'X' is positive integer if the +type+ is
1037
# unsigned, or negative integer if the +type+ is signed.
1039
# For example, if size_t is defined as unsigned, then
1040
# check_signedness('size_t') would returned +1 and the
1041
# SIGNEDNESS_OF_SIZE_T=+1 preprocessor macro would be passed to the
1042
# compiler, and SIGNEDNESS_OF_INT=-1 if check_signedness('int') is
1045
def check_signedness(type, headers = nil)
1047
checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
1048
if try_static_assert("(#{type})-1 < 0")
1050
elsif try_static_assert("(#{type})-1 > 0")
1055
$defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
1056
signed < 0 ? "signed" : "unsigned"
1087
# Used internally by the what_type? method to check if _typeof_ GCC
1088
# extension is available.
1090
return $typeof if defined?($typeof)
1091
$typeof = %w[__typeof__ typeof].find do |t|
1094
#{t}(rbcv_foo) rbcv_bar;
1017
1099
def what_type?(type, member = nil, headers = nil, &b)
1101
var = val = "*rbcv_var_"
1102
func = "rbcv_func_(void)"
1021
1104
m << "." << member
1022
name = "(((#{type} *)0)->#{member})"
1106
type, member = type.split('.', 2)
1109
val = "(#{var}).#{member}"
1111
prelude = [cpp_include(headers).split(/^/)]
1112
prelude << ["typedef #{type} rbcv_typedef_;\n",
1113
"extern rbcv_typedef_ *#{func};\n",
1114
"static rbcv_typedef_ #{var};\n",
1116
type = "rbcv_typedef_"
1117
fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s"
1119
var = "*rbcv_member_"
1120
func = "rbcv_mem_func_(void)"
1122
type = "rbcv_mem_typedef_"
1123
prelude[-1] << "typedef #{typeof}(#{val}) #{type};\n"
1124
prelude[-1] << "extern #{type} *#{func};\n"
1125
prelude[-1] << "static #{type} #{var};\n"
1026
1129
x ? super : "unknown"
1028
1131
checking_for checking_message(m, headers), fmt do
1029
if scalar_ptr_type?(type, member, headers, &b)
1030
if try_static_assert("sizeof(*#{name}) == 1", headers)
1033
elsif scalar_type?(type, member, headers, &b)
1034
if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
1036
elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
1038
elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
1040
elsif try_static_assert("sizeof(#{name}) > 1", headers)
1132
if scalar_ptr_type?(type, member, prelude, &b)
1133
if try_static_assert("sizeof(*#{var}) == 1", prelude)
1137
elsif scalar_type?(type, member, prelude, &b)
1138
unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude)
1139
unsigned = "unsigned"
1145
type = UNIVERSAL_INTS.find do |t|
1148
pre += [["static #{unsigned} #{t} #{ptr}#{var};\n",
1149
"extern #{unsigned} #{t} #{ptr}*#{func};\n"]]
1151
try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre)
1154
[unsigned, type, ptr].join(" ").strip
1051
1160
# Internal use only.
1053
1162
def find_executable0(bin, path = nil)
1054
ext = config_string('EXEEXT')
1163
exts = config_string('EXECUTABLE_EXTS') {|s| s.split} || config_string('EXEEXT') {|s| [s]}
1055
1164
if File.expand_path(bin) == bin
1056
1165
return bin if File.executable?(bin)
1057
ext and File.executable?(file = bin + ext) and return file
1167
exts.each {|ext| File.executable?(file = bin + ext) and return file}
1060
1171
if path ||= ENV['PATH']
1188
1301
def create_header(header = "extconf.h")
1189
1302
message "creating %s\n", header
1190
sym = header.tr("a-z./\055", "A-Z___")
1191
1304
hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1194
when /^-D([^=]+)(?:=(.*))?/
1195
hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
1307
when /^-D([^=]+)(?:=(.*))?/
1308
hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
1197
1310
hdr << "#undef #$1\n"
1200
1313
hdr << "#endif\n"
1202
1315
unless (IO.read(header) == hdr rescue false)
1203
open(header, "w") do |hfile|
1316
open(header, "wb") do |hfile|
1204
1317
hfile.write(hdr)
1393
1506
CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
1394
1507
ldflags = #{$LDFLAGS}
1395
1508
dldflags = #{$DLDFLAGS}
1396
archflag = #{$ARCH_FLAG}
1397
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
1509
ARCH_FLAG = #{$ARCH_FLAG}
1510
DLDFLAGS = $(ldflags) $(dldflags)
1398
1511
LDSHARED = #{CONFIG['LDSHARED']}
1399
1512
LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'}
1400
1513
AR = #{CONFIG['AR']}
1401
1514
EXEEXT = #{CONFIG['EXEEXT']}
1516
RUBY_BASE_NAME = #{CONFIG['RUBY_BASE_NAME']}
1403
1517
RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
1404
1518
RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
1405
1519
arch = #{CONFIG['arch']}
1570
1686
target_prefix = ""
1573
srcprefix ||= '$(srcdir)'
1574
RbConfig::expand(srcdir = srcprefix.dup)
1689
srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
1690
RbConfig.expand(srcdir = srcprefix.dup)
1578
srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1580
obj = File.basename(f, ".*") << ".o"
1581
$objs.push(obj) unless $objs.index(obj)
1694
srcs = $srcs || Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1695
objs = srcs.inject(Hash.new {[]}) {|h, f| h[File.basename(f, ".*") << ext] <<= f; h}
1697
unless objs.delete_if {|b, f| f.size == 1}.empty?
1698
dups = objs.sort.map {|b, f|
1699
"#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}"
1701
abort "source files duplication - #{dups.join(", ")}"
1583
elsif !(srcs = $srcs)
1584
srcs = $objs.collect {|o| o.sub(/\.o\z/, '.c')}
1704
$objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
1705
srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
1588
i.sub!(/\.o\z/, ".#{$OBJEXT}")
1590
$objs = $objs.join(" ")
1592
target = nil if $objs == ""
1709
target = nil if $objs.empty?
1594
1711
if target and EXPORT_PREFIX
1595
1712
if File.exist?(File.join(srcdir, target + '.def'))
1622
1739
dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1623
1740
staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1624
1741
mfile = open("Makefile", "wb")
1625
mfile.print(*configuration(srcprefix))
1742
conf = configuration(srcprefix)
1743
conf = yield(conf) if block_given?
1627
1746
libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1628
1747
LIBPATH = #{libpath}
1632
1751
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1633
1752
DISTCLEANDIRS = #{$distcleandirs.join(' ')}
1754
extout = #{$extout && $extout.quote}
1636
1755
extout_prefix = #{$extout_prefix}
1637
1756
target_prefix = #{target_prefix}
1638
1757
LOCAL_LIBS = #{$LOCAL_LIBS}
1639
1758
LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1640
1759
SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1760
OBJS = #{$objs.join(" ")}
1642
1761
TARGET = #{target}
1643
1762
DLLIB = #{dllib}
1644
1763
EXTSTATIC = #{$static || ""}
1652
1771
TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
1653
1772
CLEANLIBS = #{n}.#{CONFIG['DLEXT']} #{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
1654
CLEANOBJS = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, '$(TARGET)')}} *.bak
1773
CLEANOBJS = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")} if target} *.bak
1656
1775
all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1657
1776
static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
1777
.PHONY: all install static install-so install-rb
1778
.PHONY: clean clean-so clean-rb
1659
1780
mfile.print CLEANINGS
1660
1781
fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"}
1682
1803
mfile.print "\t@-$(RM) #{fseprepl[dest]}\n"
1683
1804
mfile.print "\t@-$(RMDIRS) #{fseprepl[dir]}\n"
1685
mfile.print "#{dest}: #{f}\n"
1686
mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{fseprepl[dir]}\n"
1806
mfile.print "#{dest}: #{f}\n\t@-$(MAKEDIRS) $(@D#{sep})\n"
1807
mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} $(@D#{sep})\n"
1687
1808
if defined?($installed_list)
1688
1809
mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
1706
1827
dest = "#{dir}/#{File.basename(f)}"
1707
1828
mfile.print("install-rb#{sfx}: #{dest}\n")
1708
mfile.print("#{dest}: #{f}\n")
1709
mfile.print("\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
1710
mfile.print("#{fseprepl[f]} $(@D#{sep})\n")
1829
mfile.print("#{dest}: #{f}\n\t@-$(MAKEDIRS) $(@D#{sep})\n")
1830
mfile.print("\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
1711
1831
if defined?($installed_list) and !$extout
1712
1832
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
1742
1861
return unless target
1744
mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
1863
mfile.puts SRC_EXT.collect {|e| ".path.#{e} = $(VPATH)"} if $nmake == ?b
1745
1864
mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
1746
1865
mfile.print "\n"
1748
CXX_EXT.each do |ext|
1749
1868
COMPILE_RULES.each do |rule|
1750
mfile.printf(rule, ext, $OBJEXT)
1869
mfile.printf(rule, e, $OBJEXT)
1751
1870
mfile.printf("\n\t%s\n\n", COMPILE_CXX)
1755
1874
COMPILE_RULES.each do |rule|
1756
mfile.printf(rule, ext, $OBJEXT)
1875
mfile.printf(rule, e, $OBJEXT)
1757
1876
mfile.printf("\n\t%s\n\n", COMPILE_C)
1933
2052
RPATHFLAG = config_string('RPATHFLAG') || ''
1934
2053
LIBARG = config_string('LIBARG') || '-l%s'
1935
2054
MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || 'int main() {return 0;}'
2055
UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
2056
%w[int short long long\ long]
1937
sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if sep != "/"} || ""
2058
sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || ""
1939
2060
clean-rb-default::