2

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)
dominik
  • 1,319
  • 13
  • 23
  • use this: [link](https://stackoverflow.com/questions/11896304/openssl-is-not-recognized-as-an-internal-or-external-command/44199907#44199907) it will help you... – Ajay Mistry Aug 30 '17 at 10:55

4 Answers4

3

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

cjurjiu
  • 1,758
  • 13
  • 21
  • Thanks, I tried your approach. Unfortunately I receive the same error message. I only changed `ADD_LIBRARY` to `add_subdirectory(library) add_library(library ${library_srcs})` – dominik Aug 30 '17 at 12:23
  • Ahh, I see. You're implying that `find_package(...)` does not work at all. In that case I have to edit `library/CMakeLists.txt` and remove `find_package` right? – dominik Aug 30 '17 at 12:30
  • well, using the approach I suggested you don't need find_package, not for OpenSSL, since you are providing the math manually to OpenSSL. You can use find_package just fine if you need other stuff, such as OpenGL – cjurjiu Aug 31 '17 at 04:41
  • I also considered "library" to be the project that needs OpenSSL. If that's not the case, then you could do `add_subdirectory(library) add_library(library ${library_srcs}) LINK_DIRECTORIES(${OPENSSL_LIBRARIES_DIR}) ADD_LIBRARY(myCppNativeCore #your other params here#) TARGET_INCLUDE_DIRECTORIES(myCppNativeCore PUBLIC ${OPENSSL_INCLUDE_DIR}) TARGET_LINK_LIBRARIES(myCppNativeCore library ${OPENSSL_LIBRARIES})` to add both your `library` and the OpenSSL dependencies to your `myCppNativeCore` library, which presumably lives in `/app/src/main/cpp` – cjurjiu Aug 31 '17 at 04:42
  • Hi @cjurjiu I know this is an old thread but I posted a solution that properly relies on the `find_package(OpenSSL)` mechanism, in case you are interested. – piwi Feb 27 '20 at 10:50
2

The reason OpenSSL is not found is because all the find_*() commands also rely on the variable CMAKE_SYSROOT variable, which is used to prefix paths searched by those commands. This is used when cross-compiling to point to the root directory of the target environment.

A solution is to add the path where OpenSSL is located to CMAKE_FIND_ROOT_PATH; the documentation of find_library() states:

The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more directories to be prepended to all other search directories. This effectively “re-roots” the entire search under given locations.

This solution works for me:

set(OPENSSL_ROOT_DIR "/path/to/openssl/for/android")
list(APPEND CMAKE_FIND_ROOT_PATH "${OPENSSL_ROOT_DIR}")
find_package(OpenSSL)
piwi
  • 5,136
  • 2
  • 24
  • 48
0

For me it worked to import openssl via gradle and then linking the fetched lib like described here

Laurenz Honauer
  • 254
  • 1
  • 12
0

Either append NO_CMAKE_FIND_ROOT_PATH to your find_* command, e.g.

find_package(OpenSSL REQUIRED NO_CMAKE_FIND_ROOT_PATH)

Or set CMAKE_FIND_ROOT_PATH_MODE_* variables (like this) to NEVER. The following options fixed the Android and iOS builds on macOS for me:

-DOPENSSL_USE_STATIC_LIBS=TRUE \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER
Sergei Ousynin
  • 170
  • 2
  • 13