Search code examples
androidc++cmakeandroid-ndk

Android CMake: Could NOT find OpenSSL


I'm pretty new to Android with NDK / CMake. However, I'm trying to embed a native CMake library into an Android Application. However, this library depends on OpenSSL.

That's why I downloaded a precompiled version of OpenSSL for Android.

However, when I try to sync the project I get the following error:

 Could NOT find OpenSSL, try to set the path to OpenSSL root folder
 in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES)  
 (found version "1.1.0f")

Here is my (minimal) project structure

<app-name>
   -app
      - src
        - main
          - cpp
            - library
              - CMakeLists.txt
            CMakeLists.txt
   - distribution
     - openssl
       - armeabi
         - include
           - openssl
               ... 
         - lib
            libcrypto.a, libssl.a

In my build.gradle I've defined the following:

externalNativeBuild {
    cmake {
        path 'src/main/cpp/CMakeLists.txt'
    }
}

The /app/src/main/cpp/CmakeLists.txt looks as follows:

cmake_minimum_required(VERSION 3.4.1)


set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../distribution)

set(OPENSSL_ROOT_DIR ${distribution_DIR}/openssl/${ANDROID_ABI})
set(OPENSSL_LIBRARIES "${OPENSSL_ROOT_DIR}/lib")
set(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include)


message("OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES}")
message("OPENSSL_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR}")

find_package(OpenSSL REQUIRED)


add_subdirectory(library)

Solution

  • find_package(...) searches for libraries in a few standard locations (read here - search for "Search paths specified in cmake"). In your case, it fails because it can't find OpenSSL on the machine you're trying to cross-compile the code for Android.

    I know I also had various attempts on linking OpenSSL with my native c++ Android code, and the only way I managed it make it work, was the following:

    SET(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../distribution)
    SET(OPENSSL_ROOT_DIR ${distribution_DIR}/openssl/${ANDROID_ABI})
    
    SET(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
    SET(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include)
    SET(OPENSSL_LIBRARIES "ssl" "crypto")
    
    
    #<----Other cmake code/defines here--->
    
    LINK_DIRECTORIES(${OPENSSL_LIBRARIES_DIR})   
    
    ADD_LIBRARY(library #your other params here#)   
    
    TARGET_INCLUDE_DIRECTORIES(library PUBLIC ${OPENSSL_INCLUDE_DIR})
    TARGET_LINK_LIBRARIES(library ${OPENSSL_LIBRARIES})
    

    I know I also tried to make find_package work correctly, by playing with some of it configuration properties, such as CMAKE_FIND_ROOT_PATH, and some other approaches, but I couldn't get it done.

    Don't know if the solution I provided is the best approach, cmake-wise. Maybe someone has a better way of doing it, but alas, it solved my problem at the time.

    Hope this helps