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

Android NDK集成OpenSSL静态库时CMake链接报未定义引用错误

NDK集成OpenSSL出现undefined reference错误的解决方法

我正在编写一个通过NDK集成OpenSSL的Demo应用,但构建时出现undefined reference错误。

操作步骤

为Android交叉编译OpenSSL(以x86_64为例,其他ABI操作类似):

openssl-1.1.1q $ ./Configure android-x86_64
openssl-1.1.1q $ make
openssl-1.1.1q $ cp libssl.a <path_to_project_cpp_dir>/libs/x86_64/
openssl-1.1.1q $ cp -r ./include/openssl <path_to_project_cpp_dir>/libs/include/

项目中的CMakeLists.txt

在项目cpp目录中添加如下配置:

cmake_minimum_required(VERSION 3.18.1)

project("ndk-poc")

add_library(
        ndk-poc
        SHARED
        ndk-poc.cpp)

find_library(
        log-lib
        log)

add_library(libssl STATIC IMPORTED)
set_target_properties(
        libssl
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libssl.a )

include_directories(${CMAKE_SOURCE_DIR}/libs/include/)

target_link_libraries(
        ndk-poc
        libssl
        ${log-lib})

测试代码ndk-poc.cpp

#include <jni.h>
#include <string>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/sha.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_techyourchance_android_screens_home_HomeFragment_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {

    /* Testing OPENSSL prime generation and BigNum. */
    BIGNUM *prime1 = NULL;
    int bits = 16; /* Number of bits for the generated prime. */
    int safe = 0;

    prime1 = BN_new();
    if (prime1 == NULL) {
        printf("Out of memory.\n");
    } else if (BN_generate_prime_ex(prime1, bits, safe, NULL, NULL, NULL)) {
        printf("Success!\n");
        int len;
        len = BN_num_bytes(prime1);
        unsigned char* buffer;
        buffer = static_cast<unsigned char*>(malloc(len));
        if (!buffer) {
            printf("Out of memory allocating buffer.\n");
        } else {
            int wlen;
            wlen = BN_bn2bin(prime1, buffer);
            printf("Wrote %d bytes.\n", wlen);
            int i;
            for(i=0;i<wlen;++i) {
                printf("Byte %d of buffer = %d.\n", i, buffer[i]);
            }
            free(buffer);
            char* st;
            st = BN_bn2dec(prime1);
            printf("Prime = %s.\n", st);
            OPENSSL_free(st);
        }
    } else {
        printf("Error generating prime.\n");
    }

    std::string result = "Test completed!";
    return env->NewStringUTF(result.c_str());
}

构建错误信息

Android Studio中未显示错误,但构建项目时,所有调用OpenSSL API的代码均出现unresolved reference错误:

...
C:/Users/Vasiliy/projects/ndk-poc/app/src/main/cpp/ndk-poc.cpp:38: error: undefined reference to 'BN_bn2dec'
C:/Users/Vasiliy/projects/ndk-poc/app/src/main/cpp/ndk-poc.cpp:40: error: undefined reference to 'CRYPTO_free'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

问题原因及解决方法

问题出在仅链接了OpenSSL的libssl库,但缺少了依赖的libcrypto库。OpenSSL的功能被拆分到两个静态库中:

  • libssl.a:主要包含SSL/TLS相关的功能实现
  • libcrypto.a:包含基础加密算法、大数运算(如BN_*系列函数)、内存管理(如CRYPTO_free)等核心功能

测试代码中调用的BN_bn2dec、CRYPTO_free等函数都属于libcrypto.a的范畴,因此必须同时链接这个库。

修复步骤:

  1. 补充拷贝libcrypto.a到项目目录
    交叉编译完成后,除了拷贝libssl.a,还要将libcrypto.a也复制到对应ABI的libs目录:
openssl-1.1.1q $ cp libcrypto.a <path_to_project_cpp_dir>/libs/x86_64/
  1. 在CMakeLists.txt中添加libcrypto的导入配置
    在现有libssl的配置下方,添加以下内容:
add_library(libcrypto STATIC IMPORTED)
set_target_properties(
        libcrypto
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcrypto.a )
  1. 更新链接库列表
    在target_link_libraries中加入libcrypto,确保两个库都被链接:
target_link_libraries(
        ndk-poc
        libssl
        libcrypto
        ${log-lib})

完成以上步骤后,重新构建项目即可解决链接错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:35:26