编译Android环境的libjpeg-turbo使用cmake

1. libjpeg-turbo

  前面已经编译过1.5.9[1]版本的libjpeg-turbo,现在版本升级到2.0.1,基于CMake编译。

  依然还是一样,按照官网介绍,libjpeg-turbolibjpeg2-6倍,得益于它高度优化的哈夫曼算法。在许多情况下,libjpeg-turbo的性能可与专有的高速JPEG编解码器相媲美.

On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg, all else being equal. On other types of systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by virtue of its highly-optimized Huffman coding routines. In many cases, the performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs

2. 编译过程

2.1 编译环境

在Windows 10的虚拟机VM上的Ubuntu中编译

ubuntu

2.2 编译要求

我们将参照源码中的BUILDING.md编译,github地址BUILDING.md

NDK
  Linux 64 位 (x86) / android-ndk-r15c

CMakeandroid-cmake
  cmake-3.12.1-Linux-x86_64

NASM 或者 YASM
  如果需要编译x86 或者 x86-64的库,需要安装NASM 2.10及以上或者YASM 2.10及以上版本。

tool

2.3 配置环境变量

把Cmake配置进系统环境变量,当然这不是必须的。


env.jpg

2.4 编译

2.4.1 下载源码

下载并解压源码https://github.com/libjpeg-turbo/libjpeg-turbo

2.4.2 编译脚本

2.4.2.1 sh编译脚本(自定义编译链)

注意
  这种方式是完全按照源码中的BUILDING.md构建,稍显复杂,容易出错。但是不要求CMake的交叉编译工具链,也就是说,我们随便在CMake官网下载Linux版本就可以用了。

#!/bin/sh

# lib-name
MY_LIBS_NAME=libjpeg-turbo
MY_SOURCE_DIR=$(pwd)/libjpeg-turbo-master
#编译的过程中产生的中间件的存放目录,为了区分编译目录,源码目录,install目录
MY_BUILD_DIR=binary

export PATH=/home/as/Android/cmake-3.12.1-Linux-x86_64/bin:$PATH

NDK_PATH=/home/as/Android/android-ndk-r15c
BUILD_PLATFORM=linux-x86_64
TOOLCHAIN_VERSION=4.9
ANDROID_VERSION=24

ANDROID_ARMV5_CFLAGS="-march=armv5te"
ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"  # -mfpu=vfpv3-d16  -fexceptions -frtti
ANDROID_ARMV8_CFLAGS="-march=armv8-a"   # -mfloat-abi=softfp -mfpu=neon -fexceptions -frtti
ANDROID_X86_CFLAGS="-march=i386 -mtune=intel -mssse3 -mfpmath=sse -m32"
ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"

# params($1:arch,$2:arch_abi,$3:host,$4:compiler,$5:cflags,$6:processor)
build_bin() {

    echo "-------------------star build $2-------------------------"

    ARCH=$1                # arm arm64 x86 x86_64
    ANDROID_ARCH_ABI=$2    # armeabi armeabi-v7a x86 mips
    # 最终编译的安装目录
    PREFIX=$(pwd)/dist/${MY_LIBS_NAME}/${ANDROID_ARCH_ABI}/
    HOST=$3
    COMPILER=$4
    PROCESSOR=$6
    SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-${ARCH}
    CFALGS="$5"
    TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
    
    # build 中间件
    BUILD_DIR=./${MY_BUILD_DIR}/${ANDROID_ARCH_ABI}

    export CFLAGS="$5 -Os -D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
                   -isystem ${NDK_PATH}/sysroot/usr/include \
                   -isystem ${NDK_PATH}/sysroot/usr/include/${HOST} "
    export LDFLAGS=-pie

    echo "path==>$PATH"
    echo "build_dir==>$BUILD_DIR"
    echo "ARCH==>$ARCH"
    echo "ANDROID_ARCH_ABI==>$ANDROID_ARCH_ABI"
    echo "HOST==>$HOST"
    echo "CFALGS==>$CFALGS"
    echo "COMPILER==>$COMPILER-gcc"
    echo "PROCESSOR==>$PROCESSOR"

    mkdir -p ${BUILD_DIR}   #创建当前arch_abi的编译目录,比如:binary/armeabi-v7a
    cd ${BUILD_DIR}         #此处 进了当前arch_abi的2级编译目录


cat >toolchain.cmake << EOF 
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR $6)
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${COMPILER}-gcc)
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${COMPILER})
EOF # 此处不顶格写脚本会报一个错误

    cmake -G"Unix Makefiles" \
          -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
          -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
          -DCMAKE_INSTALL_PREFIX=${PREFIX} \
          -DWITH_JPEG8=1 \
          ${MY_SOURCE_DIR}

    make clean
    make
    make install

    #从当前arch_abi编译目录跳出,对应上面的cd ${BUILD_DIR},以便function多次执行
    cd ../../

    echo "-------------------$2 build end-------------------------"
}

# build armeabi
build_bin arm armeabi arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV5_CFLAGS" arm

#build armeabi-v7a
build_bin arm armeabi-v7a arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV7_CFLAGS" arm

#build arm64-v8a
build_bin arm64 arm64-v8a aarch64-linux-android aarch64-linux-android "$ANDROID_ARMV8_CFLAGS" aarch64

#build x86
build_bin x86 x86 x86 i686-linux-android "$ANDROID_X86_CFLAGS" i386

#build x86_64
build_bin x86_64 x86_64 x86_64 x86_64-linux-android "$ANDROID_X86_64_CFLAGS" x86_64

2.4.2.2 android-cmake(自带编译链)

注意
  这个脚本要求Linux环境的Android-cmake,通过Android sdk-manager下载更新cmake,android-cmake已经自带交叉编译工具链,但通常我们不使用cmake带的,因为他脚本里写死了NDK版本12,而NDK的build/cmake目录里也带了相应的编译链,所以,我们一般使用我们NDK自带的编译链

# lib-name
MY_LIBS_NAME=libjpeg-turbo
MY_SOURCE_DIR=$(pwd)/libjpeg-turbo-master
MY_BUILD_DIR=binary

CMAKE_PATH=/home/as/Android/cmake-3.6.4111459-linux-x86_64

export PATH=${CMAKE_PATH}/bin:$PATH

NDK_PATH=/home/as/Android/android-ndk-r15c
BUILD_PLATFORM=linux-x86_64
TOOLCHAIN_VERSION=4.9
ANDROID_VERSION=24

ANDROID_ARMV5_CFLAGS="-march=armv5te"
ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"  # -mfpu=vfpv3-d16  -fexceptions -frtti
ANDROID_ARMV8_CFLAGS="-march=armv8-a "                   # -mfloat-abi=softfp -mfpu=neon -fexceptions -frtti
ANDROID_X86_CFLAGS="-march=i386 -mtune=intel -mssse3 -mfpmath=sse -m32"
ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"

# params($1:arch,$2:arch_abi,$3:host,$4:compiler,$5:cflags,$6:processor)
build_bin() {

    echo "-------------------start build $1-------------------------"

    ANDROID_ARCH_ABI=$1    # armeabi armeabi-v7a x86 mips
    CFALGS="$2"
    
    PREFIX=$(pwd)/dist/${MY_LIBS_NAME}/${ANDROID_ARCH_ABI}/
    # build 中间件
    BUILD_DIR=./${MY_BUILD_DIR}/${MY_LIBS_NAME}/${ANDROID_ARCH_ABI}

    echo "path==>$PATH"
    echo "build_dir==>$BUILD_DIR"
    echo "ANDROID_ARCH_ABI==>$ANDROID_ARCH_ABI"
    echo "CFALGS==>$CFALGS"


    mkdir -p ${BUILD_DIR}
    cd ${BUILD_DIR}

    # -DCMAKE_MAKE_PROGRAM=${NDK_PATH}/prebuilt/${BUILD_PLATFORM}/bin/make \
    # -DCMAKE_ASM_COMPILER=${NDK_PATH}/prebuilt/${BUILD_PLATFORM}/bin/yasm \

    cmake -G"Unix Makefiles" \
      -DANDROID_ABI=${ANDROID_ARCH_ABI} \
      -DANDROID_PLATFORM=android-${ANDROID_VERSION} \
      -DCMAKE_BUILD_TYPE=Release \
      -DANDROID_NDK=${NDK_PATH} \
      -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
      -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
      -DCMAKE_INSTALL_PREFIX=${PREFIX} \
      -DANDROID_ARM_NEON=TRUE \
      -DANDROID_TOOLCHAIN=clang \
      -DANDROID_STL=c++_static \
      -DCMAKE_C_FLAGS="${CFALGS} -Os -Wall -pipe -fPIC" \
      -DCMAKE_CXX_FLAGS="${CFALGS} -Os -Wall -pipe -fPIC" \
      -DANDROID_CPP_FEATURES=rtti exceptions \
      -DWITH_JPEG8=1 \
      ${MY_SOURCE_DIR}

    make clean
    make
    make install

    cd ../../../

    echo "-------------------$1 build end-------------------------"
}

# build armeabi
build_bin armeabi "$ANDROID_ARMV5_CFLAGS"

#build armeabi-v7a
build_bin armeabi-v7a "$ANDROID_ARMV7_CFLAGS"

#build arm64-v8a
build_bin arm64-v8a "$ANDROID_ARMV8_CFLAGS"

#build x86
build_bin x86 "$ANDROID_X86_CFLAGS"

#build x86_64
build_bin x86_64 "$ANDROID_X86_64_CFLAGS"

2.4.3 去掉版本号

动态库的版本号
  安装规则一般so都会带版本号,但是如果我们在Android上使用不带版本号。可以通过修改CMake脚本,不带版本号。

动态库实现版本号一般使用SET_TARGET_PROPERTIES指令定义一下语句:
  SET_TARGET_PROPERTIES(target PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本,SOVERSION 指代 API 版本

  1. libjpeg-turbo-master/CMakeLists.txt中注释
    turbojpeg注释版本号
  2. libjpeg-turbo-master/sharedlib/CMakeLists.txt中注释
    jpeg注释版本号

2.4.4 执行编译脚本

sh build.sh

x86_64.jpg

注释版本号编译
arm64-v8a注释版本号

注释版本号message

2.4.5 编译可能遇到的问题

  1. Syntax error: end of file unexpected (expecting "}")
    编译脚本中 cat <<EOF >文件名 内容 EOF,最好顶格写,否则可能出现上述错误

  2. 未识别的cflags参数
    一些cflags参数可能导致编译识别,修改编译出错的参数即可

2.4.6 install结果

dist/libjpeg-turbo

dist/libjpeg-turbo/arm64-v8a

dist/libjpeg-turbo/arm64-v8a/lib

注释版本号的编译


注释版本号

  1. 编译Android环境的libjpeg-turbo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容