[[diary/Kojima]]

・Qt-4.8.1と-fvisibility(2)

当初はQtのライブラリをnmで調べると"no symbols"と言われるのが原因かと思って,
ビルド時にlinux.confで設定されている--strip-unneededを--strip-debugにして
デバッグシンボルだけを削除するようにしてみたのだけど,
libdbusmenu-qtがコンパイルできない状況は変わらず.

 後から分かったけど,--strip-unneededした共有ライブラリの場合,
 nmだけではシンボルが表示されないけど,-Dを指定すると動的シンボルは
 表示されるので,共有ライブラリをリンクするのに問題は無いらしい.

さて,それでは何が原因か,,と悩んでいたところ,解決は全然別のところから見つかった.

libdbusmenu-qtがビルドできないのは放置して,kdelibs-4.8.3をビルドしようとすると,
configure時にQtが--fvisibility=hiddenでビルドされていないぞ,と言うエラーが出た.

 /check_qt_visibility.cpp:5:3: エラー: #error QT_VISIBILITY_AVAILABLE 
     is not available
 ...
 CMake Error at cmake/modules/FindKDE4Internal.cmake:1295 (message):
   Qt compiled without support for -fvisibility=hidden.  This will break
   plugins and linking of some applications.  Please fix your Qt installation
   (try passing --reduce-exports to configure).
 Call Stack (most recent call first):
   CMakeLists.txt:50 (find_package)

見たことのないタイプのエラーだったのであれこれ調べてみたところ,-fvisibility=hidden
というのはGCC4系で採用された新しいオプションで,
クラス宣言等でシンボルの数が膨大になりがちなC++のライブラリの,
内部向けのシンボルを外部には見せなくするためのオプションらしい.

なるほど,g++にはこういうオプションがあったのか,と思って,改めてQtのソースコードを見てみると,
Qt-4.7.1ではconfigure_REDUCE_EXPORTS.patchとして,

 --- qt-kde-qt/configure 2010-09-07 06:05:01.000000000 +0900
 +++ build/configure     2011-02-13 22:29:59.000000000 +0900
 @@ -730,7 +730,7 @@
  CFG_PRECOMPILE=auto
  CFG_SEPARATE_DEBUG_INFO=auto
  CFG_SEPARATE_DEBUG_INFO_NOCOPY=no
 -CFG_REDUCE_EXPORTS=auto
 +CFG_REDUCE_EXPORTS=yes
  CFG_MMX=auto
  CFG_3DNOW=auto
  CFG_SSE=auto

こんなのを当ててたのだけど,4.8.1のビルド時にはこれを外していたのに気がついて,
このパッチを当てるようにQt-4.8.1をビルドし直してやったところ,
無事libdbusmenu-qtのビルドも通るようになった.

このオプションで,生成されるバイナリがどの程度変るのかと思って,
libdbusmenu-qtがビルドできなかったライブラリ(NG)とできるようになったライブラリ(OK)
を比較してみたところ,

 NG$ nm -C -D usr/lib64/libQtCore.so.4.8.1 | grep " T " | wc -l
 4812

 OK$ nm -C -D usr/lib64/libQtCore.so.4.8.1 | grep " T " | wc -l
 3699

ということで,1100個くらいシンボル数が減っていて,
どうやら本来は外部には見せるべきでないシンボルを公開してしまっていたので,
libdbusmenu-qtのテストコードのリンクに失敗していた,ということらしい.

また,この設定はパッチにしなくても,kdelibsのエラーメッセージにあるように,
configureに-reduce-exports=yesという指定を与えればOKらしい

 reduce-exports)
       if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
           CFG_REDUCE_EXPORTS="$VAL"
       else
           UNKNOWN_OPT=yes
       fi
       ;;

BLFSのQtのビルド方法(http://www.linuxfromscratch.org/blfs/view/svn/x/qt4.html)
にはこの種の指定が無いので,LFSが採用しているGCC-4.7.0では,
自動的に良きに計らってくれるのかも知れないけど,そこまでは調べていない.

何とかこれでQt-4.8.1ベースのKDEのビルドに取りかかれそうだけど,
そろそろ授業準備(今年は2ヶ月遅くなった)でビジーモードになっているのであった..

#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS