安卓系统的libjpeg-turbo

20

我需要在Android NDK中使用libjpeg-turbo。有人成功编译为.a(静态)库吗? 我尝试过几次,但只是出现很多错误。


1
  1. 链接https://github.com/psquare/libtjpeg不存在。
  2. 这个链接https://wiki.linaro.org/BenjaminGaignard/libjpeg-turboAndSkia是用于替换的,必须在Android源代码树中进行编译。
  3. 你想看到很多错误行吗?
- KoVadim
1
虽然Benjamin的博客解释了如何在Android平台中使用libjpeg-turbo替换内置的jpeg库,但是要构建一个独立的库,只需下载源代码(git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android)并在由git创建的libjpeg-turbo目录中运行ndk-build。这是我的命令行:NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=armeabi-v7a。这将生成一个共享库。我会在答案中发布静态库的命令行。 - Alex Cohn
希望将其构建为共享库并按@AlexCohn所述进行操作会导致错误:从./jccolor.c中包含的文件:118:0: ./jccolext.c:29:1:错误:在“static”之前需要“=”,“,”,“;”,“asm”或“__attribute__” ./jccolext.c:86:1:错误:在“static”之前需要“=”,“,”,“;”,“asm”或“__attribute__”(以及其他一堆行)。 - Roberto Andrade
通过将ndk从r8d升级到r10d,我解决了自己的问题。 - Roberto Andrade
2
根据@AlexCohn的[评论](https://dev59.com/eWct5IYBdhLWcg3wNq0g#12296343?noredirect=1#comment48228616_12296343),您可以通过将`turbojpeg-jni.c`添加到要在`Android.mk`中构建的文件列表中,来包含封装JNI接口的生成。这样,您可以直接使用提供的Java类,而无需创建自己的本地代码来调用lib。 - Roberto Andrade
显示剩余3条评论
4个回答

33

安装 Android NDK。以下说明已经经过验证,适用于 r8b 版本,旧版本可能会出现问题,我不确定。

从 Benjamin Gaignard 获取 libjpeg-turbo 的 Android 源代码:

git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android
在由git创建的libjpeg-turbo目录中,编辑Android.mk文件:在第70行后面的LOCAL_MODULE := libjpeg之后,添加下列内容:
ifeq ($(notdir $(MAKECMDGOALS)),libjpeg.a)
  LOCAL_SRC_FILES +=  $(libsimd_SOURCES_DIST)
  include $(BUILD_STATIC_LIBRARY)
  include $(CLEAR_VARS)
  LOCAL_MODULE := dummy
endif

运行ndk-build命令:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk obj/local/armeabi/libjpeg.a

利润!

PS: 你可能需要 armeabi-v7a 版本:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=armeabi-v7a obj/local/armeabi-v7a/libjpeg.a

为了提高性能,可以编译成 ARM 架构,命令行中添加:

LOCAL_ARM_MODE=arm

如果你的目标支持 NEON ,则添加到命令行:

LOCAL_ARM_NEON=true ARCH_ARM_HAVE_NEON=true

更新: 为了让它能够在Android NDK r15及更高版本中工作,请从Android.mk中删除所有对libcutils的引用。


2
哦,是的。我忘记了第11行。Git中有一个明显的错误。在true)LOCAL_CFLAGS之间拆分该行。您可以忽略警告。关于libjpeg.a - 再次是我的错。目标应该是obj/local/armeabi/libjpeg.a。我已经相应地修复了我的答案。 - Alex Cohn
1
Alex,对于x86和mips的支持有什么更新吗?三年过去了? - Asiimwe
@PaulAsiimwe.T:你一定会发现markmancadetailed update非常有用。 - Alex Cohn
1
我刚刚升级了我的 NDK 从 r8dr10d,再次尝试后它成功了,所以我猜测问题可能出在那个旧版本的 ndk 上? - Roberto Andrade
2
@RobertoAndrade:在 Android.mk 文件中,在第一个 include $(BUILD_SHARED_LIBRARY) 之前添加 LOCAL_SRC_FILES+=turbojpeg-jni.c - Alex Cohn
显示剩余18条评论

8
这篇答案扩展了Alex Cohn的答案。完全归功于他给我的开始。这个答案将允许你建立带有ARM汇编(带或不带NEON)以及x86的libjpeg-turbo。还提供了对MIPS的兼容性,这样你就可以为Android NDK r8e版本支持的所有平台构建你的应用,并成为一个好公民。
我仍然是一个相对新手,没有权限附加附件。因此,我必须内联一堆代码。我也确信有更好的方法来处理下面的一些细节,所以欢迎提出改进建议。
让所有这些工作正常运行需要进行六个主要步骤(第二步有很多子步骤 - 每个子步骤都可以在六个主步骤之后找到):
  1. Download via git the libjpeg-turbo library containing a set of code and .mk files for Android. I downloaded it from here with git:

    git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android
    

    Full credit and thanks must be given to Tom Gall for doing the initial work.

  2. Download YASM (an assembler for x86) and configure the Android build environment to support it. See the set of instructions on configuring YASM for the Android NDK that I am including below the horizontal rule at the end of my Android.mk changes in step 6. Supporting x86 requires that you aren't shy about tweaking the NDK install.

    I perhaps could have used the NASM compiler, but was far enough down the YASM path before investigating NASM that I brought the YASM path to completion.

  3. Create the simd/jsmidcfg.inc file. The libjpeg-turbo library provides simd/jsmidcfg.inc.h. It is meant for the pre-processor to take the .h and convert it to a .inc. I'm sure there is a better way for it to happen than what I did. But couldn't get it sorted out due to time pressures. Instead, I manually ran one the gcc that came with Android to create the file using the following command:

    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.4.3\prebuilt\windows-x86_64\bin\i686-linux-android-gcc.exe -E C:\development\thirdparty\libjpeg-turbo\libjpeg-turbo-android-1.2.0\simd\jsimdcfg.inc.h -o C:\development\thirdparty\libjpeg-turbo\libjpeg-turbo-android1.2.0\simd\jsimdcfg.inc
    

    After the pre-processor completed, I had to hand-edit the file to get it into a usable state. I had to select all of the lines above "; -- jpeglib.h" and delete them.

    Next, I had to find each of the %defines that started with _cpp_protection_ and duplicate each of those %defines WITHOUT the _cpp_protection_. For example, %define _cpp_protection_RGB_RED 0 became %define RGB_RED 0

  4. For ARM, I wanted my code to dynamically support NEON instructions on hardware that had it, and to fallback to something simpler on hardware that didn't, I modified simd/jsimd_arm.c to dynamically query for the information. I didn't want to have to make that choice when building libjpeg-turbo.

    I added the following lines of code:

    #ifdef ANDROID
    #include <cpufeatures/cpu-features.h>
    #endif
    

    and

    #ifdef ANDROID
      uint64_t cpuFeatures = android_getCpuFeatures();
      if (cpuFeatures & ANDROID_CPU_ARM_FEATURE_NEON) {
         simd_support |= JSIMD_ARM_NEON;
      }
    #endif
    

    within the init_simd() method.

  5. Enabling MIPS.

    To be a good citizen, I wanted to enable compilation on MIPS. While there isn't any assembler code for MIPS, the code should at least compile and run. To do that, I copied simd/jsimd_arm.c to simd/jsimd_mips.c. I edited the file so that init_simd() set simd_support = 0; I also changed all of the jsimd_can_*() methods to return 0. Finally, I removed the implementation from all of the other methods.

  6. Because I was interested in more than just a build for ARM, I changed the Application.mk file to include the following lines:

    APP_ABI := all
    APP_OPTIM := release
    

    The APP_OPTIM comes from How to optimize a native code with android-ndk (Speed Optimization)

    Within Android.mk, I commented out everything from the "cjpeg" comment block and below. To do a block comment, I followed the advice of How to add multi line comments in makefiles

    I next customized the Android.mk file itself so that I could build for all currently supported CPUs (ARM, x86, MIPS). Here is what I ended up with (some code commented out because I wanted a static library -- also to leave the original code in place so I can see what changed). You will most likely have to change (or remove) the addprefix method calls because the file below is customized for my build environment. But other than that, it should work for you.

.

##################################################
###                simd                        ###
##################################################
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

#ifeq ($(ARCH_ARM_HAVE_NEON),true)
#LOCAL_CFLAGS += -D__ARM_HAVE_NEON
#endif

# From autoconf-generated Makefile
EXTRA_DIST = simd/nasm_lt.sh simd/jcclrmmx.asm simd/jcclrss2.asm simd/jdclrmmx.asm simd/jdclrss2.asm \
simd/jdmrgmmx.asm simd/jdmrgss2.asm simd/jcclrss2-64.asm simd/jdclrss2-64.asm \
simd/jdmrgss2-64.asm simd/CMakeLists.txt

#libsimd_SOURCES_DIST = simd/jsimd_arm_neon.S \
                       simd/jsimd_arm.c

libsimd_SOURCES_DIST :=


ifeq ($(TARGET_ARCH),arm)
libsimd_SOURCES_DIST := simd/jsimd_arm_neon.S \
                       simd/jsimd_arm.c
endif

ifeq ($(TARGET_ARCH),x86)
#libsimd_SOURCES_DIST := simd/jsimd_mips.c

# List of assembly files needed is derived from content within simd/CMakelists.txt
# The Intel Atom supports x86 32-bit assembly.  So take those files and leave the
# 64-bit behind.

libsimd_SOURCES_DIST := simd/jsimd_i386.c \
simd/jsimdcpu.asm simd/jccolmmx.asm simd/jcgrammx.asm simd/jdcolmmx.asm simd/jcsammmx.asm simd/jdsammmx.asm \
    simd/jdmermmx.asm simd/jcqntmmx.asm simd/jfmmxfst.asm simd/jfmmxint.asm simd/jimmxred.asm simd/jimmxint.asm simd/jimmxfst.asm simd/jcqnt3dn.asm \
    simd/jf3dnflt.asm simd/ji3dnflt.asm simd/jcqntsse.asm simd/jfsseflt.asm simd/jisseflt.asm simd/jccolss2.asm simd/jcgrass2.asm simd/jdcolss2.asm \
    simd/jcsamss2.asm simd/jdsamss2.asm simd/jdmerss2.asm simd/jcqnts2i.asm simd/jfss2fst.asm simd/jfss2int.asm simd/jiss2red.asm simd/jiss2int.asm \
    simd/jiss2fst.asm simd/jcqnts2f.asm simd/jiss2flt.asm
endif

ifeq ($(TARGET_ARCH),mips)
libsimd_SOURCES_DIST := simd/jsimd_mips.c
endif


#LOCAL_SRC_FILES := $(libsimd_SOURCES_DIST)
#LOCAL_SRC_FILES := $(addprefix ../../libjpeg-turbo-android-1.2.0/,$(LOCAL_SRC_FILES))

LOCAL_C_INCLUDES := $(LOCAL_PATH)/simd \
                    $(LOCAL_PATH)/android

LOCAL_C_INCLUDES := simd android
#LOCAL_C_INCLUDES := $(addprefix ../../libjpeg-turbo-android-1.2.0/,$(LOCAL_C_INCLUDES))


#AM_CFLAGS := -march=armv7-a -mfpu=neon
#AM_CCASFLAGS := -march=armv7-a -mfpu=neon

#LOCAL_MODULE_TAGS := debug

#LOCAL_MODULE := libsimd

#include $(BUILD_STATIC_LIBRARY)

######################################################
###           libjpeg.so                       ##
######################################################

#include $(CLEAR_VARS)

# From autoconf-generated Makefile
libjpeg_SOURCES_DIST =  jcapimin.c jcapistd.c jccoefct.c jccolor.c \
        jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
        jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
        jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
        jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
        jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
        jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
        jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c \
jaricom.c jcarith.c jdarith.c \
turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c #\
turbojpeg-mapfile

LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST) $(libsimd_SOURCES_DIST)
#LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST)
LOCAL_SRC_FILES := $(addprefix ../../../libjpeg-turbo-android-1.2.0/,$(LOCAL_SRC_FILES))

#LOCAL_SHARED_LIBRARIES := libcutils
#LOCAL_STATIC_LIBRARIES := libsimd

#LOCAL_C_INCLUDES := $(LOCAL_PATH) 

# Include C:/development/android/ide/android-ndk-r8e-windows-x86_64/sources/android
# instead of the lower-level cpufeatures because of how I had to include
# cpu-features.h.  It appears as if there is a naming conflict, so I had to
# change how the file was included to avoid naming conflicts.

LOCAL_C_INCLUDES := $(addprefix ../../../libjpeg-turbo-android-1.2.0/,$(LOCAL_C_INCLUDES)) \
C:/development/thirdparty/libjpeg-turbo/libjpeg-turbo-android-1.2.0 \
C:/development/android/ide/android-ndk-r8e-windows-x86_64/sources/android
#LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES)) ./
#LOCAL_C_INCLUDES := $(addprefix $(LOCAL_PATH),$(LOCAL_C_INCLUDES)) $(LOCAL_PATH)../../../libjpeg-turbo-android-1.2.0/

LOCAL_CFLAGS := -DAVOID_TABLES  -O3 -fstrict-aliasing -fprefetch-loop-arrays  -DANDROID \
        -DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_CFLAGS += -DJPEG_LIB_VERSION=80  # I need version 8 because of some of the methods I depend on
LOCAL_YASMFLAGS := -P../../libjpeg-turbo-android-1.2.0/simd/jsimdcfg.inc

#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_STATIC_LIBRARY)

#LOCAL_MODULE_TAGS := debug

#LOCAL_MODULE := libjpeg
LOCAL_MODULE := jpeg-turbo

#include $(BUILD_SHARED_LIBRARY)
#LOCAL_STATIC_LIBRARIES := cpufeatures

include $(BUILD_STATIC_LIBRARY)

# We reference android/cpufeatures in the Android.mk file of our main app, so
# we don't need to do anything here.
#$(call import-module,android/cpufeatures)

一些随libjpeg-turbo一起提供的源代码是以.asm格式提供的,也就是说,需要使用NASM汇编器进行编译。由于其初始状态,Android NDK不支持此格式。
为了在NDK中使用.asm支持,我遵循了这里提出的大致概述:http://software.intel.com/en-us/articles/using-yasm-compiler-on-android-ndkbuild 以下是一组更详细的说明。在android-ndk-r8\build\core中,需要执行以下操作:
  1. build-binary.mk:

    all_source_extensions := .c .s .S $(LOCAL_CPP_EXTENSION) => all_source_extensions := .c .s .asm .S $(LOCAL_CPP_EXTENSION)

    For me, the above was on line 228.

    After the line that starts with: "# Build the sources to object files" you will see several foreach loops. Add one like this (I added it on line 272):

    $(foreach src,$(filter %.asm,$(LOCAL_SRC_FILES)), $(call compile-asm-source,$(src),$(call get-object-name,$(src))))
    
  2. definitions.mk:

    Create a new compile-asm-source to match the new entry we added within the new for loop above. We also have to add a new define within the make file. I added the following. It is a combination and simplification of the various rules used to build .c files. We need a different set of options when using yasm that necessitate these changes.

    define  ev-compile-asm-source
    _SRC:=$$(LOCAL_PATH)/$(1)
    _OBJ:=$$(LOCAL_OBJS_DIR)/$(2)
    
    _FLAGS := -f elf -DELF -DPIC $$(LOCAL_YASMFLAGS)
    
    _TEXT := "Compile $$(call get-src-file-text,$1)"
    _CC   := $$(NDK_CCACHE) $$(TARGET_ASM)
    
    $$(_OBJ): PRIVATE_SRC      := $$(_SRC)
    $$(_OBJ): PRIVATE_OBJ      := $$(_OBJ)
    $$(_OBJ): PRIVATE_DEPS     := $$(call host-path,$$(_OBJ).d)
    $$(_OBJ): PRIVATE_MODULE   := $$(LOCAL_MODULE)
    $$(_OBJ): PRIVATE_TEXT     := "$$(_TEXT)"
    $$(_OBJ): PRIVATE_CC       := $$(_CC)
    $$(_OBJ): PRIVATE_CFLAGS   := $$(_FLAGS)
    
    ifeq ($$(LOCAL_SHORT_COMMANDS),true)
    _OPTIONS_LISTFILE := $$(_OBJ).cflags
    $$(_OBJ): $$(call generate-list-file,$$(_FLAGS),$$(_OPTIONS_LISTFILE))
    $$(_OBJ): PRIVATE_CFLAGS := @$$(call host-path,$$(_OPTIONS_LISTFILE))
    $$(_OBJ): $$(_OPTIONS_LISTFILE)
    endif
    
    $$(call generate-file-dir,$$(_OBJ))
    
    $$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $$(NDK_DEPENDENCIES_CONVERTER)
    @$$(HOST_ECHO) "$$(PRIVATE_TEXT)  : $$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
    $$(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) \
    $$(call cmd-convert-deps,$$(PRIVATE_DEPS))
    endef
    
    compile-asm-source = $(eval $(call ev-compile-asm-source,$1,$2))
    

    Search for the line that starts with 'compile-s-source'. I found it at line 1491. The new compile-asm-source can go right below that.

    Next, search for the line that starts with "get-object-name". I found it at line 1270. Add ".asm" to the inner for-loop. Put it together with the .c, .s, and .S

  3. import-locals.mk:

    Add the following line below the LOCAL_CFLAGS and the LOCAL_CPPFLAGS line

    LOCAL_YASMFLAGS  := $(LOCAL_CFLAGS) $(strip $(LOCAL_YASMFLAGS))
    
  4. default-build-commands.mk:

    Add the following line anywhere in the file. I put mine under the TARGET_CXX section and above the TARGET_LD section.

    TARGET_ASM       = $(TOOLCHAIN_PREFIX)yasm
    
  5. Download and copy yasm.exe to the build folders:

    Download a copy of YASM from here: http://yasm.tortall.net/

    I have the Win64 version of the NDK, so downloaded the Win64 version of YASM. If you have the Win32 version of the NDS, download th Win32 version of YASM.

    You should just get the .exe. Copy it to the following directories as yasm.exe. If you have any other toolchain versions, copy it to those directories as well:

    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.4.3\prebuilt\windows-x86_64\i686-linux-android\bin
    
    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.6\prebuilt\windows-x86_64\i686-linux-android\bin
    
    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.7\prebuilt\windows-x86_64\i686-linux-android\bin
    

    Then, copy the file again to the directories below as i686-linux-android-yasm.exe. And as above, if you have any other toolchain versions, copy it to those directories as well:

    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.4.3\prebuilt\windows-x86_64\bin
    
    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.6\prebuilt\windows-x86_64\bin
    
    C:\development\android\ide\android-ndk-r8e-windows-x86_64\toolchains\x86-4.7\prebuilt\windows-x86_64\bin
    

谢谢分享!人们似乎正在寻找这些更新! - Alex Cohn
你是一名“新手”吗?非常感谢。 - Asiimwe
我正在尝试按照上述步骤进行操作。我认为步骤2和3是针对x-86的,步骤4是针对arm的,步骤5是针对MIPS的。如果我理解有误,请纠正我。目前我只对ARM感兴趣。当我克隆了git仓库并尝试在第4步中进行更改时,我没有看到cpufeatures目录。我只在名为“machine”的目录下看到了一个cpu-features.h文件。请问您能给予建议吗? - rajaramyadhav
如果你有一个可用的版本,我很想看一下。我已经成功地将libjpegturbo与Alex Kohn的版本配合使用了。不过,我也希望能够进行动态NEON检测。 - rajaramyadhav

2

感谢Alex Cohn和answered Dec分享;

本答案扩展了Alex Cohn和answered Dec的答案;

我使用的是jpeg turbo 1.3.9和ndk-r9d,关于yasm.exe,ndk-r9d已经包含在内,在完成answered Dec的第三步后,我遇到了一个错误,位于simd/jsimdext.inc的第182行:“%define EXTN(name)_ %+ name; foo() -> _foo”,将其更改为“%define EXTN(name)name”即可,这个问题已经解决;

这是我的Android.mk文件。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_CFLAGS += -D__ARM_HAVE_NEON

#ifeq ($(ARCH_ARM_HAVE_NEON),true)
#LOCAL_CFLAGS += -D__ARM_HAVE_NEON
#endif

# From autoconf-generated Makefile
EXTRA_DIST = nasm_lt.sh CMakeLists.txt \
    jccolext-mmx.asm   jcgryext-mmx.asm   jdcolext-mmx.asm   jdmrgext-mmx.asm \
    jccolext-sse2.asm  jcgryext-sse2.asm  jdcolext-sse2.asm  jdmrgext-sse2.asm \
    jccolext-sse2-64.asm  jcgryext-sse2-64.asm  jdcolext-sse2-64.asm \
    jdmrgext-sse2-64.asm



ifeq ($(TARGET_ARCH),arm)
libsimd_SOURCES_DIST := simd/jsimd_arm_neon.S \
                       simd/jsimd_arm.c

AM_CFLAGS := -march=armv7-a -mfpu=neon
AM_CCASFLAGS := -march=armv7-a -mfpu=neon

endif

ifeq ($(TARGET_ARCH),x86)
# List of assembly files needed is derived from content within simd/CMakelists.txt
# The Intel Atom supports x86 32-bit assembly.  So take those files and leave the
# 64-bit behind.

#libsimd_SOURCES_DIST := simd/jsimd_i386.c \
    simd/jsimdcpu.asm \
    simd/jfdctflt-3dn.asm \
    simd/jidctflt-3dn.asm \
    simd/jquant-3dn.asm \
    simd/jccolor-mmx.asm \
    simd/jcgray-mmx.asm \
    simd/jcsample-mmx.asm \
    simd/jdcolor-mmx.asm \
    simd/jdmerge-mmx.asm \
    simd/jdsample-mmx.asm \
    simd/jfdctfst-mmx.asm \
    simd/jfdctint-mmx.asm \
    simd/jidctfst-mmx.asm \
    simd/jidctint-mmx.asm \
    simd/jidctred-mmx.asm \
    simd/jquant-mmx.asm \
    simd/jfdctflt-sse.asm \
    simd/jidctflt-sse.asm \
    simd/jquant-sse.asm \
    simd/jccolor-sse2.asm \
    simd/jcgray-sse2.asm \
    simd/jcsample-sse2.asm \
    simd/jdcolor-sse2.asm \
    simd/jdmerge-sse2.asm \
    simd/jdsample-sse2.asm \
    simd/jfdctfst-sse2.asm \
    simd/jfdctint-sse2.asm \
    simd/jidctflt-sse2.asm \
    simd/jidctfst-sse2.asm \
    simd/jidctint-sse2.asm \
    simd/jidctred-sse2.asm \
    simd/jquantf-sse2.asm \
    simd/jquanti-sse2.asm

libsimd_SOURCES_DIST := simd/jsimd_i386.c simd/jsimd.h simd/jsimdcfg.inc.h simd/jsimdext.inc \
    simd/jcolsamp.inc simd/jdct.inc simd/jsimdcpu.asm \
    simd/jfdctflt-3dn.asm   simd/jidctflt-3dn.asm   simd/jquant-3dn.asm \
    simd/jccolor-mmx.asm    simd/jcgray-mmx.asm     simd/jcsample-mmx.asm \
    simd/jdcolor-mmx.asm    simd/jdmerge-mmx.asm    simd/jdsample-mmx.asm \
    simd/jfdctfst-mmx.asm   simd/jfdctint-mmx.asm   simd/jidctfst-mmx.asm \
    simd/jidctint-mmx.asm   simd/jidctred-mmx.asm   simd/jquant-mmx.asm \
    simd/jfdctflt-sse.asm   simd/jidctflt-sse.asm   simd/jquant-sse.asm \
    simd/jccolor-sse2.asm   simd/jcgray-sse2.asm    simd/jcsample-sse2.asm \
    simd/jdcolor-sse2.asm   simd/jdmerge-sse2.asm   simd/jdsample-sse2.asm \
    simd/jfdctfst-sse2.asm  simd/jfdctint-sse2.asm  simd/jidctflt-sse2.asm \
    simd/jidctfst-sse2.asm  simd/jidctint-sse2.asm  simd/jidctred-sse2.asm  \
    simd/jquantf-sse2.asm   simd/jquanti-sse2.asm
endif

ifeq ($(TARGET_ARCH),mips)
libsimd_SOURCES_DIST := simd/jsimd_mips.c
endif

LOCAL_C_INCLUDES := $(LOCAL_PATH)/simd \
                    $(LOCAL_PATH)/android

LOCAL_SRC_FILES:= $(libsimd_SOURCES_DIST)

LOCAL_CFLAGS := -DAVOID_TABLES  -O3 -fstrict-aliasing -fprefetch-loop-arrays  -DANDROID \
        -DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_CFLAGS += -DJPEG_LIB_VERSION=80  # I need version 8 because of some of the methods I depend on

$(warning "libsimd")
LOCAL_MODULE := libsimd
LOCAL_MODULE_FILENAME := libsimd
include $(BUILD_STATIC_LIBRARY)

######################################################
###           libjpeg.so                       ##
######################################################

#include $(CLEAR_VARS)

# From autoconf-generated Makefile
libjpeg_SOURCES_DIST =  jcapimin.c jcapistd.c jccoefct.c jccolor.c \
        jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
        jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
        jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
        jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
        jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
        jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
        jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c \
    jaricom.c jcarith.c jdarith.c \
    turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c \
    turbojpeg-mapfile

LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST)

LOCAL_SHARED_LIBRARIES += libcutils
LOCAL_STATIC_LIBRARIES += libsimd

LOCAL_C_INCLUDES := $(LOCAL_PATH) 



$(warning "libjpeg")

LOCAL_CFLAGS := -DAVOID_TABLES  -O3 -fstrict-aliasing -fprefetch-loop-arrays  -DANDROID \
        -DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_CFLAGS += -DJPEG_LIB_VERSION=80  # I need version 8 because of some of the methods I depend on

#D:\android-ndk-r9d\toolchains\x86-4.8\prebuilt\windows-x86_64\bin\i686-linux-android-gcc.exe -E D:\WORKSPACE\MINE\libjpeg_turbo_1.3.9_multi_platform\jni\simd\jsimdcfg.inc.h -o D:\WORKSPACE\MINE\libjpeg_turbo_1.3.9_multi_platform\jni\simd\jsimdcfg.inc

LOCAL_MODULE := libjpeg
LOCAL_MODULE_FILENAME:=libjpeg

LOCAL_STATIC_LIBRARIES += cpufeatures

include $(BUILD_STATIC_LIBRARY)

这个 Android.mk 是为 x86 设计的吗?我尝试使用您提供的 Android.mk 并执行以下命令:ndk-build NDK_PROJECT_PATH =。 APP_BUILD_SCRIPT =。/Android.mk APP_ABI = x86 obj / local / x86 / libjpeg.a,它可以工作,但我不确定这是否正确,因为下面 @markmanca 的答案要复杂得多。 - Iker Jamardo Zugaza

0

对于任何试图构建官方仓库版本的人,我成功地使用了此处附加的补丁:libjpeg-turbo cross-compile to Android fails

然后,根据您是为32位还是64位编译:

export CFLAGS="-DSIZEOF_SIZE_T=4"

或者

export CFLAGS="-DSIZEOF_SIZE_T=4"

使用-DWITH_SIMD=FALSE -DCMAKE_TOOLCHAIN_FILE=your_toolchain_file运行cmake。

当然,我知道禁用SIMD并不理想,但至少我成功构建了一个可以开始使用的版本。希望在未来,构建系统的NEON SIMD支持能够得到修复。使用./ configure也未能为ARM构建正确的SIMD。

顺便说一句,我希望人们能够为主要存储库贡献修复,而不仅仅是将其分叉。距离alex-cohn回答中引用的存储库的最后一次更改已经过去2年了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接