~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to lib/mkmf.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2010-07-31 17:08:39 UTC
  • mfrom: (1.1.4 upstream) (8.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100731170839-j034dmpdqt1cc4p6
Tags: 1.9.2~svn28788-1
* New release based on upstream snapshot from the 1.9.2 branch,
  after 1.9.2 RC2. That branch is (supposed to be) binary-compatible
  with the 1.9.1 branch.
  + Builds fine on i386. Closes: #580852.
* Upgrade to Standards-Version: 3.9.1. No changes needed.
* Updated generated incs.
* Patches that still need work:
  + Unclear status, need more investigation:
   090729_fix_Makefile_deps.dpatch
   090803_exclude_rdoc.dpatch
   203_adjust_base_of_search_path.dpatch
   902_define_YAML_in_yaml_stringio.rb.dpatch
   919_common.mk_tweaks.dpatch
   931_libruby_suffix.dpatch
   940_test_thread_mutex_sync_shorter.dpatch
  + Maybe not needed anymore, keeping but not applying.
   102_skip_test_copy_stream.dpatch (test doesn't block anymore?)
   104_skip_btest_io.dpatch (test doesn't block anymore?)
   201_gem_prelude.dpatch (we don't use that rubygems anyway?)
   202_gem_default_dir.dpatch (we don't use that rubygems anyway?)
   940_test_file_exhaustive_fails_as_root.dpatch
   940_test_priority_fails.dpatch
   100518_load_libc_libm.dpatch
* Add disable-tests.diff: disable some tests that cause failures on FreeBSD.
  Closes: #590002, #543805, #542927.
* However, many new failures on FreeBSD. Since that version is still an
  improvement, add the check that makes test suite failures non-fatal on
  FreeBSD again. That still needs to be investigated.
* Re-add 903_skip_base_ruby_check.dpatch
* Add build-dependency on ruby1.8 and drop all pre-generated files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- indent-tabs-mode: t -*-
1
2
# module to create Makefile for extension modules
2
3
# invoke like: ruby -r mkmf extconf.rb
3
4
 
9
10
ORIG_LIBPATH = ENV['LIB']
10
11
 
11
12
CXX_EXT = %w[cc cxx cpp]
12
 
if /mswin|bccwin|mingw|os2/ !~ CONFIG['build_os']
 
13
if File::FNM_SYSCASE.zero?
13
14
  CXX_EXT.concat(%w[C])
14
15
end
15
 
SRC_EXT = %w[c m] << CXX_EXT
 
16
SRC_EXT = %w[c m].concat(CXX_EXT)
16
17
$static = nil
17
18
$config_h = '$(arch_hdrdir)/ruby/config.h'
18
19
$default_static = $static
65
66
$beos = /beos/ =~ RUBY_PLATFORM
66
67
$haiku = /haiku/ =~ RUBY_PLATFORM
67
68
$solaris = /solaris/ =~ RUBY_PLATFORM
 
69
$universal = /universal/ =~ RUBY_PLATFORM
68
70
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
69
71
 
70
72
# :stopdoc:
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])
 
161
$extmk &&= true
158
162
if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
159
163
  $topdir = $hdrdir
160
164
  $top_srcdir = $hdrdir
191
195
end
192
196
 
193
197
def rm_f(*files)
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)
196
200
end
197
201
 
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)
201
205
end
202
206
 
203
207
# Returns time stamp of the +target+ file if it exists and is newer
266
270
      @log = nil
267
271
    end
268
272
  end
269
 
  
 
273
 
270
274
  def self::postpone
271
275
    tmplog = "mkmftmp#{@postpone += 1}.log"
272
276
    open do
274
278
      @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
275
279
      begin
276
280
        log.print(open {yield})
 
281
      ensure
277
282
        @log.close
278
283
        File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
279
 
      ensure
280
284
        @log, @logfile, @orgout, @orgerr = log, *save
281
285
        @postpone -= 1
282
286
        rm_f tmplog
363
367
You have to install development tools first.
364
368
MSG
365
369
  end
366
 
  src = create_tmpsrc(src, &b)
367
 
  xsystem(command)
368
 
ensure
369
 
  log_src(src)
370
 
  rm_rf 'conftest.dSYM'
 
370
  begin
 
371
    src = create_tmpsrc(src, &b)
 
372
    xsystem(command)
 
373
  ensure
 
374
    log_src(src)
 
375
    rm_rf 'conftest.dSYM'
 
376
  end
371
377
end
372
378
 
373
379
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
374
380
  conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
375
 
                                'src' => CONFTEST_C,
 
381
                                'src' => "#{CONFTEST_C}",
376
382
                                'arch_hdrdir' => "#$arch_hdrdir",
377
383
                                'top_srcdir' => $top_srcdir.quote,
378
384
                                'INCFLAGS' => "#$INCFLAGS",
414
420
end
415
421
 
416
422
def try_link0(src, opt="", &b)
417
 
  try_do(src, link_command("", opt), &b)
 
423
  cmd = link_command("", opt)
 
424
  if $universal
 
425
    require 'tmpdir'
 
426
    Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
 
427
      begin
 
428
        ENV["TMPDIR"] = tmpdir
 
429
        try_do(src, cmd, &b)
 
430
      ensure
 
431
        ENV["TMPDIR"] = oldtmpdir
 
432
      end
 
433
    end
 
434
  else
 
435
    try_do(src, cmd, &b)
 
436
  end
418
437
end
419
438
 
420
439
def try_link(src, opt="", &b)
435
454
  rm_f "conftest*"
436
455
end
437
456
 
 
457
class Object
 
458
  alias_method :try_header, (config_string('try_header') || :try_cpp)
 
459
end
 
460
 
438
461
def cpp_include(header)
439
462
  if header
440
463
    header = [header] unless header.kind_of? Array
441
 
    header.map {|h| "#include <#{h}>\n"}.join
 
464
    header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
442
465
  else
443
466
    ""
444
467
  end
601
624
def install_files(mfile, ifiles, map = nil, srcprefix = nil)
602
625
  ifiles or return
603
626
  ifiles.empty? and return
604
 
  srcprefix ||= '$(srcdir)'
 
627
  srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
605
628
  RbConfig::expand(srcdir = srcprefix.dup)
606
629
  dirs = []
607
630
  path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
662
685
# Internal use only.
663
686
#
664
687
def checking_for(m, fmt = nil)
665
 
  f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim #'
 
688
  f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
666
689
  m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
667
690
  message "%s", m
668
691
  a = r = nil
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.
808
831
#
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))
813
836
      true
814
837
    else
815
838
      false
827
850
  message = checking_message(header, paths)
828
851
  header = cpp_include(header)
829
852
  checking_for message do
830
 
    if try_cpp(header)
 
853
    if try_header(header)
831
854
      true
832
855
    else
833
856
      found = false
834
857
      paths.each do |dir|
835
858
        opt = "-I#{dir}".quote
836
 
        if try_cpp(header, opt)
 
859
        if try_header(header, opt)
837
860
          $INCFLAGS << " " << opt
838
861
          found = true
839
862
          break
856
879
# HAVE_STRUCT_FOO_BAR preprocessor macro would be passed to the compiler.
857
880
#
858
881
# HAVE_ST_BAR is also defined for backward compatibility.
859
 
 
882
#
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)
964
987
  end
965
988
end
966
989
 
 
990
STRING_OR_FAILED_FORMAT = "%s"
 
991
# :stopdoc:
 
992
def STRING_OR_FAILED_FORMAT.%(x)
 
993
  x ? super : "failed"
 
994
end
 
995
# :startdoc:
 
996
 
967
997
# Returns the size of the given +type+.  You may optionally specify additional
968
998
# +headers+ to search in for the +type+.
969
999
#
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.
976
1006
#
977
 
def check_sizeof(type, headers = nil, &b)
978
 
  expr = "sizeof(#{type})"
979
 
  fmt = "%d"
980
 
  def fmt.%(x)
981
 
    x ? super : "failed"
982
 
  end
 
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"
 
1012
  prelude = [prelude]
 
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))
986
 
      size
987
 
    end
988
 
  end
 
1016
    if UNIVERSAL_INTS.include?(type)
 
1017
      type
 
1018
    elsif size = UNIVERSAL_INTS.find {|t|
 
1019
        try_static_assert("#{expr} == sizeof(#{t})", prelude, opts, &b)
 
1020
      }
 
1021
      $defs.push(format("-DSIZEOF_%s=SIZEOF_%s", type.tr_cpp, size.tr_cpp))
 
1022
      size
 
1023
    elsif size = try_constant(expr, prelude, opts, &b)
 
1024
      $defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
 
1025
      size
 
1026
    end
 
1027
  end
 
1028
end
 
1029
 
 
1030
# Returns the signedness of the given +type+.  You may optionally
 
1031
# specify additional +headers+ to search in for the +type+.
 
1032
#
 
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.
 
1038
#
 
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
 
1043
# done.
 
1044
#
 
1045
def check_signedness(type, headers = nil)
 
1046
  signed = nil
 
1047
  checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
 
1048
    if try_static_assert("(#{type})-1 < 0")
 
1049
      signed = -1
 
1050
    elsif try_static_assert("(#{type})-1 > 0")
 
1051
      signed = +1
 
1052
    else
 
1053
      next nil
 
1054
    end
 
1055
    $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
 
1056
    signed < 0 ? "signed" : "unsigned"
 
1057
  end
 
1058
  signed
989
1059
end
990
1060
 
991
1061
# :stopdoc:
1014
1084
SRC
1015
1085
end
1016
1086
 
 
1087
# Used internally by the what_type? method to check if _typeof_ GCC
 
1088
# extension is available.
 
1089
def have_typeof?
 
1090
  return $typeof if defined?($typeof)
 
1091
  $typeof = %w[__typeof__ typeof].find do |t|
 
1092
    try_compile(<<SRC)
 
1093
int rbcv_foo;
 
1094
#{t}(rbcv_foo) rbcv_bar;
 
1095
SRC
 
1096
  end
 
1097
end
 
1098
 
1017
1099
def what_type?(type, member = nil, headers = nil, &b)
1018
1100
  m = "#{type}"
1019
 
  name = type
 
1101
  var = val = "*rbcv_var_"
 
1102
  func = "rbcv_func_(void)"
1020
1103
  if member
1021
1104
    m << "." << member
1022
 
    name = "(((#{type} *)0)->#{member})"
1023
 
  end
1024
 
  fmt = "seems %s"
 
1105
  else
 
1106
    type, member = type.split('.', 2)
 
1107
  end
 
1108
  if member
 
1109
    val = "(#{var}).#{member}"
 
1110
  end
 
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",
 
1115
             ]
 
1116
  type = "rbcv_typedef_"
 
1117
  fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s"
 
1118
  if typeof
 
1119
    var = "*rbcv_member_"
 
1120
    func = "rbcv_mem_func_(void)"
 
1121
    member = nil
 
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"
 
1126
    val = var
 
1127
  end
1025
1128
  def fmt.%(x)
1026
1129
    x ? super : "unknown"
1027
1130
  end
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)
1031
 
        "string"
1032
 
      end
1033
 
    elsif scalar_type?(type, member, headers, &b)
1034
 
      if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
1035
 
        "long long"
1036
 
      elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
1037
 
        "long"
1038
 
      elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
1039
 
        "int"
1040
 
      elsif try_static_assert("sizeof(#{name}) > 1", headers)
1041
 
        "short"
1042
 
      else
1043
 
        "char"
1044
 
      end
1045
 
    end
 
1132
    if scalar_ptr_type?(type, member, prelude, &b)
 
1133
      if try_static_assert("sizeof(*#{var}) == 1", prelude)
 
1134
        return "string"
 
1135
      end
 
1136
      ptr = "*"
 
1137
    elsif scalar_type?(type, member, prelude, &b)
 
1138
      unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude)
 
1139
        unsigned = "unsigned"
 
1140
      end
 
1141
      ptr = ""
 
1142
    else
 
1143
      next
 
1144
    end
 
1145
    type = UNIVERSAL_INTS.find do |t|
 
1146
      pre = prelude
 
1147
      unless member
 
1148
        pre += [["static #{unsigned} #{t} #{ptr}#{var};\n",
 
1149
                 "extern #{unsigned} #{t} #{ptr}*#{func};\n"]]
 
1150
      end
 
1151
      try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre)
 
1152
    end
 
1153
    type or next
 
1154
    [unsigned, type, ptr].join(" ").strip
1046
1155
  end
1047
1156
end
1048
1157
 
1051
1160
# Internal use only.
1052
1161
#
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
 
1166
    if exts
 
1167
      exts.each {|ext| File.executable?(file = bin + ext) and return file}
 
1168
    end
1058
1169
    return nil
1059
1170
  end
1060
1171
  if path ||= ENV['PATH']
1065
1176
  file = nil
1066
1177
  path.each do |dir|
1067
1178
    return file if File.executable?(file = File.join(dir, bin))
1068
 
    return file if ext and File.executable?(file << ext)
 
1179
    if exts
 
1180
      exts.each {|ext| File.executable?(ext = file + ext) and return ext}
 
1181
    end
1069
1182
  end
1070
1183
  nil
1071
1184
end
1165
1278
# 'extconf.h'.
1166
1279
#
1167
1280
# For example:
1168
 
 
1281
#
1169
1282
#    # extconf.rb
1170
1283
#    require 'mkmf'
1171
1284
#    have_func('realpath')
1187
1300
#
1188
1301
def create_header(header = "extconf.h")
1189
1302
  message "creating %s\n", header
1190
 
    sym = header.tr("a-z./\055", "A-Z___")
 
1303
  sym = header.tr_cpp
1191
1304
  hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1192
 
      for line in $defs
1193
 
        case line
1194
 
        when /^-D([^=]+)(?:=(.*))?/
1195
 
      hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
1196
 
        when /^-U(.*)/
 
1305
  for line in $defs
 
1306
    case line
 
1307
    when /^-D([^=]+)(?:=(.*))?/
 
1308
      hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
 
1309
    when /^-U(.*)/
1197
1310
      hdr << "#undef #$1\n"
1198
 
        end
1199
 
      end
 
1311
    end
 
1312
  end
1200
1313
  hdr << "#endif\n"
1201
1314
  hdr = hdr.join
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)
1205
1318
    end
1206
1319
  end
1229
1342
  ldir = with_config(target + "-lib", ldefault)
1230
1343
  $arg_config.last[1] ||= "${#{target}-dir}/lib"
1231
1344
 
1232
 
  idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
 
1345
  idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
1233
1346
  if defaults
1234
1347
    idirs.concat(defaults.collect {|d| d + "/include"})
1235
1348
    idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1242
1355
    end
1243
1356
  end
1244
1357
 
1245
 
  ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
 
1358
  ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : []
1246
1359
  if defaults
1247
1360
    ldirs.concat(defaults.collect {|d| d + "/lib"})
1248
1361
    ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1260
1373
  if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1261
1374
    # iff package specific config command is given
1262
1375
    get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1263
 
  elsif ($PKGCONFIG ||= 
 
1376
  elsif ($PKGCONFIG ||=
1264
1377
         (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1265
1378
         find_executable0(pkgconfig) && pkgconfig) and
1266
1379
      system("#{$PKGCONFIG} --exists #{pkg}")
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']}
1402
1515
 
 
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']}
1439
1553
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1440
1554
 
1441
1555
all install static install-so install-rb: Makefile
 
1556
.PHONY: all install static install-so install-rb
 
1557
.PHONY: clean clean-so clean-rb
1442
1558
 
1443
1559
RULES
1444
1560
end
1523
1639
# Makefile.
1524
1640
#
1525
1641
# Setting the +target_prefix+ will, in turn, install the generated binary in
1526
 
# a directory under your Config::CONFIG['sitearchdir'] that mimics your local
 
1642
# a directory under your RbConfig::CONFIG['sitearchdir'] that mimics your local
1527
1643
# filesystem when you run 'make install'.
1528
1644
#
1529
1645
# For example, given the following file tree:
1570
1686
    target_prefix = ""
1571
1687
  end
1572
1688
 
1573
 
  srcprefix ||= '$(srcdir)'
1574
 
  RbConfig::expand(srcdir = srcprefix.dup)
 
1689
  srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
 
1690
  RbConfig.expand(srcdir = srcprefix.dup)
1575
1691
 
 
1692
  ext = ".#{$OBJEXT}"
1576
1693
  if not $objs
1577
 
    $objs = []
1578
 
    srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1579
 
    for f in srcs
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}
 
1696
    $objs = objs.keys
 
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(',')}}"
 
1700
      }
 
1701
      abort "source files duplication - #{dups.join(", ")}"
1582
1702
    end
1583
 
  elsif !(srcs = $srcs)
1584
 
    srcs = $objs.collect {|o| o.sub(/\.o\z/, '.c')}
 
1703
  else
 
1704
    $objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
 
1705
    srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
1585
1706
  end
1586
1707
  $srcs = srcs
1587
 
  for i in $objs
1588
 
    i.sub!(/\.o\z/, ".#{$OBJEXT}")
1589
 
  end
1590
 
  $objs = $objs.join(" ")
1591
1708
 
1592
 
  target = nil if $objs == ""
 
1709
  target = nil if $objs.empty?
1593
1710
 
1594
1711
  if target and EXPORT_PREFIX
1595
1712
    if File.exist?(File.join(srcdir, target + '.def'))
1601
1718
      makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
1602
1719
    end
1603
1720
    if makedef
1604
 
      $distcleanfiles << '$(DEFFILE)'
 
1721
      $cleanfiles << '$(DEFFILE)'
1605
1722
      origdef = deffile
1606
1723
      deffile = "$(TARGET)-$(arch).def"
1607
1724
    end
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?
 
1744
  mfile.puts(conf)
1626
1745
  mfile.print "
1627
1746
libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1628
1747
LIBPATH = #{libpath}
1632
1751
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1633
1752
DISTCLEANDIRS = #{$distcleandirs.join(' ')}
1634
1753
 
1635
 
extout = #{$extout}
 
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(' ')}
1641
 
OBJS = #{$objs}
 
1760
OBJS = #{$objs.join(" ")}
1642
1761
TARGET = #{target}
1643
1762
DLLIB = #{dllib}
1644
1763
EXTSTATIC = #{$static || ""}
1651
1770
  mfile.print "
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
1655
1774
 
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
1658
1779
"
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"
1684
1805
    else
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"
1689
1810
      end
1705
1826
      for f in files
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")
1713
1833
        end
1719
1839
    end
1720
1840
    if $extout
1721
1841
      dirs.uniq!
1722
 
      dirs.reverse!
1723
1842
      unless dirs.empty?
1724
1843
        mfile.print("clean-rb#{sfx}::\n")
1725
 
        for dir in dirs
 
1844
        for dir in dirs.sort_by {|d| -d.count('/')}
1726
1845
          mfile.print("\t@-$(RMDIRS) #{fseprepl[dir]}\n")
1727
1846
        end
1728
1847
      end
1741
1860
 
1742
1861
  return unless target
1743
1862
 
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"
1747
1866
 
1748
 
  CXX_EXT.each do |ext|
 
1867
  CXX_EXT.each do |e|
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)
1752
1871
    end
1753
1872
  end
1754
 
  %w[c].each do |ext|
 
1873
  %w[c].each do |e|
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)
1758
1877
    end
1759
1878
  end
1822
1941
  $LIBRUBYARG = ""
1823
1942
  $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
1824
1943
  $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
1825
 
  $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"]
 
1944
  $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
1826
1945
  $DEFLIBPATH.unshift(".")
1827
1946
  $LIBPATH = []
1828
1947
  $INSTALLFILES = []
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]
1936
2057
 
1937
 
sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if sep != "/"} || ""
 
2058
sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || ""
1938
2059
CLEANINGS = "
1939
2060
clean-rb-default::
1940
2061
clean-rb::