android 的 libjpeg-turbo

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12260149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:14:03  来源:igfitidea点击:

libjpeg-turbo for android

androidandroid-ndkjpeglibjpeg-turbo

提问by KoVadim

I need libjpeg-turbofor android ndk. Did anyone managed to compile it as .a (static) lib? I have tried a few times, but it gave me a lot of errors only.

我需要用于 android ndk 的libjpeg-turbo。有没有人设法将它编译为 .a(静态)lib?我已经尝试了几次,但它只给了我很多错误。

回答by Alex Cohn

Install Android NDK. Following instructions were verified with r8b, older versions may have problems, I don't know.

安装安卓 NDK。以下说明已通过r8b验证,旧版本可能有问题,我不知道。

Get the Android sources for libjpeg-turbofrom Benjamin Gaignard:

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

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

In the libjpeg-turbodirectory created by git, edit file Android.mk: after line 70, LOCAL_MODULE := libjpeg, add the following:

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

Run ndk-build:

运行ndk-build

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

Profit!

利润!

PS:You may want the armeabi-v7aversion:

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

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

Or compile for ARM, to improve performance, add to command line:

或者为ARM编译,为了提高性能,添加到命令行:

LOCAL_ARM_MODE=arm

If your target has NEONsupport, add to command line:

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

LOCAL_ARM_NEON=true ARCH_ARM_HAVE_NEON=true


UPDATE: to get it work with Android NDK r15 and later, remove all references to libcutilsfrom Android.mk.

更新:要使其与 Android NDK r15 及更高版本一起使用,请libcutilsAndroid.mk 中删除所有引用。

回答by markmanca

This answer expands on Alex Cohn's answer. Full credit goes to him for getting me started. This answer will allow you to build libjpeg-turbo with assembly for ARM (with or without NEON) as well as x86. Compatibility is also provided for MIPS so that you can be a good citizen and build your app for all of the platforms that the r8e version of the Android NDK supports.

这个答案扩展了亚历克斯科恩的答案。完全归功于他让我开始。这个答案将允许您使用 ARM(有或没有 NEON)以及 x86 的程序集构建 libjpeg-turbo。还为 MIPS 提供了兼容性,以便您可以成为一名优秀的公民,并为 r8e 版本的 Android NDK 支持的所有平台构建您的应用程序。

I still a relative newbie to actually answering questions, so don't have permissions to include attachments. So I'm going to have to inline a bunch of code. I'm also sure there are better ways to do bits and pieces of the below, so am open to suggestions for improvement.

我仍然是实际回答问题的相对新手,因此无权包含附件。所以我将不得不内联一堆代码。我也确信有更好的方法来做下面的点点滴滴,所以我愿意接受改进建议。

Getting this all to work was done in six main steps (step two has many sub-steps -- each of which can be found after the main six steps):

使这一切工作通过六个主要步骤完成(第二步有许多子步骤——每个子步骤都可以在主要的六个步骤之后找到):

  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 0became %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.

  1. 通过 git 下载 libjpeg-turbo 库,其中包含一组适用于 Android 的代码和 .mk 文件。我从这里用 git 下载了它:

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

    必须对 Tom Gall 所做的初步工作给予充分的信任和感谢。

  2. 下载 YASM(x86 的汇编程序)并配置 Android 构建环境以支持它。请参阅我在第 6 步中 Android.mk 更改末尾的水平规则下方包含的有关为 Android NDK 配置 YASM 的一组说明。支持 x86 要求您不要羞于调整 NDK 安装。

    我也许可以使用 NASM 编译器,但在研究 NASM 之前我已经完成了 YASM 路径,我完成了 YASM 路径。

  3. 创建 simd/jsmidcfg.inc 文件。libjpeg-turbo 库提供了 simd/jsmidcfg.inc.h。它旨在让预处理器获取 .h 并将其转换为 .inc。我确信有比我所做的更好的方式来实现它。但由于时间紧迫,无法解决。相反,我使用以下命令手动运行 Android 附带的 gcc 来创建文件:

    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
    

    预处理器完成后,我必须手动编辑文件以使其进入可用状态。我必须选择“; -- jpeglib.h”上面的所有行并删除它们。

    接下来,我必须找到以 _cpp_protection_ 开头的每个 %defines 并复制每个 %defines 而不使用 _cpp_protection_。例如,%define _cpp_protection_RGB_RED 0成为%define RGB_RED 0

  4. 对于 ARM,我希望我的代码在拥有它的硬件上动态支持 NEON 指令,并在没有它的硬件上回退到更简单的东西,我修改了 simd/jsimd_arm.c 以动态查询信息。我不想在构建 libjpeg-turbo 时做出这样的选择。

    我添加了以下代码行:

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

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

    在 init_simd() 方法中。

  5. 启用 MIPS。

    为了成为一个好公民,我想在 MIPS 上启用编译。虽然 MIPS 没有任何汇编代码,但代码至少应该可以编译和运行。为此,我将 simd/jsimd_arm.c 复制到 simd/jsimd_mips.c。我编辑了该文件,以便init_simd()设置simd_support = 0;我还将所有jsimd_can_*()方法更改为返回 0。最后,我从所有其他方法中删除了实现。

  6. 因为我不仅对 ARM 的构建感兴趣,所以我更改了 Application.mk 文件以包含以下几行:

    APP_ABI := all
    APP_OPTIM := release
    

    APP_OPTIM 来自How to optimize a native code with android-ndk (Speed Optimization)

    在 Android.mk 中,我注释掉了“cjpeg”注释块和下面的所有内容。要进行块注释,我遵循了如何在 makefile 中添加多行注释的建议

    接下来我自定义了 Android.mk 文件本身,以便我可以为所有当前支持的 CPU(ARM、x86、MIPS)构建。这是我的最终结果(一些代码被注释掉了,因为我想要一个静态库——同时保留原始代码,以便我可以看到发生了什么变化)。您很可能必须更改(或删除) addprefix 方法调用,因为下面的文件是为我的构建环境定制的。但除此之外,它应该适合你。

.

.

##################################################
###                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)


Some of the source code that ships with libjpeg-turbo is in .asm format. That is, it needs to be compiled with the NASM assembler. As it ships, the Android NDK doesn't have support for it.

libjpeg-turbo 附带的一些源代码采用 .asm 格式。也就是说,它需要使用 NASM 汇编器进行编译。在发布时,Android NDK 不支持它。

To get .asm support working with NDK, I followed the rough outline presented here: http://software.intel.com/en-us/articles/using-yasm-compiler-on-android-ndkbuild

为了获得使用 NDK 的 .asm 支持,我遵循了此处提供的粗略大纲:http: //software.intel.com/en-us/articles/using-yasm-compiler-on-android-ndkbuild

Here are a set of more detailed instructions. Within android-ndk-r8\build\core, the following things need to occur:

这里有一组更详细的说明。在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,)"
    _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,,))
    

    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 belowthe 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
    
  1. build-binary.mk:

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

    对我来说,上面是第 228 行。

    在以“# Build the source to object files”开头的行之后,您将看到几个 foreach 循环。添加一个这样的(我在第 272 行添加了它):

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

    创建一个新的 compile-asm-source 以匹配我们在上面的新 for 循环中添加的新条目。我们还必须在 make 文件中添加一个新定义。我添加了以下内容。它是用于构建 .c 文件的各种规则的组合和简化。在使用需要这些更改的 yasm 时,我们需要一组不同的选项。

    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,)"
    _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,,))
    

    搜索以“compile-s-source”开头的行。我在第 1491 行找到了它。新的 compile-asm-source 可以在它的正下方。

    接下来,搜索以“get-object-name”开头的行。我在第 1270 行找到了它。将“.asm”添加到内部 for 循环中。将其与 .c、.s 和 .S 放在一起

  3. 进口locals.mk:

    在 LOCAL_CFLAGS 和 LOCAL_CPPFLAGS 行下方添加以下行

    LOCAL_YASMFLAGS  := $(LOCAL_CFLAGS) $(strip $(LOCAL_YASMFLAGS))
    
  4. 默认构建命令.mk:

    在文件中的任意位置添加以下行。我把我的放在 TARGET_CXX 部分和 TARGET_LD 部分上面。

    TARGET_ASM       = $(TOOLCHAIN_PREFIX)yasm
    
  5. 下载 yasm.exe 并将其复制到构建文件夹:

    从这里下载 YASM 的副本:http: //yasm.tortall.net/

    我有Win64版本的NDK,所以下载了Win64版本的YASM。如果您有 Win32 版本的 NDS,请下载 YASM 的 Win32 版本。

    您应该只获取 .exe。将其作为 yasm.exe 复制到以下目录。如果您有任何其他工具链版本,请将其复制到这些目录中:

    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
    

    然后,再次将文件复制到以下目录中作为 i686-linux-android-yasm.exe。如上所述,如果您有任何其他工具链版本,请将其复制到这些目录中:

    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
    

回答by Mr. Xian

Thanks Alex Cohn and answered Dec for share;

感谢 Alex Cohn 并回答了 12 月的分享;

This answer expands on Alex Cohn's answer & answered Dec's answer;

这个答案扩展了 Alex Cohn 的答案并回答了 Dec 的答案;

I'm use jpeg turbo 1.3.9, ndk-r9d, about yasm.exe, the ndk-r9d is contained, on after did answered Dec's step 3, I had one error in simd/jsimdext.inc line:182 "%define EXTN(name) _ %+ name ; foo() -> _foo"; change it to "%define EXTN(name) name"; then ok, this problem had fixed;

我正在使用 jpeg turbo 1.3.9,ndk-r9d,关于 yasm.exe,包含 ndk-r9d,在回答了 Dec 的第 3 步之后,我在 simd/jsimdext.inc 行中有一个错误:182 "%define EXTN(name) _ %+ name ; foo() -> _foo"; 将其更改为“%define EXTN(name) name”;那么好的,这个问题已经解决了;

this is my Android.mk

这是我的 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)

回答by Droid Coder

For anyone trying to build the official repo version, I had success using the patch attached here: libjpeg-turbo cross-compile to Android fails.

对于任何试图构建官方 repo 版本的人,我使用这里附加的补丁取得了成功:libjpeg-turbo cross-compile to Android failed

Then, depending on whether you're compiling for 32-bit or 64-bit:

然后,取决于您是为 32 位还是 64 位编译:

export CFLAGS="-DSIZEOF_SIZE_T=4"

or

或者

export CFLAGS="-DSIZEOF_SIZE_T=4"

And run cmake with -DWITH_SIMD=FALSE -DCMAKE_TOOLCHAIN_FILE=your_toolchain_file.

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

Of course, I'm aware that disabling SIMD is not ideal, but at least I managed to get a build I can start using. Hopefully, the buildsystem's NEON SIMD support will get fixed, in the future. Using ./configure also failed to build the correct SIMD for ARM.

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

Incidentally, I wish folks would contribute fixes to the main repo, rather than simply forking it. It's been 2 years since the last change to the repo cited in alex-cohn's answer.

顺便说一句,我希望人们能对主存储库进行修复,而不是简单地分叉它。自上次对 alex-cohn 的回答中引用的 repo 进行更改以来,已经过去了 2 年。