なかだです。

At Wed, 29 Oct 2003 20:18:49 +0900,
Siena. / SHINAGAWA, Norihide wrote:
> (1) EXTFLAGS が引数無しの "-L" に展開され、main.o がリンクされない
> 
> ChangeLog:
> Wed Aug  6 17:28:10 2003  Nobuyoshi Nakada  <nobu / ruby-lang.org>
> * ext/extmk.rb (extmake): pass LIBPATH to make ruby.  [ruby-dev:21137]
> 
> "$(libdir)" が正しく展開されるように変更するのが本筋かと思いますが、
> とりあえずの対症療法として $extpath から "$(libdir)" を削除しました。

これは、makeまで$(libdir)のまま渡されて、makeによって展開される
のが正しい姿でしょう。そう考えれば、mkmf.rbのString#quoteでシン
グルクォートを使うようにすべきかも知れませんが、humanとmacosが
どうなるのか。

できれば、OS/2 EMXでも引数を配列で渡せばシェルを通さないように
したほうがいいんでしょうけどねぇ。

> (2) $extlibs の重複除去のため、EXTLIBS の正しいリンク順が破壊される
> 
> ChangeLog:
> Tue Aug 12 16:55:11 2003  Nobuyoshi Nakada  <nobu / ruby-lang.org>
> * ext/extmk.rb (extmake): compact $extlibs.
> 
> 少なくともうちのビルド環境では、経験的に調べた範囲では、
> ライブラリ a が b に依存する場合に、リンク時のコマンドでオプションの
> 指定順は "-la -lb" とせねばならず、"-lb -la" とはできないようです。

これはUnix系のldでは標準的な動作ですが、重複するライブラリを使
うものはないだろうと思って手を抜いてしまいました。

> 上記の変更のために、重複した時にこの逆転が起きてしまっています。
> パッチでは、新規追加分を $extlibs の左側に追加するようにしました。

入れ換えただけでは、逆にすでに$extlibsにあるものの順序が保証さ
れないでしょう。真面目にやるならこんなとこ?

def merge_libs(*libs)
  libs.inject([]) do |l, r|
    i = 0
    (r & l).each do |c|
      j = r.index(c)
      l.insert(l.rindex(c), *r[i...j])
      i = j + 1
    end
    l.concat(r[i..-1])
  end
end

require 'test/unit'

class TestLib < Test::Unit::TestCase
  def assert_in_order(array, x, y)
    assert(array.index(x) < array.rindex(y), "#{x} must proceed to #{y}")
  end
  def test_simple
    assert_equal([], merge_libs(%w[]))
    assert_equal(%w[a b], merge_libs(%w[a], %w[b]))
    array = merge_libs(%w[a c], %w[b])
    assert_in_order(array, "a", "c")
  end
  def test_seq
    array = merge_libs(%w[a c d], %w[b c d e])
    assert_in_order(array, "a", "c")
    assert_in_order(array, "c", "d")
    assert_in_order(array, "b", "c")
    assert_in_order(array, "d", "e")
    array = merge_libs(%w[a c d], %w[c b e])
    assert_in_order(array, "a", "c")
    assert_in_order(array, "c", "d")
    assert_in_order(array, "c", "b")
    assert_in_order(array, "b", "e")
  end
  def test_cyclic
    array = merge_libs(%w[a c d], %w[b c b])
    assert_in_order(array, "a", "c")
    assert_in_order(array, "c", "d")
    assert_in_order(array, "b", "c")
    assert_in_order(array, "c", "b")
    array = merge_libs(%w[a c a d], %w[b c b])
    assert_in_order(array, "a", "c")
    assert_in_order(array, "c", "a")
    assert_in_order(array, "c", "d")
    assert_in_order(array, "a", "d")
    assert_in_order(array, "b", "c")
    assert_in_order(array, "c", "b")
  end
end

-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦