build.logの読み解き方 #0 「sys-apps/groff-1.20.1-r3」
バグを見かけては、それを解決する連載の予定…。いつまで続くことやら。
今回は今 Mac OS X prefix で emerge できない sys-apps/groff-1.20.1-r3 について。
とりあえず ~/Gentoo/var/tmp/portage/sys-apps/groff-1.20.1-r3/temp/build.log を見てみます。
i686-apple-darwin10-g++ -march=core2 -msse4.2 -m32 -pipe -fomit-frame-pointer -O2 -Wl,-dead_strip_dylibs -o troff dictionary.o div.o env.o input.o majorminor.o mtsm.o node.o number.o reg.o /Users/naota/Gentoo/var/tmp/portage/sys-apps/groff-1.20.1-r3/work/groff-1.20.1/src/libs/libgroff/libgroff.a -lm collect2: ld terminated with signal 6 [Abort trap] Undefined symbols: "node::~node()", referenced from: extra_size_node::~extra_size_node()in div.o extra_size_node::~extra_size_node()in div.o vertical_size_node::~vertical_size_node()in div.o vertical_size_node::~vertical_size_node()in div.o token_node::token_node(token const&)in input.o non_interpreted_node::non_interpreted_node(macro const&)in input.o non_interpreted_char_node::non_interpreted_char_node(unsigned char)in input.o non_interpreted_char_node::~non_interpreted_char_node()in input.o non_interpreted_char_node::~non_interpreted_char_node()in input.o token_node::~token_node()in input.o token_node::~token_node()in input.o token_node::~token_node()in input.o token_node::~token_node()in input.o non_interpreted_node::~non_interpreted_node()in input.o non_interpreted_node::~non_interpreted_node()in input.o non_interpreted_node::~non_interpreted_node()in input.o non_interpreted_node::~non_interpreted_node()in input.o got unhandled exception: symbol(s) not found terminate called after throwing an instance of 'char const*' make[2]: *** [troff] Error 1 make[2]: Leaving directory `/Users/naota/Gentoo/var/tmp/portage/sys-apps/groff-1.20.1-r3/work/groff-1.20.1/src/roff/troff' make[1]: *** [src/roff/troff] Error 2 make[1]: Leaving directory `/Users/naota/Gentoo/var/tmp/portage/sys-apps/groff-1.20.1-r3/work/groff-1.20.1' make: *** [all] Error 2
この部分が今度のエラーの核。だいたいは node::~node() が見当たらないと言ってます。
前回はbuildが通ったという知識があるので、それを元に比較します。
% eix groff [I] sys-apps/groff Available versions: [M](~)1.20.1-r1 (~)1.20.1-r2 (~)1.20.1-r3 {X examples linguas_ja} Installed versions: 1.20.1-r2(06時40分48秒 2010/08/11)(-X -examples -linguas_ja) Homepage: http://www.gnu.org/software/groff/groff.html Description: Text formatter used for man pages
成功したのは groff-1.20.1-r2, 失敗したのは groff-1.20.1-r3 で revison が1つ違うだけ。すなわち元のソースのバージョンは一緒で、 patch が追加されたり削除されたりしているってことです。
この2つの違いを見ます。
% cd ~/Gentoo/usr/portage/sys-apps/groff % diff -u groff-1.20.1-r2.ebuild groff-1.20.1-r3.ebuild --- groff-1.20.1-r2.ebuild 2009-11-11 19:31:58.000000000 +0900 +++ groff-1.20.1-r3.ebuild 2010-08-07 21:31:47.000000000 +0900 @@ -1,13 +1,13 @@ -# Copyright 1999-2009 Gentoo Foundation +# Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-apps/groff/groff-1.20.1-r2.ebuild,v 1.1 2009/11/07 06:10:09 matsuu Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-apps/groff/groff-1.20.1-r3.ebuild,v 1.2 2010/07/25 21:29:44 jer Exp $ inherit autotools eutils toolchain-funcs DESCRIPTION="Text formatter used for man pages" HOMEPAGE="http://www.gnu.org/software/groff/groff.html" SRC_URI="mirror://gnu/groff/${P}.tar.gz - linguas_ja? ( mirror://gentoo/${PF}-japanese.patch.bz2 )" + linguas_ja? ( mirror://gentoo/${P}-r2-japanese.patch.bz2 )" LICENSE="GPL-2" SLOT="0" @@ -29,6 +29,9 @@ cd "${S}" epatch "${FILESDIR}"/${PN}-1.19.2-man-unicode-dashes.patch #16108 #17580 #121502 + epatch "${FILESDIR}"/${P}-tmac-ec.patch #263524 + epatch "${FILESDIR}"/${P}-Thtml-mem-leak.patch #294045 + epatch "${FILESDIR}"/${P}-double-frees-mem-leaks.patch #294045 # put the docs in the Gentoo-specific spot sed -i \ @@ -55,7 +58,7 @@ EOF if use linguas_ja ; then - epatch "${WORKDIR}"/${PF}-japanese.patch #255292 + epatch "${WORKDIR}"/${P}-r2-japanese.patch #255292 eautoconf eautoheader fi
ここで、 ${PF} = "1.20.1-r2" あるいは "1.20.1-r3" で ${P} = "1.20.1" です。 LINGUAS="ja" は指定されてない(先の eix の出力で "-linguas_ja" であった)ことから、 "if use linguas_ja; then ... fi" の部分は無視できます。
問題は残りの patch の部分でしょう。 node::~node() あたりがあやしいので grep します。
% grep node files/groff-1.20.1-* files/groff-1.20.1-Thtml-mem-leak.patch:* src/roff/troff/node.h (node::~node): Move to... files/groff-1.20.1-Thtml-mem-leak.patch:* src/roff/troff/node.cpp: Here. Free `state' and `push_state'. files/groff-1.20.1-Thtml-mem-leak.patch: src/roff/troff/node.cpp | 11 ++++++++++- files/groff-1.20.1-Thtml-mem-leak.patch: src/roff/troff/node.h | 4 ---- files/groff-1.20.1-Thtml-mem-leak.patch:diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp files/groff-1.20.1-Thtml-mem-leak.patch:--- a/src/roff/troff/node.cpp files/groff-1.20.1-Thtml-mem-leak.patch:+++ b/src/roff/troff/node.cpp files/groff-1.20.1-Thtml-mem-leak.patch:+inline node::~node() files/groff-1.20.1-Thtml-mem-leak.patch: class charinfo_node : public node { files/groff-1.20.1-Thtml-mem-leak.patch:@@ -4643,7 +4651,7 @@ void hline_node::tprint(troff_output_file *out) files/groff-1.20.1-Thtml-mem-leak.patch:@@ -4651,6 +4659,7 @@ void hline_node::tprint(troff_output_file *out) files/groff-1.20.1-Thtml-mem-leak.patch:diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h files/groff-1.20.1-Thtml-mem-leak.patch:--- a/src/roff/troff/node.h files/groff-1.20.1-Thtml-mem-leak.patch:+++ b/src/roff/troff/node.h files/groff-1.20.1-Thtml-mem-leak.patch:@@ -132,10 +132,6 @@ inline node::node(node *n, statem *s, int divlevel) files/groff-1.20.1-Thtml-mem-leak.patch:-inline node::~node() files/groff-1.20.1-Thtml-mem-leak.patch: int node_list_ends_sentence(node *); files/groff-1.20.1-double-frees-mem-leaks.patch:@@ -2213,14 +2213,15 @@ node *environment::make_tag(const char *nm, int i) files/groff-1.20.1-double-frees-mem-leaks.patch:- return new special_node(*m); files/groff-1.20.1-double-frees-mem-leaks.patch:+ return new special_node(m);
"files/groff-1.20.1-Thtml-mem-leak.patch:+inline node::~node()" が見えます…。あやしい。この patch を見てみましょう。
--- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -1811,6 +1811,14 @@ void suppress_output_file::really_transparent_char(unsigned char) { } +inline node::~node() +{ + if (state != 0) + delete state; + if (push_state != 0) + delete push_state; +} + /* glyphs, ligatures, kerns, discretionary breaks */ class charinfo_node : public node {
node.cpp に inline な関数が書かれています。 inline な関数は出現したところにコードが埋められる(ちょっと適当)ので、(基本的に)他から読まれない *.cpp に inline 関数があるとリンクが失敗しそうで、さっきのエラーとあっています。ここの inline を消して buildしてみましょう。
% edit files/groff-1.20.1-Thtml-mem-leak.patch % ebuild groff-1.20.1-r3.ebuild digest % emerge -1 groff
として、無事 build できました。
まとめると
こんな感じですね。次回(あるかどうか…)お楽しみに。