3

Eclipseでビルド構成を変更するときに、Android NDKに特定のライブラリを再構築させる方法はありますか?

AndroidNDKを使用してC++ライブラリを構築するAndroidプロジェクトの構築を構築しています。SequoyahプラグインでEclipseを使用しています。すべてがセットアップされ、うまく機能します。

ただし、ビルド構成で問題が発生しました。プロジェクト->プロパティを右クリックし、C / C ++ビルドセクションに移動すると、ビルド構成を管理できます。これにより、ほとんどのC++ライブラリが何らかの方法で依存する従来のデバッグビルドとリリースビルドを作成できます。

これが私の「デバッグ」構成の例です。

V=1 NDK_DEBUG=1 NDK_APPLICATION_MK=config/debug/Application.mk

これらはうまく機能しますが、構成を切り替えても、構築しているライブラリの再構築がトリガーされない点が異なります。これは、各ビルド構成が異なるディレクトリにダンプされるVisual Studioのようなもので予想されますが、Eclipseではすべてが同じディレクトリにダンプされます。再構築をトリガーするために、関連するソースファイルを実際に変更する必要があります。したがって、最終的には、デバッグ構成で(たとえば)実行されますが、リリースで構築されたライブラリにリンクすることになります。

だから私の質問は:構成を変更するときにNDKにライブラリを再構築させる方法はありますか?追加できる-Bコマンドを知っていますが、それは毎回すべてを再構築します。1つの特定のライブラリ(この場合はlibBootInfo)に対してのみ再構築できれば、毎回再構築しても問題ありません。

ルートAndroid.mkファイルは次のようになります。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := game$(MY_BUILD_CONFIG_EXTENSION)

# Include files are relative to the NDK root directly (fix by prepending with $(LOCAL_PATH))
# Source files are relative $(LOCAL_PATH)

#LOCAL_LDLIBS    := -landroid

# Add all source file names to be included in lib separated by a whitespace
LOCAL_SRC_FILES :=  ../../../../../../engine/code/main/mainandroid.cpp

# Module dependencies are expressed with LOCAL_STATIC_LIBRARIES and LOCAL_SHARED_LIBRARIES.
# we're building the "main" entry point, so it doesn't depend on much
LOCAL_STATIC_LIBRARIES := libDebug$(MY_BUILD_CONFIG_EXTENSION) libCore$(MY_BUILD_CONFIG_EXTENSION)

include $(BUILD_SHARED_LIBRARY)

$(call import-module,libBdCore)
$(call import-module,libDebug)

##################################################################
## In addition to the core game library, we also build another
## *.so file here: "libBootInfo". This very small library is used
## by Java to find out which version of game to load based on
## the current build configuration.
##

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libBootInfo

# Add all source file names to be included in lib separated by a whitespace
# TODO: This path is relative to "android-ndk\build\core" which seems
#       different from the LOCAL_SRC_FILES in game above. It seems like
#       the build process leaves us in a different directory than we started.
#       We make need to look into a way to make sure that this path always 
#       works regardless of what came before it.
#
LOCAL_SRC_FILES := ../../../../engine/code/main/bootinfo.cpp

include $(BUILD_SHARED_LIBRARY)
4

2 に答える 2

2

NDKビルドは、常に.soライブラリを更新しlib/armeabiます。一方obj、ディレクトリには、モジュールごとに、デバッグビルドとリリースビルド用の個別のツリーが含まれています。

残念ながら、Android.mktgeフレームワークでサポートされていないことを行う場合は、この設定を簡単に失敗させることができます。

たとえば、あなたの場合、cppファイル(../../../..)への長い上りパスは悪い考えかもしれません。LOCAL_PATHモジュールごとに設定し、で避けることをお勧めし../ますLOCAL_SRC_FILES

これがAndroid.mkの私の提案された変更です:

ANDROID_MK_PATH := $(call my-dir)
LOCAL_PATH := $(ANDROID_MK_PATH)/../../../engine/code/main

include $(CLEAR_VARS)

LOCAL_MODULE := game$(MY_BUILD_CONFIG_EXTENSION)
LOCAL_SRC_FILES :=  mainandroid.cpp
LOCAL_STATIC_LIBRARIES := libDebug$(MY_BUILD_CONFIG_EXTENSION) libCore$(MY_BUILD_CONFIG_EXTENSION)

include $(BUILD_SHARED_LIBRARY)

##################################################################
## In addition to the core game library, we also build another
## *.so file here: "libBootInfo". This very small library is used
## by Java to find out which version of game to load based on
## the current build configuration.
##

include $(CLEAR_VARS)

LOCAL_MODULE := libBootInfo
LOCAL_SRC_FILES := bootinfo.cpp

include $(BUILD_SHARED_LIBRARY)

$(call import-module,libBdCore)
$(call import-module,libDebug)

更新:実際には、モジュール名のサフィックスを使用してビルド構成を分離することが、私の目には最善の解決策です。このアプローチにより、一度に複数の構成を構築およびデプロイできます。たとえば、ライブラリをTegra(ネオンなし)またはSnapdragon(ネオンあり)のいずれかに最適化する必要がある場合に使用します。最近まで、Playストアに2つの別々のAPKを配置するのは簡単ではなかったため、両方をパッケージ化していましたlibv-neon.solibv-tegra.solib/armeabi-v7a

BootInfoライブラリに含まれるロジックはわかりませんが、ライブラリを1つだけデプロイする場合は、Javaクラスの静的コンストラクターで次のコードを使用することで面倒な作業をすべて回避できます。

static {
    boolean loaded = false;
    while (!loaded) {
        try {
            System.loadLibrary("game" + nextExtensionAttempt);
            loaded = true;
        } 
        catch (Exception ex) {
        }
    }
}

別のアプローチは、出力ディレクトリをオーバーライドすること./objです。この目的のために、Application.mkファイルに次の行を追加できます。

NDK_APP_OUT := obj$(MY_BUILD_EXTENSION)

このようにして、すべての.obj、、、.aおよび.soファイル(にインストールされる前libs/armeabi)は、構成ごとに別々のディレクトリに配置されます。さらに簡単に、コマンドラインでNDK_OUTパラメータを指定できます。ndk-build

ndk-build V=1 NDK_OUT=obj${MY_BUILD_EXTENSION}

Eclipseを使用して構成を維持および選択する場合、これは非常に簡単です。これにより、Javaは常に同じ名前になるため、モジュールを簡単にロードできます。ただし、一度にデプロイできるのは1つの構成のみです。

于 2012-10-20T10:06:47.777 に答える
0

私はこれを完全に正しく機能させることができませんでした。結局、空のソースファイルを書き出すバッチファイルを作成しました。そのバッチファイルは、Eclipseのビルドステップの一部として実行されます。次に、そのソースファイルをライブラリの一部として含めました。タイムスタンプはビルドするたびに変わるため、ndkをだましてそのライブラリを毎回再構築させます。ライブラリが小さく保たれ、ほとんどのコードが他のライブラリに存在することを確認して、ビルド時間を非常に短くします。

于 2012-11-15T17:48:08.247 に答える