使用鸿蒙编译工具链交叉编译 libcurl 精华
本文主要讲述交叉编译第三方库(以 libcurl 为例进行讲解)时遇到的一些问题,以及如何解决这些问题。希望能够对大家有所帮助,避免踩坑。
安装 HarmonyOS Native SDK
这里以 macOS系统为例,描述如何安装 HarmonyOS NativeSDK。
- 下载 macOS版本的 DevEco Studio 并安装,下载地址为:
https://developer.harmonyos.com/cn/develop/deveco-studio#download
- 通过 DevEco Studio 的 SDK Manager 下载 HarmonyOS Native SDK
2.1 点击欢迎页中的 Configure(或设置图标)-> Preferences,进入属性配置页面
2.2 点击 Appearance & Behavior -> System Settings -> HarmonyOS SDK 进入 HarmonyOS SDK 页面
2.3 在 SDK Platforms 选项卡中,勾选 Native SDK。注意这里 Native SDK 的版本号为:2.1.1.21,在后面配置环境变量时会用到
2.4 在 SDK Tools 选项卡中,勾选 Toolchains
2.5 点击 OK 按钮
- 配置环境变量
3.1 打开终端工具,执行下述命令,打开 .bash_profile 文件
vi ~/.bash_profile
3.2 输入以下内容
export OHOS_SDK_HONE=$HOME/Library/Huawei/sdk
export OHOS_NATIVE_HOME=$OHOS_SDK_HOME/native/2.1.1.21
3.3 保存并退出编辑器
3.4 在终端执行以下命令,使环境变量生效
source ~/.bash_profile
编译 openssl
由于要在 libcurl 支持 SSL/TLS,所以在编译 libcurl 之前需先编译 openssl 库。这里介绍如何使用鸿蒙编译工具链编译 arm 架构的 openssl 静态库。过程如下:
- 下载 openssl 源码
wget https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_1_1_1g.zip
- 解压缩
unzip OpenSSL_1_1_1g.zip
- 设置交叉编译环境变量
export AR=$OHOS_NATIVE_HOME/llvm/bin/llvm-ar
export CC=$OHOS_NATIVE_HOME/llvm/bin/clang
export LD=$OHOS_NATIVE_HOME?llvm/bin/ld.lld
export CFLAGS="--target=arm-linux-ohos --gcc-toolchain=$OHOS_NATIVE_HOME/llvm --sysroot=$OHOS_NATIVE_HOME/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -MD -march=armv7-a -mthumb"
export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld -lunwind"
export RANLIB=$OHOS_NATIVE_HOME/llvm/bin/llvm-ranlib
- 切换到 openssl-OpenSSL_1_1_1g 目录,执行 Configure 命令。
./Configure linux-armv4 \
--prefix=<输出目录> \
zlib \
no-asm \
no-shared \
no-unit-test \
no-tests
- 执行以下命令开始编译 openssl
make && make install
编译 libcurl
编译 arm 架构的 libcurl 静态库过程如下:
- 下载 libcurl 源码
wget https://github.com/curl/curl/releases/download/curl-7_71_1/curl-7.71.1.zip
- 解压缩
unzip curl-7.71.1.zip
- 设置交叉编译环境变量
export PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH
export AR=$OHOS_NATIVE_HOME/llvm/bin/llvm-ar
export AS=$OHOS_NATIVE_HOME/llvm/bin/llvm-as
export LD=$OHOS_NATIVE_HOME/llvm/bin/ld.lld
export RANLIB=$OHOS_NATIVE_HOME/llvm/bin/llvm-ranlib
export STRIP=$OHOS_NATIVE_HOME/llvm/bin/llvm-strip
export CC=$OHOS_NATIVE_HOME/llvm/bin/clang
export CFLAGS="--target=arm-linux-ohos --gcc-toolchain=$OHOS_NATIVE_HOME/llvm --sysroot=$OHOS_NATIVE_HOME/sysroot -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -mfpu=neon -funwind-tables -fstack-protector -fno-strict-aliasing"
export CPPFLAGS="--gcc-toolchain=$OHOS_NATIVE_HOME/llvm --sysroot=$OHOS_NATIVE_HOME/sysroot"
export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld"
export LIBS="-lunwind"
- 切换到 curl-7.71.1 目录,执行 configure 命令
./configure --prefix=<输出目录> \
--target=arm-linux-ohos \
--host=arm-linux \
--with-ssl=<openssl 静态库输出目录> \
--disable-shared \
--disable-threaded-resolver
- 执行以下命令开始编译libcurl
make && make install
踩过的坑
- 编译 openssl 静态库运行 Configure 命令时,需要指定所使用的编译器模版,例如编译 Android arm 版本时指定的值为:android-arm。但鸿蒙编译工具链并没有在 Configure的支持列表中。通过查看 Configurations/15-android.conf 文件,可以看到编译 Android arm版本时使用的模版为:
"android-arm" => {
inherit_from => [ "android", asm("armv4_asm") ],
bn_ops => add("RC4_CHAR"),
}
所以这里我们使用 linux-armv4。
2. 编译 libcurl 静态库运行 configure 命令时,出现下述错误提示:
checking whether to enable the threaded resolver... yes
checking whether to use POSIX threads for threaded resolver... auto
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking for pthread_create... no
checking for pthread_create in -lpthread... no
configure: error: Threaded resolver enabled but no thread library found
原因是鸿蒙编译工具链没有提供独立的pthread 线程库,解决方法是在执行configure命令时,指定 --disable-threaded-resolver 即可。
3. 编译 libcurl静态库执行 make命令时,出现下述错误提示:
CC libcurl_la-url.lo
url.c:57:2: error: "We can't compile without socket() support!"
#error "We can't compile without socket() support!"
^
1 error generated.
原因是在 configure执行过程中,没有检测到可用的socket 函数,导致未定义 HAVE_SOCKET 宏。解决方式是,在 CPPFLAGS 环境变量中加上 --gcc-toolchain 和 --sysroot 的定义。
结语
个人体验是鸿蒙编译工具链还不是很完善,例如:缺少独立的 atomic、gcc 等。希望华为可以尽快补齐这方面的能力,与 NDK 比肩。也希望鸿蒙能够越走越远。
还没遇到,先mark一下。
博主,编译出libcurl后,在dev eco中链接编译,但是报很多库内函数未定义的错,请问有可能是什么原因呀?ld.lld: error: undefined symbol: EVP_sha256
>>> referenced by sha256.c
>>> libcurl_la-sha256.o:(my_sha256_init) in archive D:/1_liutian/5_app/3_native/native/entry/src/main/cpp/lib/libcurl.a
>>> referenced by openssl.c
>>> libcurl_la-openssl.o:(ossl_sha256sum) in archive D:/1_liutian/5_app/3_native/native/entry/src/main/cpp/lib/libcurl.a