13

armv6用のライブラリを構築したいのですが、デバイスがサポートしている場合に実行時に有効にするネオンコードがいくつかあります。ネオンコードはネオン組み込み関数を使用しており、コンパイルできるようにするには、armeabi-v7aを有効にする必要がありますが、これは通常のcコードに影響します(一部のローエンドデバイスでは壊れます)。

したがって、Androidビルドシステムが過度に煩わしくない場合は、質問する必要はありませんが、armv6用に1つのファイルをコンパイルし、arm7-neon用にもう1つのファイルをコンパイルする方法はないようです。

それが実行可能であれば、誰かが手がかりを与えることができますか?

編集
返信してinternet-inkを無駄にする前に、これらが主なポイントであることを明確にする必要があります
。1)1つのlibのみを作成します。
2) armv6(pre neonデバイス、たとえばarmeabi)で実行されるビルドを作成します。
3)このビルドにNEONコードも含めることを許可します(実行時のCPU検出に基づいて実行できます。CPU検出は質問の範囲外です)。
4) NEONコードはac / cppファイルから取得され、neon組み込み関数を使用して記述されます。

これらの要件のいずれかの部分を省略すると、問題のポイントが完全に失われます

4

6 に答える 6

12

最近、NDKの制限を回避する別の方法を見つけました。私のケースはNEONとは関係ありませんでしたが、あなたにとっては同じハックでうまくいく可能性があります。

秘訣は、NDKの既存の「タグ」メカニズムを使用してCFLAGS、一連のファイルに特別なものを指定することです。これがあなたのやり方です:

まず、ネオン固有のソースをリストします。build-binary.mkは、armeabi-v7aをターゲットにしていないことを検出するため、 docs/CPU-ARM-NEON.html.neonで説明されているサフィックスを使用することはできません。私は次のテクニックを使用します:

LOCAL_NEON_SRC_FILES := imgproc/neon_utils.c \
                        videoproc/usingneon.cpp
LOCAL_SRC_FILES := main.c \
                   imgproc/img.c \
                   videoproc/video.cpp

LOCAL_SRC_FILES += $(LOCAL_NEON_SRC_FILES)

CFLAGSここで、 NEONのを定義します。

LOCAL_NEON_CFLAGS := -mfloat-abi=softfp -mfpu=neon -march=armv7

最後に、Android.mkに次の魔法の行を追加します。

TARGET-process-src-files-tags += $(call add-src-files-target-cflags, $(LOCAL_NEON_SRC_FILES), $(LOCAL_NEON_CFLAGS))

ビルドするバイナリが複数ある場合は、次の$(LOCAL_NEON_SRC_FILES)方法でリセットすることをお勧めします。

include $(CLEAR_VARS)

このために、Android.mkまたはに以下を追加しますApplication.mk

modules-LOCALS += NEON_SRC_FILES

注:私はこの魔法をNEONで試したことがないので、まったく別の目的で必要でした。ファイルおよびプロジェクトに必要なコンパイルオプションを実現するには、いくつかの調整が必要になる場合があります。NDK r.8bを使用していますが、これが以前の(または後の)バージョンで機能するかどうかを確認していません。

于 2012-09-02T09:18:12.287 に答える
4

NEONコードを別のモジュール(静的ライブラリまたは共有ライブラリ)に配置すると、 Android.mk内のそのモジュールのCFLAGSを必要に応じて手動で調整できます。

組み込み関数の周りに#ifdef__ARM_NEON__を使用するCファイルがある場合、最良の選択は、これらのファイルを共有ライブラリに配置することです。1つはv6用にコンパイルされ、もう1つはneon用にコンパイルされます。

私は通常、このような「補足」ライブラリをJavaから直接ロードするため、メインのネイティブコードはこれらの変更をまったく気にしません。


更新:静的ライブラリを使用する簡単な例を次に示します。

Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := neon_utils
LOCAL_SRC_FILES := neon_add.c
LOCAL_CFLAGS += -mfloat-abi=softfp -mfpu=neon -march=armv7
include $(BUILD_STATIC_LIBRARY)

NDK_PATH:=$(call my-dir)/../..

include $(CLEAR_VARS)
LOCAL_MODULE    := test_conditional_load
LOCAL_C_INCLUDES := $(NDK_PATH)/sources/cpufeatures
LOCAL_SRC_FILES := main.c
LOCAL_STATIC_LIBRARIES  :=  neon_utils cpufeatures

include $(BUILD_EXECUTABLE)

include $(NDK_PATH)/sources/cpufeatures/Android.mk

main.c

#include <stdio.h>
#include <cpu-features.h>

void neon_add(int32_t * ptr);

int main()
{
    int32_t int32_4[] = {2,3,4,5};

    if (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON)
    {
        neon_add(int32_4);
        printf("neon\n");
    }
    else
    {
        printf("not neon\n");
    }
    printf("values = %d, %d, %d, %d\n", int32_4[0], int32_4[1], int32_4[2], int32_4[3]);
    return 0;
}

neon_add.c

#include <arm_neon.h>

void neon_add(int32_t * ptr)
{
    int32x4_t vin = vld1q_s32(ptr);
    int32x4_t vout = vaddq_s32(vin, vin);
    vst1q_s32(ptr, vout);
}
于 2012-06-12T15:46:43.723 に答える
2

このリンクを使用する http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html

.neonファイルのサフィックスを使用して、NEONをサポートする特定のソースファイルを選択的にビルドできます。うまくいけば、これがABIの選択に当てはまるかどうかを判断できます...

NEONコードパスを1つのファイルに入れることができる場合があり、上記のようにmake fileを条件付きで使用して、ターゲットとするABIに基づいて正しいファイルを作成することを選択します。

于 2012-03-27T01:11:03.880 に答える
1

ドキュメントからのこのスニペットはおそらく役に立ちます:

   # define a static library containing our NEON code
   ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
      include $(CLEAR_VARS)
      LOCAL_MODULE    := mylib-neon
      LOCAL_SRC_FILES := mylib-neon.c
      LOCAL_ARM_NEON  := true
      include $(BUILD_STATIC_LIBRARY)
   endif # TARGET_ARCH_ABI == armeabi-v7a

これは、さまざまなABIに同じAndroid.mkファイルを使用している場合でも、armeabi-v7aを使用している場合にのみmylib-neonをコンパイルします。armeabi v6の場合、完全にスキップされます。

于 2011-10-06T19:32:57.720 に答える
0

より単純な実装を探している場合:

まず、すべてのNEON対応コードがABI armeabi-v7aに対してのみ条件付きでコンパイルされ、さらに、実行時にNEONを含むARMv7実装で実行されている場合にのみ実行されることを確認します。

/* 
   bar_better_on_neon.c
 */

#ifdef HAVE_ARMV7
#  include <arm_neon.h>
#  ifdef ANDROID
#    include "cpu-features.h"
#  endif
#endif

#ifdef HAVE_ARMV7 
static int check_for_neon(void)
{
#  ifdef ANDROID
    // Not all Android devices with ARMv7 are guaranteed to have NEON, so check.
    uint64_t features = android_getCpuFeatures();
    return (features & ANDROID_CPU_ARM_FEATURE_ARMv7) && (features & ANDROID_CPU_ARM_FEATURE_NEON);
#  elif defined(__APPLE__)
    return 1;
#  else
    return 0;
#  endif
}
#endif

void bar(void)
{
#ifdef HAVE_ARMV7
    if (check_for_neon()) {

        /* here put neon code */

    } else {
#endif

        /* here put non-neon code */

#ifdef HAVE_ARMV7
    }
#endif
}

ここでは、check_for_neon()はNDKのcpufeaturesライブラリを使用しています。次に、Android.mkファイルで:

LOCAL_SRC_FILES := foo.c bar_better_on_neon.c
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
  # Compile the one file in NEON mode.
  LOCAL_SRC_FILES := $(subst bar_better_on_neon.c, bar_better_on_neon.c.neon,$(LOCAL_SRC_FILES))
  LOCAL_CFLAGS += -DHAVE_ARMV7=1
endif
于 2015-07-29T03:26:04.733 に答える
-1

はい、Application.mkファイルに次を追加します。

APP_ABI := armeabi armeabi-v7a
LOCAL_ARM_NEON := true

NDKはarmeabilibsにNEONサポートを追加しません。これらは相互に排他的であるため、これらの行を追加して通常どおりにコンパイルすると、2つの別個のsoファイルが生成されます。それらの両方をエクスポート先のディレクトリ構造のapkに含めると、サポートされている場合、デバイスはネオンを自動的にロードします。

于 2012-07-11T18:28:16.533 に答える