2017-09-13 24 views
1

我们最近添加了cpu-features来检测平台功能,如ARMV8和CRC,AES和SHA。我们抓住了一个bug report与最新的NDK建设。当我们在armeabi项目尝试包括<cpu-features.h>它导致:如何在本地库中使用cpu-feature?

$ 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 

我们使用直接从JNI项目来的CXXFLAGS我创建了一个几年前。我使用ndk-build来检查Android的构建系统集的标志,然后将它们传输到我们的脚本。我们没有制作它们;他们是官方的NDK编译器选项。

当我catcpu-features.h我看到一个不祥的征兆:

/* __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 

我们似乎缺少在我们的过程和实施的东西。首先,所有需要的定义都由预处理器提供(见下文)。预处理器提供__ARM_ARCH,但Android的标题检查__ARM_ARCH__

其次,<machine/cpu-features.h>似乎不包括所需的声明:

​​

我们不使用Android的构建系统,所以很少的适用:The cpufeatures Library。它的水平也很高,缺乏我们需要的一些细节。

我的问题是,我们如何在普通的本地库中使用cpu-features?我们对第一个和第二个问题缺少什么?


我们的脚本设置CXXCXXFLAGS等,他们都可以使用,一旦脚本来源。在这种情况下:

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

和:

的CPU的功能
$ $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__ 
... 

没有人可以声明或定义:

$ 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

现在在AOSP Tracker中打开:[编号为65641866,编译cpu-feature时脏编译。c与C++编译器](https://issuetracker.google.com/issues/65641866)。 – jww

回答

2

库不是预构建的NDK的一部分,但作为来源发货。当使用ndk-build构建时,可以通过引用它来自动构建该库,但是当使用外部构建系统时,您需要确保自己包含并构建它。

来源是android-ndk/sources/android/cpufeatures,在那里你会发现不同的cpu-features.h。 (为了达到你找到了一个,你可能包括machine/cpu-features.h相反,这是一个完全不同势东西。)

所以,你需要从android-ndk/sources/android/cpufeatures包括cpu-features.h,并建立cpu-features.c作为构建过程的一部分。或者,如果您正在生成静态库,那么也可以根据此头来构建代码,并记录库的用户在生成最终共享库时需要包含cpufeatures库。

+0

谢谢@mstorsjo。任何有关错误使用定义的想法?由于Android使用了错误的预处理器宏,我们是否需要定义一些东西? – jww

+0

我没有看到任何错误。你不小心包含头文件是不是东西,你应该在任何情况下都包括。 – mstorsjo

+0

由于Android的f :: k'd up目录布局和源文件的位置,我们正在捕捉更多相关的错误。我希望他们能拉他们的头出来了一个$$和使用'--sysroot'他们方式,它已被用于在过去的20年左右。他们需要停下来继续做下去。顺便说一句,我们并没有意外地包含任何东西。我们所做的一切都有其道理。这里的问题似乎是AOSP在SYSROOT或路径上留下了一个坏掉的。 – jww