Android ndk 同时构建ARMv7a常规和霓虹灯

Android ndk 同时构建ARMv7a常规和霓虹灯,android-ndk,makefile,neon,Android Ndk,Makefile,Neon,由于我有一个处理非常密集的应用程序,我想构建一个支持NEON/Advanced SIMD的变体。另外,我有多个带有算法的源文件,所以我不想分别为每个文件启用neon。 以下是Android.mk的重要部分: ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) include $(CLEAR_VARS) # Build Advanced SIMD variant LOCAL_MODULE := mymod-neon LOCAL_ARM_NEON

由于我有一个处理非常密集的应用程序,我想构建一个支持NEON/Advanced SIMD的变体。另外,我有多个带有算法的源文件,所以我不想分别为每个文件启用neon。 以下是Android.mk的重要部分:

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)

include $(CLEAR_VARS)
# Build Advanced SIMD variant
LOCAL_MODULE            := mymod-neon
LOCAL_ARM_NEON          := true
LOCAL_ARM_MODE          := $(MY_ARM_MODE)
LOCAL_SRC_FILES         := $(MY_SRC_FILES)
LOCAL_C_INCLUDES        := $(MY_C_INCLUDES)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_SHARED_LIBRARIES  := $(MY_SHARED_LIBRARIES)
include $(BUILD_SHARED_LIBRARY)

endif

include $(CLEAR_VARS)
# Build regular variant
LOCAL_MODULE            := mymod
LOCAL_ARM_MODE          := $(MY_ARM_MODE)
LOCAL_SRC_FILES         := $(MY_SRC_FILES)
LOCAL_C_INCLUDES        := $(MY_C_INCLUDES)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_SHARED_LIBRARIES  := $(MY_SHARED_LIBRARIES)
include $(BUILD_SHARED_LIBRARY)
我曾尝试为ARMv7a构建两个库,但遗憾的是,由于使用了“高级”Makefile工具,我没有编译两个不同的库

它覆盖
.o
目标:

/android-ndk/build/core/build-binary.mk:272: warning: overriding commands for target `obj/local/armeabi-v7a/objs/myalg.o'
遗憾的是,我没有找到一种方法来强制霓虹灯对象在
objs neon
而不是
obj
中构建


有什么办法可以优雅地解决这个问题吗?

我最后做的是将我们的
src
符号链接到
src-neon
目录,并通过
src-neon
访问所有霓虹灯源:

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)

include $(CLEAR_VARS)
# Build Advanced SIMD variant
LOCAL_MODULE            := mymod-neon
LOCAL_ARM_NEON          := true
LOCAL_ARM_MODE          := $(MY_ARM_MODE)
LOCAL_SRC_FILES         := $(call get_sources,`src-neon`)
LOCAL_C_INCLUDES        := $(MY_C_INCLUDES)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_SHARED_LIBRARIES  := $(MY_SHARED_LIBRARIES)
include $(BUILD_SHARED_LIBRARY)

endif

include $(CLEAR_VARS)
# Build regular variant
LOCAL_MODULE            := mymod
LOCAL_ARM_MODE          := $(MY_ARM_MODE)
LOCAL_SRC_FILES         := $(call get_sources,`src`)
LOCAL_C_INCLUDES        := $(MY_C_INCLUDES)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_SHARED_LIBRARIES  := $(MY_SHARED_LIBRARIES)
include $(BUILD_SHARED_LIBRARY)

幸运的是,我们很早就决定只在Unix机器上工作,所以这对我们来说是一个可行的选择。

是的,ndk build应该通过调试和非调试以及ISA来分隔中间对象,所以实际上我认为,正如其他人指出的,您可能在其他地方有错误。请注意,ndk build将通过ISA和调试/非调试,而不是模块名称来分隔中间对象。因此,如果多个模块试图构建同一个文件,您可能会遇到问题

话虽如此,我要指出的是,您可能以稍微错误的方式进行操作,因为
armeabi-v7a
并不意味着支持霓虹灯。虽然ARM确实在v7a中引入了NEON,但它是供供应商添加的可选协处理器,因此v7a处理器可能没有NEON协处理器。不幸的是,有了这些信息,你又回到了原点

这个问题有点重复,这里:

此外,NDK构建文档确实花了整整一页的时间来讨论这个问题。查看您的android-ndk-r8e/documentation.html,左侧有一个指向“CPU ARM Neon”的链接

他们指出的一点是,实现这一点的最佳方法是通过CPU调度,但他们也向您展示了如何使用.neon额外文件扩展名将源文件标记为neon与non neon。不管构建系统是什么,在不同的源文件中放置不同的CPU代码总是好的,因为你可以删除很多丑陋的预处理器的东西。我想这是一种最佳实践,这就是NDK所支持的


在所有这些之后,我看到你最终得到了LCID Fire的解决方案。您可以使用略有不同的源文件构建不同的库。实际上,您应该有3个不同的库,一个用于非v7a,一个用于带neon的v7a,一个用于不带neon的v7a

对我来说,你的Android.mk构建了obj/local/armeabi-v7a/objs/mymod/myalg.o和obj/local/armeabi-v7a/objs/mymod/myalg.o
。也许你在某个地方覆盖了NDK应用程序?。。或者,
$(MY_SRC_FILES)
两次列出myalg.c?NEON是Android中的一个运行时选项。要使两个ARMv7A二进制文件生活在一起,需要做很多额外的工作。我使用ARMv5和ARMv7A创建fat二进制文件,在ARMv7A构建中,我测试NEON的运行时选项,如果有,就使用它。如果(android_getcpuffamily()==android_CPU_FAMILY_ARM&&(android_getCpuFeatures()&android_CPU_ARM_FEATURE_NEON)!=0)@AlexCohn,但这仅在您有两个不同的src目录时才有效。对我来说,它们都指向
$(我的SRC\u文件)
@LCIDFire:不,我使用了相同的SRC目录