Home > Net >  Android NDK: CMake fails while linking static library (OpenSSL)
Android NDK: CMake fails while linking static library (OpenSSL)

Time:10-27

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.

  • Related