NDKで複数の共有ライブラリを1つにまとめて巨大共有ライブラリを作るには

6,211 views
Skip to first unread message

tueda

unread,
Mar 14, 2011, 5:26:19 AM3/14/11
to android-g...@googlegroups.com
こんにちは。


NDKで複数の共有ライブラリ(libA.so, libB.so, libC.so)を1つにまとめて
(libZ.so)を作りたいのですが、
この時のAndroid.mkの書き方がよくわかりません。
やりたいことは通常のgccの--whole-archive libA.so libB.so libC.so --no-
whole-archiveと同様に
リンク先のバイナリを全て取り込む事です。

普通に
LOCAL_SHARED_LIBRARIES := libA.so libB.so libC.so
と書くと、後でJava側から全ての共有ライブラリをロードする必要があります
(それで動くことは動く)。
いろいろ調べると
LOCAL_WHOLE_STATIC_LIBRARIES := libA.so libB.so libC.so
というのが近い気がするのですが、やはり取り込んでくれません。
(そもそもSTATICなところに.soを突っ込むのが間違えている気がする...)

libA.so, libB.so, libC.so --> libZ.so
というように複数の共有ライブラリを1つの共有ライブラリにするには、どうす
ればいいでしょうか。
あるいは無理そうならスタティックライブラリからでもいいです。
libA.a, libB.a, libC.a --> libZ.so

Suzuki Naoto

unread,
Mar 14, 2011, 10:40:11 AM3/14/11
to android-g...@googlegroups.com
tueda 様

鈴木@triTech です。

> NDKで複数の共有ライブラリ(libA.so, libB.so, libC.so)を1つにまとめて
> (libZ.so)を作りたいのですが、
> この時のAndroid.mkの書き方がよくわかりません。

> あるいは無理そうならスタティックライブラリからでもいいです。


> libA.a, libB.a, libC.a --> libZ.so

include $(CLEAR_VARS)

LOCAL_MODULE := Z
LOCAL_SRC_FILES := ...

LOCAL_STATIC_LIBRARIES := A B C

include $(BUILD_SHARED_LIBRARY)

という感じで、できませんかね?

以上

tueda

unread,
Mar 15, 2011, 4:16:32 AM3/15/11
to android-g...@googlegroups.com
tuedaです。

いろいろ調査&試行錯誤した結果、現状でこれはできないようです。

>> NDKで複数の共有ライブラリ(libA.so, libB.so, libC.so)を1つにまとめて
>> (libZ.so)を作りたいのですが、
>> この時のAndroid.mkの書き方がよくわかりません。

上の方法はあきらめて、下の複数のスタティックライブラリから1つの共有ライ
ブラリを作るのは多分成功しました。
(そのライブラリを使ったアプリは1秒でクラッシュしましたが、期待した絵は
出たので多分大丈夫)

>> あるいは無理そうならスタティックライブラリからでもいいです。
>> libA.a, libB.a, libC.a --> libZ.so
>

いろいろ手順が複雑で過不足無く理解しているか不安ですが、
わかった手順をまとめておきます。

1. スタティックライブラリのコンパイル(libA.a libB.a libC.a)
BUILD_STATIC_LIBRARYを指定してコンパイル。
(注意)現状のNDKだとなぜかBUILD_STATIC_LIBRARYの時に限って
Application.mkでAPP_MODULESの 指定が必要。
これを指定しないとndk-buildを呼んでも何もおきません。

2. 共有ライブラリのコンパイル(libZ.so)
コンパイルした.aとヘッダーファイルをexternal/includeまたはlibの下にコ
ピーしてAndroid.mkを修正。
使用中のAndroid.mkをそのまま張り付けています。少し見にくいです。すみません。

LOCAL_PATH := $(call my-dir)

# libpng.a用
include $(CLEAR_VARS)
LOCAL_MODULE := prebuild-libpng
LOCAL_SRC_FILES := external/lib/libpng.a
include $(PREBUILT_STATIC_LIBRARY)

# libm3g-reader-writer.a用
include $(CLEAR_VARS)
LOCAL_MODULE := prebuild-libm3g-reader-writer
LOCAL_SRC_FILES := external/lib/libm3g-reader-writer.a
include $(PREBUILT_STATIC_LIBRARY)

# libm3g.so用
include $(CLEAR_VARS)
LOCAL_MODULE := libm3g
LOCAL_SRC_FILES := AnimationController.cpp \
(以下省略)
LOCAL_CPPFLAGS := -fexceptions -frtti
LOCAL_LDLIBS := -lGLESv1_CM -llog -lz
LOCAL_WHOLE_STATIC_LIBRARIES := prebuild-libm3g-reader-writer \
prebuild-libpng
#LOCAL_STATIC_LIBRARIES := prebuild-libm3g-reader-writer \
# prebuild-libpng
LOCAL_C_INCLUDES := ./include ./jni/external/include
include $(BUILD_SHARED_LIBRARY)

ポイントは、
・スタティックライブラリ毎にモジュールを定義してPREBUILD_STATIC_LIBRARY
でコンパイルする(実際はただのコピー)。
・共有ライブラリのコンパイル時にLOCAL_STATIC_LIBRARIESもしくは
LOCAL_WHOLE_STATIC_LIBRARIESで上のモジュールを指定する
 (全部取り込みたいときはWHOLE_STATICの方、使用するものだけ取り込みたい
ときはSTATICの方)
・LOCAL_WHOLE_STATIC_LIBRARIESは現在(2011/03/15)のNDKのバージョンで
は$NDK_ROOT /toolchains/arm-linux-androideabi-4.4.3/setup.mkの修正が必要。
 具体的には'whole-archive-list-flags' を'link-whole-archive-flags'に変
更する。
http://groups.google.com/group/android-ndk/browse_thread/thread/81683168dd574420/6ed49f3fd2693825


3. その他の気づいたこと
よく考えると通常.aから.soを作ることはできません(-fPICつけてコンパイルし
てないから)。
で、不思議だなあと思っていろいろググルとAndroidのツールチェーンだとデ
フォルトで-fPICが強制されているようです。
http://groups.google.com/group/android-ndk/browse_thread/thread/9fd148aa92a6fab6/863a4c0b3c9fdc47
というわけで難しいことを考えなくても共有ライブラリが作れるようです。

Reply all
Reply to author
Forward
0 new messages