torutkのブログ

ソフトウェア・エンジニアのブログ

Solaris 10 x86/SunStudio 11コンパイラでCppUnit-1.12.0がビルドエラー

C++単体テストツールの主流であるCppUnitです。https://sourceforge.net/projects/cppunit/

これが、最新版の1.12.0をSolaris上でSunStudio C++コンパイラを使ってビルドするとエラーとなってしまいます。
エラーはlibcppunit-1.12.soのリンク時に発生します。

CC -G -zdefs -nolib -hlibcppunit-1.12.so.0 -o ./libs/libcppunit-1.12.so.0.0.0 
.libs/AdditionalMessage.o .libs/Asserter.o ... -mt
未定義の                          最初に参照している
シンボル                            ファイル
std::ostream &std::ostream::operator<<(int) .libs/CompilerOutputter.o
std::ostream &std::ostream::operator<<(double) .libs/StringTools.o
fabs                                .libs/TestAssert.o
void __Crun::pure_error()         .libs/CompilerOutputter
  :

以前のバージョン1.10.2では、ビルドでのエラーは発生しません。

CC -G -nolib -hlibcppunit-1.10.so.2 -o .libs/libcppunit-1.10.so.2.0.0 .libs/AdditionalMessage.o ....

違いは、リンク時のコマンドラインオプションに、-zdefsがあるかどうかの違いです。
この-zdefsとは何者でしょうか?

いろいろ検索して調べるとSunの技術フォーラムで言及がありました。
http://forum.sun.com/jive/thread.jspa?threadID=71111&messageID=261346
これによると、動的リンクライブラリをビルドするときは未定義シンボルがあってもかまわず生成してしまうので、実行時に不足分があるとエラーとなってしまうが、-zdefsを付けると、ビルド時点で未定義シンボルがあるとエラーとしてしまうとのことです。

今回未定義でエラーになったシンボルは、libCstd(libCrun)が持っているものです。したがって、-zdefsを削除するか、リンクにlibCrunを指定するかで回避できるように思われます。

回避策

configureのオプションで、-nolibsオプションによって本来標準でリンクされたはずのライブラリをリンクするよう指定する方法でビルド可能です。

$ ./configure CC=cc CXX=CC CXXFLAGS="-pta -instances=global -mt \
-xtarget=generic -g -features=no%transitions" LD=CC LDFLAGS="-lCstd \
-lCrun -lc -lm"