FreeBSDのportsで、math/octaveをportupgrade中に、こんなエラーがでて終了・・・
making gendoc.cc
g++44 -O2 -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/local/include -o gendoc gendoc.cc -L/usr/local/lib -pthread
making DOCSTRINGS
/libexec/ld-elf.so.1: /usr/lib/libstdc++.so.6: version GLIBCXX_3.4.11 required by ./gendoc not found
gmake[2]: *** [DOCSTRINGS] エラー 1
gmake[2]: ディレクトリ `/WORK/usr/ports/math/octave/work/octave-3.2.2/src' から出ます
gmake[1]: *** [src] エラー 2
gmake[1]: ディレクトリ `/WORK/usr/ports/math/octave/work/octave-3.2.2' から出ます
gmake: *** [all] エラー 2
*** Error code 1
Stop in /usr/ports/math/octave.
ちなみに、octaveは、USE_FORTRAN=yes になっているので、portsのバージョンが上がったみたい。
ちょっと調べてみました。
# ./gendoc
/libexec/ld-elf.so.1: /usr/lib/libstdc++.so.6: version GLIBCXX_3.4.11 required by ./gendoc not found
なるほど、実行できませんね。
% nm -C gendoc | grep GLIBCXX_3.4.11
U _ZNKSt5ctypeIcE13_M_widen_initEv@@GLIBCXX_3.4.11
GLIBCXX_3.4.11って、これのことですか。なるほど、symbol versioningってやつのことみたいですね。
えーと・・・
# ldd gendoc
gendoc:
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x480f9000)
libm.so.5 => /lib/libm.so.5 (0x481ee000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x48203000)
libthr.so.3 => /lib/libthr.so.3 (0x4820e000)
libc.so.7 => /lib/libc.so.7 (0x48223000)
なるほど、たぶん、違うバージョンのGCCの共有ライブラリが使われている、というわけで。
というか、g++44、「/usr/local/bin/g++44」でコンパイルしているのに、/usr/lib/libstdc++.so.6 が使われている時点で、そりゃおかしくないか? ですね。
ふときがつけば、「libstdc++.so.6」って、同じ名前のファイルが、いくつもあるんですけど・・・
# ls -l /usr/local/lib/gcc*/libstdc++.so.6 /usr/lib/libstdc++.so.6
-r--r--r-- 1 root wheel 981660 8 26 17:51 /usr/lib/libstdc++.so.6
-rwxr-xr-x 1 root wheel 4419577 9 17 09:57 /usr/local/lib/gcc43/libstdc++.so.6
-rwxr-xr-x 1 root wheel 4560445 9 14 11:21 /usr/local/lib/gcc44/libstdc++.so.6
ついでに、libgcc_s.so.1も複数あるし。
# ls -1 /lib/libgcc_s.so.1 /usr/local/lib/gcc*/libgcc_s.so.1
/lib/libgcc_s.so.1
/usr/local/lib/gcc43/libgcc_s.so.1
/usr/local/lib/gcc44/libgcc_s.so.1
/usr/libのほうは・・・GLIBCXX_3.4.11というのが入ってない。
% strings /usr/lib/libstdc++.so.6|grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_FORCE_NEW
一方、GCC 4.4のほうは・・・あります。
% strings /usr/local/lib/gcc44/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
おまけ。GCC 4.3だけど、まあ、これはどうでもいいけど。
% strings /usr/local/lib/gcc43/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
というわけで、/usr/local/lib/gcc44 にある共有ライブラリが使われるようにすればOKなはずなので、たとえばLD_LIBRARY_PATHを使ってやれば
# env LD_LIBRARY_PATH=/usr/local/lib/gcc44 ldd gendoc
gendoc:
libstdc++.so.6 => /usr/local/lib/gcc44/libstdc++.so.6 (0x480f9000)
libm.so.5 => /lib/libm.so.5 (0x481e3000)
libgcc_s.so.1 => /usr/local/lib/gcc44/libgcc_s.so.1 (0x481f8000)
libthr.so.3 => /lib/libthr.so.3 (0x48204000)
libc.so.7 => /lib/libc.so.7 (0x48219000)
これで、実行できるようになります。
ですが、LD_LIBRARY_PATHを指定しないといけない、ってのは正常とは思えません。
ldconfigがおかしいのかな?と思ったのですが
# ldconfig -r
/var/run/ld-elf.so.hints:
search directories: /lib:/usr/lib:/usr/lib/compat:/usr/local/lib:/usr/local/lib/compat/pkg:/usr/local/kde4/lib:/usr/local/lib/compat:/usr/local/lib/evolution/2.26:/usr/local/lib/gcc/i386-portbld-freebsd7.2/3.4.6:/usr/local/lib/gcc43:/usr/local/lib/gegl-0.0:/usr/local/lib/graphviz:/usr/local/lib/mysql:/usr/local/lib/nss:/usr/local/lib/pth:/usr/local/lib/qt4:/usr/local/lib/wine:/usr/local/lib/zsh:/usr/local/libexec/openldap:/usr/local/sge/lib/fbsd-i386:/usr/local/lib/virtualbox:/usr/local/lib/gcc44
0:-lc.7 => /lib/libc.so.7
1:-lcrypt.4 => /lib/libcrypt.so.4
(以下省略)
こういう順番でディレクトリを検索していくので、共有ライブラリが同じファイル名である以上、/usr/libが見つかってしまうのは、しかたなし。
LD_LIBRARY_PATHは使わずに、コンパイル時に、rpath(runpath, runtime shared library search path)を指定すれば、まあ、とりあえずOKかな、と。
% g++44 -O2 -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/local/include -o gendoc gendoc.cc -L/usr/local/lib -pthread -Wl,--rpath,/usr/local/lib/gcc44
% ldd gendoc
gendoc:
libstdc++.so.6 => /usr/local/lib/gcc44/libstdc++.so.6 (0x480f9000)
libm.so.5 => /lib/libm.so.5 (0x481e3000)
libgcc_s.so.1 => /usr/local/lib/gcc44/libgcc_s.so.1 (0x481f8000)
libthr.so.3 => /lib/libthr.so.3 (0x48204000)
libc.so.7 => /lib/libc.so.7 (0x48219000)
ただ、わざわざこんな「-Wl,--rpath,/usr/local/lib/gcc44」というオプションを追加しなくちゃいけない、ってのはなんか間違っている気がします。
portsのgcc44で、このへんを、ケアしてもらえないんでしょうかね。
GNU C++ (GCC) version 4.4.2 20090908 (prerelease) (i386-portbld-freebsd7.2)
compiled by GNU C version 4.4.2 20090908 (prerelease), GMP version 4.3.1, MPFR version 2.4.1.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 5feec5ea47297b9f3ff6755b82d5a555
COMPILER_PATH=/usr/local/libexec/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/:/usr/local/libexec/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/:/usr/local/libexec/gcc44/gcc/i386-portbld-freebsd7.2/:/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/:/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/
LIBRARY_PATH=/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/:/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-O2' '-fno-strict-aliasing' '-pipe' '-I/usr/local/include' '-I/usr/local/include' '-o' 'gendoc' '-L/usr/local/lib' '-pthread' '-shared-libgcc' '-mtune=i386'
/usr/local/libexec/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/collect2 -V -dynamic-linker /libexec/ld-elf.so.1 -o gendoc /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/crtbegin.o -L/usr/local/lib -L/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2 -L/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/../../.. /tmp//ccM05ca2.o -lstdc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/crtend.o /usr/lib/crtn.o
GNU ld version 2.15 [FreeBSD] 2004-05-23
Supported emulations:
elf_i386_fbsd
☆
もしかして、g++44でコンパイルしたC++なプログラムって、ことごとく動かないんじゃ・・・
試してみよう。
#include <iostream>
int
main( int argc, char* argv[] )
{
std::cout << "Hello world" << std::endl;
return 0;
}
% g++44 hello.cc
% ldd a.out
a.out:
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x4807d000)
libm.so.5 => /lib/libm.so.5 (0x48172000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x48187000)
libc.so.7 => /lib/libc.so.7 (0x48192000)
% ./a.out
Hello world
あれ?本来とは違う共有ライブラリが使われているのに、動いちゃいますね。
% strings a.out|grep GLIBC
GLIBCXX_3.4
というわけで、新しいライブラリの必要としないみたい。
ただし、コンパイル時は、/usr/local/lib/gcc44/gcc/以下の共有ライブラリが参照されています。
% g++44 -Wl,--verbose hello.cc
GNU ld version 2.15 [FreeBSD] 2004-05-23
Supported emulations:
elf_i386_fbsd
using internal linker script:
==================================================
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd",
"elf32-i386-freebsd")
OUTPUT_ARCH(i386)
省略
attempt to open /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/libstdc++.so failed
attempt to open /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/libstdc++.a failed
attempt to open /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/../../../libstdc++.so succeeded
-lstdc++ (/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/../../../libstdc++.so)
省略
attempt to open /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/libgcc_s.so failed
attempt to open /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/libgcc_s.a failed
attempt to open /usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/../../../libgcc_s.so succeeded
-lgcc_s (/usr/local/lib/gcc44/gcc/i386-portbld-freebsd7.2/4.4.2/../../../libgcc_s.so)
portsでインストールしたGCCを使うときは、rpathが自動的に追加されるようにならないかなぁ~。
0 件のコメント:
コメントを投稿