Android NDK编译zlib、openssl、curl

在Android开发中如果需要Http,Java层有大名鼎鼎的okHttp库。Java语言也有HttpURLConnection可以直接使用。但是在用C/C++开发native层代码时,如果你需要使用Http,你的头可能会疼一会儿,因为没有现成的接口可用。

好消息是有个强大的库curl,支持HTTP、HTTPS、FTP、FTPS...。功能太过强大,反正我现在只需要HTTP和HTTPS。它提供命令行工具,但我们同样可以通过C/C++调用接口。

要在Android里使用curl,首先得编译它。本文记录在mac系统使用Android NDK编译curl的过程。linux系统应该可以直接复用,Windows系统需要安装cygwin或mingw,Windows安装这个就是要一个shell的执行环境。推荐在mac或linux中编译。

先下载下curl源码,我没有使用github上面的,而是直接在官网下载,这样下载的源码比较干净,没有带那些git版本管理的文件。

如果想让curl支持https,需要依赖openssl。如果要支持压缩传输,需要依赖zlib库。同样,这两个库也没有使用github上面的源码,而是从官网下载。

openssl使用3.0.7(https://www.openssl.org/source/old/3.0/openssl-3.0.7.tar.gz)

zlib使用使用1.2.13(https://www.zlib.net/zlib-1.2.13.tar.gz)

curl使用7.88.0(https://curl.se/download/curl-7.88.0.tar.xz)

Android NDK使用了23.1.7779620。

开源软件的编译就那么几个套路。

1.先执行configure,configure完成后会生成Makefile,然后执行make编译,编译完成后执行make install安装。

2.有的开源软件源码没有configure,需要先autoconf生成configure,然后再执行第一步。

1.编译环境

这个环境是这几个软件都需要用的,我把它写到一个shell文件里面了。也可以在编译时单独配置一下。

build_env.sh

#!/bin/bash
#NDK路径,openssl需要ANDROID_NDK_ROOT变量,所以把它export一下
export ANDROID_NDK_ROOT=$HOME/Library/Android/sdk/ndk/23.1.7779620

#编译平台,我这里是mac,所以是darwin-x86_64
HOST_TAG=darwin-x86_64

#Android api版本
MIN_SDK_VERSION=23

#工具链路径
TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG

#把工具链加到PATH环境变量
PATH=$TOOLCHAIN/bin:$PATH

#输出目录,在build目录下
BUILD_DIR=$PWD/build

2.编译zlib

解压zlib,并cd到zlib目录下

tar xvf zlib-1.2.13.tar.gz
cd zlib-1.2.13

配置编译工具链,就是配置C/C++编译器、汇编器、链接器的路径,由于Android已经放弃了gcc,现在的编译器是clang和clang++。

要适用于所有CPU架构,我们要编译armv8、armv7、x86、x86_64四个平台。他们会使用不同的clang来编译。我们用TARGET_HOST来区分。

aarch64-linux-android表示要编译armv8

armv7a-linux-androideabi表示要编译armv7a

i686-linux-android表示要编译x86

x86_64-linux-android表示要编译x86_64

TARGET_HOST=aarch64-linux-android
ANDROID_ARCH=arm64-v8a
AR=$TOOLCHAIN/bin/llvm-ar
CC=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang
AS=$CC
CXX=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang++
LD=$TOOLCHAIN/bin/ld
RANLIB=$TOOLCHAIN/bin/llvm-ranlib
STRIP=$TOOLCHAIN/bin/llvm-strip

配置好工具链后执行configure。--prefix指定编译完成后软件的安装目录。--static只编译静态库。

INSTALL_DIR=$BUILD_DIR/zlib
./configure --prefix=$INSTALL_DIR/$ANDROID_ARCH --static
#上面设置了BUILD_DIR为根目录build文件夹,所以$INSTALL_DIR/$ANDROID_ARCH的值为 build/zlib/arm64-v8a

再执行make、make install。

make

make install

install后,在根目录build/curl下,出现了arm64-v8a。里面就是arm64-v8a版本的zlib库。

我把四个架构的编译写成shell文件。

build-zlib.sh

#!/bin/bash

tar xzf zlib-1.2.13.tar.gz

source ./build-env.sh

INSTALL_DIR=$BUILD_DIR/zlib

if [ ! -d $INSTALL_DIR ]; then
    mkdir -p $INSTALL_DIR
fi

cd zlib-1.2.13


function build() {
    make distclean
    TARGET_HOST=$1
    ANDROID_ARCH=$2
    AR=$TOOLCHAIN/bin/llvm-ar
    CC=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang
    AS=$CC
    CXX=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang++
    LD=$TOOLCHAIN/bin/ld
    RANLIB=$TOOLCHAIN/bin/llvm-ranlib
    STRIP=$TOOLCHAIN/bin/llvm-strip

    ./configure --prefix=$INSTALL_DIR/$ANDROID_ARCH --static

    make -j8
    make install
    make distclean
}

build aarch64-linux-android arm64-v8a
build armv7a-linux-androideabi armeabi-v7a
build i686-linux-android x86
build x86_64-linux-android x86_64

cd ..

rm -rf cd zlib-1.2.13

3.编译openssl

通过上面的zlib编译,openssl的编译流程大致是一样的,解压代码什么的就没必要记录了。

有点不一样的是openssl的Configure是大写的。并且它自己支持了Android,需要通过参数传递给它。

android-arm64表示编译64位的arm版本。

no-unit-test表示不需要单元测试。

no-shared表示不需要动态库。

-D__ANDROID_API__=$MIN_SDK_VERSION传递Android api版本。

--prefix指定Android目录

./Configure android-arm64 no-unit-test no-shared -D__ANDROID_API__=$MIN_SDK_VERSION --prefix=$INSTALL_DIR/$ANDROID_ARCH

同样写成shell文件

build-openssl.sh

#!/bin/bash

tar xzf openssl-3.0.7.tar.gz

source ./build-env.sh

INSTALL_DIR=$BUILD_DIR/openssl

if [ ! -d $INSTALL_DIR ]; then
    mkdir -p $INSTALL_DIR
fi

cd openssl-3.0.7

function build() {
    TARGET_HOST=$1
    ANDROID_ARCH=$2
    OPENSSL_ARCH=$3
    AR=$TOOLCHAIN/bin/llvm-ar
    CC=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang
    AS=$CC
    CXX=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang++
    LD=$TOOLCHAIN/bin/ld
    RANLIB=$TOOLCHAIN/bin/llvm-ranlib
    STRIP=$TOOLCHAIN/bin/llvm-strip

    ./Configure $OPENSSL_ARCH no-unit-test no-shared -D__ANDROID_API__=$MIN_SDK_VERSION --prefix=$INSTALL_DIR/$ANDROID_ARCH

    make -j8
    make install_sw
    make distclean
}

build aarch64-linux-android arm64-v8a android-arm64
build armv7a-linux-androideabi armeabi-v7a android-arm
build i686-linux-android x86 android-x86
build x86_64-linux-android x86_64 android-x86_64


cd ..

rm -rf openssl-3.0.7

4.编译curl

准备完zlib和openssl之后,就可以编译curl了。同样是老套路,configure,make,make install。

--host和--target把编译器平台传给它。

--prefix依旧还是安装目录。

--with-zlib和--with-openssl就用到了我们上面编译出来的zlib和openssl。我们把目录传给它。

--disable-shared表示不编译动态库,我只需要静态库。

./configure --host=$TARGET_HOST \
            --target=$TARGET_HOST \
            --prefix=$INSTALL_DIR/$ANDROID_ARCH \
            --with-zlib=$BUILD_DIR/zlib/$ANDROID_ARCH \
            --with-openssl=$BUILD_DIR/openssl/$ANDROID_ARCH \
            --disable-shared

curl的完整编译文件如下

build-curl.sh

#!/bin/bash

tar xzf curl-7.88.0.tar.xz

source ./build-env.sh

INSTALL_DIR=$BUILD_DIR/curl

if [ ! -d $INSTALL_DIR ]; then
    mkdir -p $INSTALL_DIR
fi

cd curl-7.88.0


function build() {
    export TARGET_HOST=$1
    export ANDROID_ARCH=$2
    export AR=$TOOLCHAIN/bin/llvm-ar
    export CC=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang
    export AS=$CC
    export CXX=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang++
    export LD=$TOOLCHAIN/bin/ld
    export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
    export STRIP=$TOOLCHAIN/bin/llvm-strip

    ./configure --host=$TARGET_HOST \
                --target=$TARGET_HOST \
                --prefix=$INSTALL_DIR/$ANDROID_ARCH \
                --with-zlib=$BUILD_DIR/zlib/$ANDROID_ARCH \
                --with-openssl=$BUILD_DIR/openssl/$ANDROID_ARCH \
                --with-pic --disable-shared

    make -j8
    make install
    make clean
}


build aarch64-linux-android arm64-v8a
build armv7a-linux-androideabi armeabi-v7a
build i686-linux-android x86
build x86_64-linux-android x86_64

cd ..

rm -rf cd curl-7.88.0

5.大功告成

编译完后,所有的库就在build目录下了。我把build目录上传github,需要的话可以直接使用。

kunliao/build-curl-openssl-zlib-android-ios (github.com)

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值