Mac下编译LibjpegTurbo

Posted by 卢小胖 on 2019-09-07
Estimated Reading Time 6 Minutes
Words 1.4k In Total
Viewed Times

Mac平台编译Libjpegturbo的优势

我尝试过在windows,linux(Ubuntu),mac下用不同的方式来编译,最后实际测试,在mac平台下,用cmake(非AS自带)编译性能是最好的。

1.Debug与Release版本区别:

debug主要用于测试,release主要用于正式版本。按道理是一样的,但是在实际测试过程中发现,debug版本性能非常差劲,在Android上的表现甚至还不如原生方法,release版本提升非常大,比如:debug版本压缩一张1080P图片要150ms,release版本只要10-30ms.

2.cmake与as编译区别:

as自带cmake编译工具,只有10和6两个大版本,而编译出来的想过大多数不理想。性能表现差劲 。所以我们选用了自己的编译链工具cmake,编写sh脚本编译。用AS编译的方法可以去看我前几篇文章,以下只介绍cmake编译。

3.为什么要在mac下编译:

上面提到了在不同平台不同工具下编译的结果都是不同的。在mac平台下编译的.so文件,以手机cpu常用构架v8a为例,压缩一张1080P图片只要10ms,但是在其他平台编译的文件需要30ms,差距还是非常大的。实测windows和linux都不能达到这个效果。

编译准备

  1. 源码下载,https://sourceforge.net/projects/libjpeg-turbo/ 建议下载2.0.x最新版本
  2. ndk下载,在ndk17之前是支持gcc编译的,在ndk17之后默认clang编译,所以我们要下载ndk16b版本。https://developer.android.google.cn/ndk/downloads/
  3. cmake工具和nasm工具,如何安装还请自行查找教程。

源码Cmakelist.txt修改

在编写脚本前,我们需要对源码进行一些微小的修改,主要是注释掉版本号,不然你编译出来的.so文件会有一些莫名其妙的后缀哦。

最外层的主Cmakelist.text:

set_target_properties(turbojpeg PROPERTIES
SOVERSION ${TURBOJPEG_SO_MAJOR_VERSION} VERSION ${TURBOJPEG_SO_VERSION})

sharelib文件夹下的cmakelist.txt修改:

set_target_properties(jpeg PROPERTIES SOVERSION ${SO_MAJOR_VERSION}
VERSION ${SO_MAJOR_VERSION}.${SO_AGE}.${SO_MINOR_VERSION})

找到以上两处注释掉,或者直接删除就好了。下面开始编写脚本文件。

编写脚本文件

build.sh文件

新建build.sh文件,需要修改的地方就是ndk路径了,主意要使用16b版本。

#!/bin/bash
# 获取指定架构名称
if [ "$#" -lt 1 ]; then
THE_ARCH=armv7
else
THE_ARCH=$(tr [A-Z] [a-z] <<< "$1")
fi
# 查找指定架构参数信息
case "$THE_ARCH" in
arm|armv5|armv6|armv7|armeabi)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=arm-linux-androideabi
# android版本下的编译器
ANDROID_PLATFORMS=arm
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=arm
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=arm-linux-androideabi
# include下全名
INCLUDE_PLATFORMS=arm-linux-androideabi
# CFLAGS是否有配置项
CFLAGS_MARCH="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays"
# 文件夹名称
BUILD_NAME=armeabi
;;
armv7a|armeabi-v7a)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=arm-linux-androideabi
# android版本下的编译器
ANDROID_PLATFORMS=arm
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=arm
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=arm-linux-androideabi
# include下全名
INCLUDE_PLATFORMS=arm-linux-androideabi
# CFLAGS是否有配置项
CFLAGS_MARCH="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays"
BUILD_NAME=armeabi-v7a
;;
armv8|armv8a|aarch64|arm64|arm64-v8a)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=aarch64-linux-android
# android版本下的编译器
ANDROID_PLATFORMS=arm64
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=aarch64
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=aarch64-linux-android
# include下全名
INCLUDE_PLATFORMS=aarch64-linux-android
# CFLAGS是否有配置项
CFLAGS_MARCH=""
BUILD_NAME=arm64-v8a
;;
x86)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=x86
# android版本下的编译器
ANDROID_PLATFORMS=x86
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=x86
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=i686-linux-android
# include下全名
INCLUDE_PLATFORMS=i686-linux-android
# CFLAGS是否有配置项
CFLAGS_MARCH=""
BUILD_NAME=x86
;;
x86_64|x64)
# 配置参数
# toolchain下的文件夹名称前缀
TOOLCHAIN_LEFT=x86_64
# android版本下的编译器
ANDROID_PLATFORMS=x86_64
# CMAKE_SYSTEM_PROCESSOR下的配置名称
PROCESSOR_PLATFORMS=x86_64
# prebuilt文件夹下的编译器名称
TOOLCHAIN_PLEBUILT=x86_64-linux-android
# include下全名
INCLUDE_PLATFORMS=x86_64-linux-android
# CFLAGS是否有配置项
CFLAGS_MARCH=""
BUILD_NAME=x86_64
;;
esac
# 基本配置
#ndk所在目录
NDK_PATH=/Users/alexlu/Desktop/ndk/android-ndk-r16b
#编译环境这里是 macOS
BUILD_PLATFORM=darwin-x86_64
#编译工具链版本
TOOLCHAIN_VERSION=4.9
#最低兼容
ANDROID_VERSION=21
# 编译配置
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-${ANDROID_PLATFORMS}
export CFLAGS="${CFLAGS_MARCH} -D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
-isystem ${NDK_PATH}/sysroot/usr/include \
-isystem ${NDK_PATH}/sysroot/usr/include/${INCLUDE_PLATFORMS}"
export LDFLAGS=-pie
TOOLCHAIN=${NDK_PATH}/toolchains/${TOOLCHAIN_LEFT}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
# 创建该架构下的对应文件夹
mkdir -p ${BUILD_NAME}

cd ${BUILD_NAME}
cat <<EOF >toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ${ANDROID_PLATFORMS})
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${TOOLCHAIN_PLEBUILT}-gcc)
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${TOOLCHAIN_PLEBUILT})
EOF

cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-DCMAKE_POSITION_INDEPENDENT_CODE=1 \
../libjpeg-turbo # 这里是源库的地址

make clean
make
make install

build_all.sh

主要就是将各个构架全都执行一遍。

for arch in armeabi armeabi-v7a arm64-v8a x86 x86_64
do
bash build.sh $arch
done

以上脚本编写完成后。开始以下步骤:

  1. 将源码目录修改为libjpeg_turbo (与sh脚本对应就行了)
  2. 在桌面新建test文件夹,将源码libjpeg-turbo文件夹和两个脚本文件放入。
  3. 打开终端,执行:
1.cd desktop/test

2.sudo sh build_all.sh

输入密码即可(mac和linux下密码是不显示的哦?)

或者:

1. cd desktop/test

2. chmod 777 build_all.sh

3. ./build_all.sh
  1. 等待完成编译即可

错误解决,在编译过程中经常会遇到奇怪的问题,可能会一头雾水,最好的解决办法是看log日志,在cmakelisterror.log 或者cmakeoutput.log中可以仔细查找问题根源。

最后附上我编译的文件