libpng的编译

2,340 阅读2分钟
  • 源码下载地址
  • 参考链接
  • libpng依赖于zlib
  • 最关键的地方就在于在根项目的Application.mk中的APP_CFLAGS += -DPNG_ARM_NEON_OPT=0,因为如果不关闭neon在编译过程中会报错,网上资源相对较少,且有的会用APP_CPPFLAGS += -DPNG_ARM_NEON_OPT=0,导致问题一致的不到解决
    • 报错日志:/pngrtran.c:4782: undefined reference to png_riffle_palette_neon
  • 同时要分清楚Android.mk中的LOCAL_CFLAGSApplication.mk中的APP_CFLAGS的区别:
    • 前者是module_specificcflags而后者是全局的clfags,在编译module的时候前者会覆盖后者
    • Application.mk

关于打包的参数设定

  • APP_CPPFLAGS和所有其他app_使变量应设置Application.mk,每个模块,使用LOCAL_CPPFLAGSLOCAL_CFLAGS
  • export CPPFLAGS="-DPNG_ARM_NEON_OPT=0"
  • PNG_ARM_NEON_IMPLEMENTATION
    • export CPPFLAGS="-DPNG_ARM_NEON_IMPLEMENTATION=2"
  • -mfpu=neon
  • Note that gcc-4.9 defines __ARM_NEON instead of the deprecated ARM_NEON, so we check both variants.
    • 如果支持neo,gcc编译器会传入__ARM_NEON或者__ARM_NEON__的宏,根据该宏来判断怎样选择代码

打包脚本

  • 目录解构:libpng-android/jni/,该目录下有libpng-1.6.37以及zlib-1.2.11目录,且在jni目录下有项目的Android.mk以及Application.mk,而libpng以及zlib目录下分别有自己的Android.mk用于各自的打包

  • libpng打包的Android.mk文件

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := libpng
    LOCAL_C_INCLUDES := 
    # LOCAL_CFLAGS := -DPNG_ARM_NEON_IMPLEMENTATION=2 -DPNG_ARM_NEON_OPT=0
    # LOCAL_CPPFLAGS := -DPNG_ARM_NEON_IMPLEMENTATION=2 -DPNG_ARM_NEON_OPT=0
    LOCAL_LDLIBS := 
    LOCAL_SHARED_LIBRARIES := 
    LOCAL_STATIC_LIBRARIES := libz
    LOCAL_PREBUILTS := 
    LOCAL_SRC_FILES := ./png.c \
    ./pngerror.c \
    ./pngget.c \
    ./pngmem.c \
    ./pngpread.c \
    ./pngread.c \
    ./pngrio.c \
    ./pngrtran.c \
    ./pngrutil.c \
    ./pngset.c \
    ./pngtrans.c \
    ./pngwio.c \
    ./pngwrite.c \
    ./pngwtran.c \
    ./pngwutil.c \
    ./arm/arm_init.c \
    ./arm/filter_neon.S \
    ./arm/filter_neon_intrinsics.c
    
    include $(BUILD_SHARED_LIBRARY)
    # include $(BUILD_STATIC_LIBRARY)
    
    # Auto-generated module by script
    # include $(CLEAR_VARS)
    
    # LOCAL_MODULE := pngtest
    # LOCAL_C_INCLUDES := 
    # LOCAL_CFLAGS := -DPNG_ARM_NEON_IMPLEMENTATION=2 -DPNG_ARM_NEON_OPT=0
    # LOCAL_CPPFLAGS :=-DPNG_ARM_NEON_IMPLEMENTATION=2 -DPNG_ARM_NEON_OPT=0
    # LOCAL_LDLIBS := 
    # LOCAL_SHARED_LIBRARIES := 
    # LOCAL_STATIC_LIBRARIES := libpng
    # LOCAL_PREBUILTS := 
    # LOCAL_SRC_FILES := ./pngtest.c
    
    # include $(BUILD_EXECUTABLE)
    
  • libpng依赖于libz,打包libz的Android.mk

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := libz
    LOCAL_C_INCLUDES := 
    LOCAL_CFLAGS := 
    LOCAL_CPPFLAGS := 
    LOCAL_LDLIBS := 
    LOCAL_SHARED_LIBRARIES := 
    LOCAL_STATIC_LIBRARIES := 
    LOCAL_PREBUILTS := 
    LOCAL_SRC_FILES := ./adler32.c \
    ./compress.c \
    ./crc32.c \
    ./deflate.c \
    ./gzclose.c \
    ./gzlib.c \
    ./gzread.c \
    ./gzwrite.c \
    ./infback.c \
    ./inffast.c \
    ./inflate.c \
    ./inftrees.c \
    ./trees.c \
    ./uncompr.c \
    ./zutil.c \
    
    include $(BUILD_STATIC_LIBRARY)
    
  • 上层的Android.mk

    include $(all-subdir-makefiles)
    
  • 上层的Application.mk

    APP_PLATFORM := android-14
    APP_CFLAGS += -DPNG_ARM_NEON_IMPLEMENTATION=2
    APP_CFLAGS += -DPNG_ARM_NEON_OPT=0
    

libpngzlib的版本对应关系

  • libpngzlib的版本之间有一个对应关系,在libpngpngpriv.h头文件中有如下代码:

    #if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM
    #  error ZLIB_VERNUM != PNG_ZLIB_VERNUM \
          "-I (include path) error: see the notes in pngpriv.h"
    
    • 注意:这里的#不是注释,是预编译指令
    • 其中ZLIB_VERNUMzlib库中的zlib.h头文件中定义的一个宏# define ZLIB_VERNUM 0x1280,对应的版本是1.2.8
    • PNG_ZLIB_VERNUMlibpng库中定义的一个宏:#define PNG_ZLIB_VERNUM 0x1280
    • 要处理这个异常,要么将# error...一行注释掉,也就是不处理两个版本号不一致的情况,要么就是在源码中修改掉两个宏中任何一个让二者一致即可,要么根据需要去下载对应的zlib