2017-09-13 2 views
1

Wir haben vor kurzem CPU-Funktionen hinzugefügt, um Plattformfunktionen wie ARMV8 und CRC, AES und SHA zu erkennen. Wir haben eine bug report zum Bauen gegen das neueste NDK gefangen. Wenn wir schließen <cpu-features.h> in einem armeabi Projekt versuchen, führt dies zu:Wie benutzt man das CPU-Feature in einer nativen Bibliothek?

$ make -f GNUmakefile-cross 
arm-linux-androideabi-g++ -DNDEBUG -g2 -O3 -fPIC -pipe -march=armv5te -mtune=xscale -mthumb -msoft-float 
-funwind-tables -fexceptions -frtti -DANDROID --sysroot=/opt/android-ndk/platforms/android-21/arch-arm 
-Wa,--noexecstack -I/opt/android-ndk/sources/cxx-stl/gnu-libstdc++/4.9/include 
-I/opt/android-ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include -c cpu.cpp 
In file included from cpu.cpp:26:0: 
/opt/android-ndk/platforms/android-21/arch-arm/usr/include/machine/cpu-features.h:52:6: error: 
# error Unknown or unsupported ARM architecture 
    ^
cpu.cpp: In function 'bool CryptoPP::CPU_QueryNEON()': 
cpu.cpp:402:29: error: 'android_getCpuFeatures' was not declared in this scope 
    if (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) 
          ^
cpu.cpp:402:33: error: 'ANDROID_CPU_ARM_FEATURE_NEON' was not declared in this scope 
    if (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) 
           ^
make: *** [cpu.o] Error 1 

Die CXXFLAGS wir verwenden kommen direkt von einem JNI-Projekt habe ich vor ein paar Jahren. Ich habe ndk-build verwendet, um die Flags von Androids Build-System-Sets zu untersuchen, und sie dann in unser Skript übertragen. Wir erfinden sie nicht; Sie sind offizielle NDK-Compileroptionen.

Wenn ich cat den Header cpu-features.h Ich sehe ein schlechtes Zeichen:

/* __ARM_ARCH__ is a number corresponding to the ARM revision 
* we're going to support. Our toolchain doesn't define __ARM_ARCH__ 
* so try to guess it. 
*/ 
#ifndef __ARM_ARCH__ 
# if defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ || \ 
     defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__ 
# define __ARM_ARCH__ 7 
# elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ || \ 
     defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6Z__ || \ 
     defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__ 
# define __ARM_ARCH__ 6 
# else 
# error Unknown or unsupported ARM architecture 
# endif 
#endif 

Wir scheinen etwas in unserem Prozess und Umsetzung zu fehlen. Zuerst werden alle erforderlichen Definitionen vom Präprozessor bereitgestellt (siehe unten). Der Präprozessor stellt __ARM_ARCH zur Verfügung, aber Android Header prüft auf __ARM_ARCH__.

Zweitens <machine/cpu-features.h> scheint nicht erforderlich Erklärungen enthalten:

$ cat /opt/android-ndk/platforms/android-21/arch-arm/usr/include/machine/cpu-features.h | grep -i android_getCpuFeatures 
$ 

Wir Androids nicht System Build verwenden, so sehr wenig davon gilt: The cpufeatures Library. Es ist auch zu hoch und es fehlen einige der Details, die wir brauchen.

Meine Frage ist, wie verwenden wir CPU-Features in einer regulären nativen Bibliothek? Was fehlt uns für das erste und zweite Problem?


Unser Skript setzt CXX, CXXFLAGS usw. Sie für den Einsatz zur Verfügung stehen, sobald das Skript stammt. In diesem Fall:

$ echo $CXX 
arm-linux-androideabi-g++ 

Und:

$ $CXX -dM -E - </dev/null | sort 
#define __ACCUM_EPSILON__ 0x1P-15K 
#define __ACCUM_FBIT__ 15 
#define __ACCUM_IBIT__ 16 
#define __ACCUM_MAX__ 0X7FFFFFFFP-15K 
#define __ACCUM_MIN__ (-0X1P15K-0X1P15K) 
#define __ANDROID__ 1 
#define __APCS_32__ 1 
#define __arm__ 1 
#define __ARM_32BIT_STATE 1 
#define __ARM_ARCH 5 
#define __ARM_ARCH_5TE__ 1 
#define __ARM_ARCH_ISA_ARM 1 
#define __ARM_ARCH_ISA_THUMB 1 
#define __ARM_EABI__ 1 
#define __ARMEL__ 1 
#define __ARM_FEATURE_CLZ 1 
#define __ARM_FEATURE_DSP 1 
#define __ARM_FEATURE_QBIT 1 
#define __ARM_FP 12 
#define __ARM_NEON_FP 4 
#define __ARM_PCS 1 
#define __ARM_SIZEOF_MINIMAL_ENUM 4 
#define __ARM_SIZEOF_WCHAR_T 4 
#define __ATOMIC_ACQ_REL 4 
#define __ATOMIC_ACQUIRE 2 
#define __ATOMIC_CONSUME 1 
#define __ATOMIC_RELAXED 0 
#define __ATOMIC_RELEASE 3 
#define __ATOMIC_SEQ_CST 5 
#define __BIGGEST_ALIGNMENT__ 8 
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ 
... 

Keiner der CPU-Funktionen scheinen erklärt oder definiert werden:

$ echo $AOSP_SYSROOT 
/opt/android-ndk/platforms/android-21/arch-arm 
$ grep -IR android_getCpuFeatures $AOSP_SYSROOT 
$ grep -IR ANDROID_CPU_ARM_FEATURE_NEON $AOSP_SYSROOT 
$ 
+0

Jetzt im AOSP-Tracker geöffnet: [Problem 65641866, Dirty kompilieren beim Kompilieren der CPU-Funktion.c mit C++ - Compiler] (https://issuetracker.google.com/issues/65641866). – jww

Antwort

2

Die Bibliothek wird als nicht vorkompilierte Teil des NDK, wird aber als Quelle geliefert. Beim Erstellen mit ndk-build kann diese Bibliothek automatisch erstellt werden, indem auf sie verwiesen wird. Wenn Sie jedoch ein externes Buildsystem verwenden, müssen Sie sicherstellen, dass Sie es selbst hinzufügen und erstellen.

Die Quelle ist in android-ndk/sources/android/cpufeatures, und dort finden Sie eine andere cpu-features.h. (Um die Sie gefunden zu erreichen, enthalten Sie wahrscheinlich machine/cpu-features.h statt, was eine völlig diffrent Sache.)

Sie müssen also cpu-features.h von android-ndk/sources/android/cpufeatures umfassen und bauen cpu-features.c als Teil des Build-Prozesses. Oder wenn Sie eine statische Bibliothek erstellen, kann es auch ausreichen, Ihren Code für diesen Header zu erstellen und zu dokumentieren, dass der Benutzer der Bibliothek die cpufeatures-Bibliothek beim Erstellen der endgültigen gemeinsam genutzten Bibliothek enthalten muss.

+0

Danke @mstorsjo. Irgendwelche Ideen über die falsche Verwendung von definiert? Müssen wir etwas aufgrund der Verwendung der falschen Preprozessor-Makros durch Android definieren? – jww

+0

Ich sehe nichts falsch. Die Kopfzeile, die Sie versehentlich eingefügt haben, ist in keinem Fall enthalten. – mstorsjo

+0

Aufgrund der f: k-up-Verzeichnis-Layouts von Android und dem Speicherort der Quelldateien treten weitere Fehler auf. Ich wünschte, sie würden ihren Kopf aus ihrem Geld herausziehen und 'sysroot' benutzen, so wie es in den letzten 20 Jahren oder so benutzt wurde. Sie müssen aufhören, s :: t aufzustellen, während sie weitermachen. Übrigens haben wir nichts versehentlich aufgenommen. Alles, was wir tun, hat einen Grund. Das Problem scheint hier zu sein, dass AOSP ein defektes '' in SYSROOT oder on-path hinterlässt. – jww

Verwandte Themen