You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CMake交叉编译OpenSSL 1.1.1 for Android的两类问题求助

Android交叉编译OpenSSL 1.1.1 via CMake ExternalProject: 解决ld: unknown option: --sysroot错误并控制安装内容

问题描述

我正在为Android平台交叉编译OpenSSL 1.1.1作为应用依赖库,使用CMake的ExternalProject模块调用OpenSSL自身的构建系统,配置如下:

ExternalProject_Add(openssl
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/openssl
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}
#INSTALL_DIR
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E echo "Starting custom configure"
COMMAND export ANDROID_NDK_HOME=@CMAKE_ANDROID_NDK@
COMMAND CC=clang;AR=@CMAKE_AR@;RANLIB=@CMAKE_RANLIB@;PATH=${OPENSSL_COMPILER_PATH}:${PERL_PATH}
COMMAND ANDROID_NDK_HOME=@CMAKE_ANDROID_NDK@;CC=clang;AR=@CMAKE_AR@;RANLIB=@CMAKE_RANLIB@;PATH=${OPENSSL_COMPILER_PATH}:${PERL_PATH};<SOURCE_DIR>/Configure ${ARCH} no-shared ${CONFIGURE_COMMAND_DEFINITIONS} -I${CMAKE_CURRENT_SOURCE_DIR}/openssl/ -I${CMAKE_CURRENT_SOURCE_DIR}/openssl/include -I@CMAKE_ANDROID_NDK@/sysroot/usr/include -I@CMAKE_ANDROID_NDK@/sysroot/usr/include/${ARCH_INCLUDE_DIR} --prefix=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ --openssldir=$@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ --libdir=""
BUILD_COMMAND export ANDROID_NDK_HOME=@CMAKE_ANDROID_NDK@
COMMAND PATH=${OPENSSL_COMPILER_PATH}:${PERL_PATH}:/bin
COMMAND ANDROID_NDK_HOME=@CMAKE_ANDROID_NDK@;PATH=${OPENSSL_COMPILER_PATH}:${PERL_PATH}:/bin;${MAKE_EXECUTABLE} -j8 build_libs
INSTALL_COMMAND ${MAKE_EXECUTABLE} -j8 install_sw
STEP_TARGETS build install
)

构建过程正常,但执行install目标时出现错误:ld: unknown option: --sysroot=/platforms/android-21/arch-arm,该错误在生成libcrypto和libssl后链接OpenSSL应用时触发。我有两个问题需要求助:

  1. 如何解决这个链接错误?我推测这和Android SDK使用GNU ld而非Clang lld有关;
  2. 如何配置OpenSSL脚本,避免安装OpenSSL应用及其他无关内容?

问题1:解决ld: unknown option: --sysroot错误

你的推测完全正确——GNU ld不支持--sysroot这个Clang/LLVM链接器专属选项,OpenSSL的Android配置脚本在混合工具链环境下可能误将该选项传递给了GNU ld。这里有几个直接有效的解决办法:

方法1:强制指定使用Clang的LLD链接器

在OpenSSL的Configure命令的环境变量中添加LD=ld.lld,确保链接步骤使用Clang配套的LLD,而非系统的GNU ld。修改后的CONFIGURE_COMMAND关键部分如下:

COMMAND ANDROID_NDK_HOME=@CMAKE_ANDROID_NDK@;CC=clang;AR=@CMAKE_AR@;RANLIB=@CMAKE_RANLIB@;LD=ld.lld;PATH=${OPENSSL_COMPILER_PATH}:${PERL_PATH};<SOURCE_DIR>/Configure ${ARCH} no-shared ${CONFIGURE_COMMAND_DEFINITIONS} ...

方法2:使用完整的NDK Clang路径

直接在CC变量中指定NDK工具链里的完整Clang路径(比如@CMAKE_ANDROID_NDK@/toolchains/llvm/prebuilt/<你的主机架构>/bin/${ARCH}-linux-android21-clang),这样OpenSSL脚本会自动关联使用配套的LLD链接器,从根源避免工具链混合的问题。

方法3:修复脚本的--sysroot参数传递(可选)

如果你坚持使用GNU ld,可以修改OpenSSL的Configurations/15-android.conf配置脚本,将--sysroot相关参数替换为GNU ld支持的格式。不过这种方法需要修改OpenSSL源码,不如前两种方法简洁可靠。


问题2:避免安装OpenSSL应用及无关内容

你已经用到了install_sw目标(OpenSSL官方提供的仅安装库和头文件、跳过二进制应用的目标),但可以进一步优化配置来彻底清除无关内容:

1. 在Configure时添加no-apps选项

在Configure命令中加入no-apps参数,直接禁用所有OpenSSL应用程序的构建,从源头避免生成不必要的二进制文件:

<SOURCE_DIR>/Configure ${ARCH} no-shared no-apps ${CONFIGURE_COMMAND_DEFINITIONS} ...

2. 确认install_sw的行为

install_sw默认只会安装:

  • OpenSSL头文件到--prefix/include目录
  • 静态库(因为你指定了no-shared)到--prefix/lib目录
  • 少量必要的配置模板(如果完全不需要,可以通过no-ssl3、no-comp等额外选项进一步精简)

3. 自定义INSTALL_COMMAND(极致精简)

如果你想完全控制安装内容,跳过OpenSSL的安装脚本,直接复制需要的文件:

INSTALL_COMMAND 
  # 创建头文件目录
  ${CMAKE_COMMAND} -E make_directory @CMAKE_INSTALL_PREFIX@/include/openssl
  # 复制头文件
  ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/include/openssl @CMAKE_INSTALL_PREFIX@/include/openssl
  # 复制静态库
  ${CMAKE_COMMAND} -E copy <BINARY_DIR>/libcrypto.a @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/
  ${CMAKE_COMMAND} -E copy <BINARY_DIR>/libssl.a @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/

这种方式完全避免了OpenSSL安装脚本可能带来的冗余内容,只保留你需要的依赖文件。


内容的提问来源于stack exchange,提问作者fabiop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:05:29