ndk编译libcurl,openssl支持https

最近在开发跨平台项目使用语言时c/c++,网络库使用的libcurl,需要支持https。本篇文章主要介绍android平台的libcurl编译。
1.编译工具: Linux 16.04, ndk 23
2.开源包下载:
zlib库 http://www.zlib.net/ 最新版本就可以(作者下载版本2.13.0);
openssl库 https://www.openssl.org/source/ 根据需求下载版本(作者下载版本1.1.1);
libcurl库 https://curl.se/download.html 根据需求下载版本 (为了项目的兼容性,作者使用版本7.58.0)。
3.编译:
3.1 写通用shell, 文件名称build-env.sh

		#!/bin/bash
		#NDK path,openssl need ANDROID_NDK_ROOT var,so export
		export ANDROID_NDK_ROOT=$HOME/android_libs/android-ndk-r23b
		export ANDROID_NDK_HOME=$HOME/android_libs/android-ndk-r23b
		#complier platform linux-x86_64
		HOST_TAG=linux-x86_64
		#Android api version
		MIN_SDK_VERSION=23
		#toolchains path
		TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG
		#add path 
		PATH=$TOOLCHAIN/bin:$PATH
		#out dir build
		BUILD_DIR=$PWD/build

由于Android已经放弃了gcc,现在的编译器是clang和clang++。要适用于所有CPU架构,我们要编译armv8、armv7、x86、x86_64四个平台。他们会使用不同的clang来编译,aarch64-linux-android表示要编译armv8,armv7a-linux-androideabi表示要编译armv7a,i686-linux-android表示要编译x86,x86_64-linux-android表示要编译x86_64。
3.2 编译zlib, 配置好工具链后执行configure,我们同样编写脚本执行,脚本名称build-zlib.sh

	  #!/bin/bash
		CRTDIR=$(pwd)
		tar xzf $CRTDIR/zlib-1.2.13.tar.gz
		source $CRTDIR/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 --shared --enable-shared

		    make -j8
		    make install
		    make distclean
		}
		build aarch64-linux-android arm64-v8a
		build x86_64-linux-android x86_64
		cd ..
		rm -rf cd $CRTDIR/zlib-1.2.13

这边我只需要arm64-v8a 和 x86_64平台的库,这边我编译出的arm64-v8a库有一点问题(libcurl检查连接时找不到libz动态库)。
3.3 openssl编译,我只需要arm64-v8a 和 x86_64平台的库,同样继续写脚本,名称build-openssl.sh

	 #!/bin/bash
    CRTDIR=$(pwd)
    tar xzf $CRTDIR/openssl-1.1.1s.tar.gz
    source $CRTDIR/build-env.sh
    INSTALL_DIR=$BUILD_DIR/openssl
    if [ ! -d $INSTALL_DIR ]; then
        mkdir -p $INSTALL_DIR
    fi
    cd openssl-1.1.1s
	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 -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 x86_64-linux-android x86_64 android-x86_64
    cd ..
     rm -rf $CRTDIR/openssl-1.1.1s

no-unit-test表示不需要单元测试,-D__ANDROID_API__=$MIN_SDK_VERSION传递Android api版本。
3.4 libcurl编译,准备工作已经完成(zlib,openssl编译完成),同样是configure,make,make install 步骤。关键参数可以查看configure文件使用。同样脚本文件执行,脚本名称build-curl.sh

     #!/bin/bash
     CRTDIR=$(pwd)
    tar xzf $CRTDIR/curl-7.58.0.tar.gz
    source $CRTDIR/build-env.sh
    INSTALL_DIR=$BUILD_DIR/curl
    
    if [ ! -d $INSTALL_DIR ]; then
        mkdir -p $INSTALL_DIR
    fi
  
    cd curl-7.58.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-ssl=$BUILD_DIR/openssl/$ANDROID_ARCH --with-ca-bundle=/data/zhangaichen/cacert.pem --with-pic --enable-shared --enable-static       
        make -j8
        make install
        make clean
    }
    build aarch64-linux-android arm64-v8a
    build x86_64-linux-android x86_64
    cd ..
    rm -rf cd $CRTDIR/curl-7.58.0

执行脚本,生成的x86_64环境和arm64-v8a环境库。
4.编译中遇到问题
4.1 脚本执行使用sh,报错 source: not found,查找资料发现source属于bash脚本,执行 bash xxx.sh 解决此问题。
4.2libcurl编译库arm64-v8a环境的库不支持zlib,重新执行查看编译输出报configure: WARNING: configure found only the libz header file, not the lib! 没有找到zlib动态库,继续去本地找config.log(注释掉rm -rf cd $CRTDIR/curl-7.58.0这一行)查看日志,找到ld: error: /home/data/android_complier/build/zlib/arm64-v8a/lib/libz.so is incompatible with aarch64linux
clang-12: error: linker command failed with exit code 1 (use -v to see invocation),发现是libz.so与要求不符合,去查看arm64-v8a环境libz.so截图如下在这里插入图片描述
将libz.so删除,从arm64-v8a系统里导出,放到此路径下,重新编译liburl的arm64-v8a环境支持zlib功能。
5.参考资料:
5.1 https://blog.csdn.net/lkun2002/article/details/129595631?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-5-129595631-blog-126852683.235v38pc_relevant_default_base&spm=1001.2101.3001.4242.4&utm_relevant_index=8
5.2 https://blog.csdn.net/weixin_41399054/article/details/121901382

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用NDK编译OpenSSL的方法如下: 1. 下载OpenSSL源代码和NDK。 2. 将OpenSSL源代码解压到一个目录下,比如 `~/openssl-1.1.1g`。 3. 在 `~/openssl-1.1.1g` 目录下创建一个名为 `Application.mk` 的文件,文件内容如下: ``` APP_ABI := armeabi-v7a APP_PLATFORM := android-21 ``` 其中 `APP_ABI` 表示编译的目标平台,这里选择 `armeabi-v7a`;`APP_PLATFORM` 表示使用的Android版本,这里选择 `android-21`。 4. 在 `~/openssl-1.1.1g` 目录下创建一个名为 `Android.mk` 的文件,文件内容如下: ``` LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := openssl LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/crypto/*.c) LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/ssl/*.c) LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_CFLAGS := -DOPENSSL_NO_ASM -DOPENSSL_ANDROID LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) include $(BUILD_SHARED_LIBRARY) ``` 其中 `LOCAL_MODULE` 表示生成的库文件名,这里设为 `openssl`;`LOCAL_SRC_FILES` 表示需要编译的源文件;`LOCAL_C_INCLUDES` 表示头文件路径;`LOCAL_CFLAGS` 表示编译选项,这里禁用汇编和启用Android特有的宏定义;`LOCAL_LDLIBS` 表示链接库,这里链接 `liblog.so`。 5. 在终端中进入 `~/openssl-1.1.1g` 目录,执行以下命令: ``` $ export NDK_HOME=/path/to/ndk $ $NDK_HOME/ndk-build ``` 其中 `/path/to/ndk` 是NDK的安装路径。执行完毕后,在 `~/openssl-1.1.1g/libs/armeabi-v7a` 目录下会生成 `libopenssl.so` 文件。 6. 将 `libopenssl.so` 文件复制到Android工程的 `libs/armeabi-v7a` 目录下。 7. 在Android工程的 `build.gradle` 文件中添加以下代码: ``` android { // ... sourceSets { main { jniLibs.srcDirs = ['libs'] } } } ``` 这样就可以在应用中使用OpenSSL库了。 注意:在使用OpenSSL时,需要在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.INTERNET" /> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值