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的范畴,因此必须同时链接这个库。
修复步骤:
- 补充拷贝libcrypto.a到项目目录
交叉编译完成后,除了拷贝libssl.a,还要将libcrypto.a也复制到对应ABI的libs目录:
openssl-1.1.1q $ cp libcrypto.a <path_to_project_cpp_dir>/libs/x86_64/
- 在CMakeLists.txt中添加libcrypto的导入配置
在现有libssl的配置下方,添加以下内容:
add_library(libcrypto STATIC IMPORTED) set_target_properties( libcrypto PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcrypto.a )
- 更新链接库列表
在target_link_libraries中加入libcrypto,确保两个库都被链接:
target_link_libraries( ndk-poc libssl libcrypto ${log-lib})
完成以上步骤后,重新构建项目即可解决链接错误。
内容的提问来源于stack exchange,提问作者Vasiliy
相关产品推荐
相关产品推荐

