I'm writing a simple proof of concept app that integrates OpenSSL using NDK. Unfortunately, it gives me undefined reference
errors during build.
What I did:
Cross-compiled OpenSSL for Android (x86_64 is shown, and similarly for other ABIs):
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/
Added the following CMakeLists.txt
into project's cpp
dir:
cmake_minimum_required(VERSION 3.18.1)
project("ndk-poc")
add_library(
# Sets the name of the library.
ndk-poc
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
ndk-poc.cpp)
find_library(
# Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that you want CMake to locate.
log)
add_library(libssl STATIC IMPORTED)
set_target_properties(
# Specifies the target library.
libssl
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libssl.a )
include_directories(${CMAKE_SOURCE_DIR}/libs/include/)
target_link_libraries(
# Specifies the target library.
ndk-poc
# Links the target library to the log library
# included in the NDK.
libssl
${log-lib})
And this is my test 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());
}
Results:
I don't see any errors inside Android Studio, but when I try building the project, all usages of OpenSSL's APIs in my test code result in unresolved reference
errors:
...
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.
What did I miss?
CodePudding user response:
OpenSSL consists of (at least) two libraries: libcrypto
which has the general-purpose cryptographic functions; and libssl
which is a TLS implementation built on top of libcrypto
.
So in your case libcrypto
would be the appropriate library to link against.