Android build system, neon i non-Neon buduje
Chcę zbudować moją bibliotekę dla armv6, i jest jakiś kod neonowy, który włączam w czasie wykonywania, jeśli urządzenie GO obsługuje. Kod neon używa Neon intrinsics i aby móc go skompilować, muszę włączyć armeabi-v7a, ale to wpływa na zwykły kod c(staje się zepsuty na niektórych urządzeniach low-end).
Tak więc, jeśli system budowania Androida nie był zbyt natrętny, nie musiałbym zadawać pytań, ale wygląda na to, że nie ma sposobu, aby skompilować jeden plik dla armv6, a drugi dla arm7-neon
Czy ktoś może podać jakieś wskazówki, jeśli jest to wykonalne?
Edit
Zanim spróbujesz odpowiedzieć i marnować Internet-ink, powinno być jasne, że są to główne punkty:
1) zrób tylko jedną lib.
2) tworzy build, który działa na armv6(przed neonami, np. armeabi).
3) pozwól, aby ta kompilacja zawierała również kod NEON (który może być wykonany w oparciu o detekcję procesora w czasie wykonywania; Detekcja procesora jest poza zakresem pytanie).
4) kod NEON pochodzi z pliku c / cpp i jest napisany przy użyciu Neon intrinsics.
Pominięcie jakiejkolwiek części tych wymagań całkowicie traci punkt pytania
6 answers
Ostatnio znalazłem inny sposób na obejście ograniczeń NDK. Moja sprawa nie była związana z neonem, ale dla Ciebie ten sam hack mógłby to zrobić.
Sztuczka polega na użyciu istniejącego mechanizmu "tag" w NDK, aby określić specjalne CFLAGS
dla kilku plików. Tak to się robi:
Najpierw wymień źródła neonowe. Nie można użyć przyrostka .neon
, jak opisano w docs/CPU-ARM-NEON.html ponieważ build-binary.mk stwierdzi, że nie kierujesz armeabi-v7a. używam następującej techniki:
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)
Zdefiniuj CFLAGS
dla neonu:
LOCAL_NEON_CFLAGS := -mfloat-abi=softfp -mfpu=neon -march=armv7
Na koniec dodaj następującą magiczną linię do swojego Android.mk:
TARGET-process-src-files-tags += $(call add-src-files-target-cflags, $(LOCAL_NEON_SRC_FILES), $(LOCAL_NEON_CFLAGS))
Jeśli masz więcej niż jeden plik binarny do zbudowania, prawdopodobnie będziesz chciał, aby $(LOCAL_NEON_SRC_FILES)
został zresetowany przez
include $(CLEAR_VARS)
W tym celu dodaj do swojego Android.mk
lub do Application.mk
:
modules-LOCALS += NEON_SRC_FILES
Uwaga: [29]} nie próbowałem tej magii dla neonu, potrzebowałem jej do zupełnie innych celów. Możesz potrzebować adaptacje w celu uzyskania pożądanych opcji kompilacji dla Twoich plików i dla Twojego projektu. Używam NDK r. 8b i nie sprawdzałem, czy to zadziała na wcześniejszych (czy późniejszych) wersjach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-02 09:18:12
Jeśli umieścisz kod NEON w oddzielnym module (biblioteka statyczna lub biblioteka współdzielona), możesz ręcznie dostroić CFLAGS dla tego modułu w swoim Android.mk za twoje pragnienie.
Jeśli masz pliki C, które używają #ifdef __ARM_NEON__ wokół intrinsics, najlepszym wyborem będzie umieszczenie tych plików w bibliotekach współdzielonych - jedna skompilowana dla v6, druga dla neon.
Zwykle Ładuję takie" supplimentowe " biblioteki bezpośrednio z Javy, tak aby główny kod natywny w ogóle nie dbają o te zmiany.
Update: Oto prosty przykład wykorzystujący statyczną bibliotekę:
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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-14 08:36:22
Używając tego linku http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
Można selektywnie budować pewne pliki źródłowe z obsługą NEON za pomocą .Neon file sufiks. Mam nadzieję, że uda ci się ustalić, czy dotyczy to wyboru ABI...
Możesz umieścić ścieżkę kodu neonowego w jednym pliku i używając opcji make File conditional, jak pokazano powyżej Wybierz, aby zbudować poprawny plik na podstawie którego ABI kierujesz
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-27 01:11:03
Ten fragment z dokumentacji prawdopodobnie pomoże:
# 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
To kompiluje tylko mylib-neon podczas używania armeabi-v7a, nawet jeśli używasz tego samego Android.mk plik dla różnych ABIs. Dla armeabi v6 pominie go całkowicie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-06 19:32:57
Jeśli szukasz prostszej implementacji:
Po pierwsze, upewnij się, że cały kod obsługujący NEON jest warunkowo kompilowany tylko dla ABI armeabi-v7a, a dodatkowo będzie wykonywany tylko wtedy, gdy jest uruchomiony na implementacji ARMv7, która zawiera NEON:
/*
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
}
Tutaj check_for_neon()
używa biblioteki cpufeatures NDK. Wtedy, w Twoim Android.mk plik:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-29 03:26:04
Tak, w Twoim Application.mk Dodaj plik:
APP_ABI := armeabi armeabi-v7a
LOCAL_ARM_NEON := true
NDK nie doda neonów do libs armeabi, ponieważ są one wzajemnie się wykluczające, po prostu dodanie tych linii i skompilowanie jak zwykle spowoduje powstanie dwóch oddzielnych plików so. Dołączasz je do swojego apk w strukturze katalogów, do których zostały wyeksportowane, a urządzenie automatycznie załaduje neon, jeśli jest obsługiwane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-11 18:28:16