Static linking of OpenSSL Crypto in CMake
Asked Answered
G

1

5

I need to make a cross-compiled OpenSSL for a MIPS device. I've tried following the documentation. Set OPENSSL_USE_STATIC_LIBS to true and set target_link_libraries to the library files you need.

CMakeLists.txt:

compileAsC99()

if(NOT ${use_http})
    message(FATAL_ERROR "program being generated without HTTP support")
endif()

set(program_c_files
    ...
)

set(program_h_files
    ...
)

include_directories(...)

add_executable(program ${program_c_files} ${program_h_files})

set(OPENSSL_USE_STATIC_LIBS TRUE)
#target_link_libraries(program OpenSSL::Crypto)
target_link_libraries(program /home/program/mips/lib/libssl.so.1.1)
target_link_libraries(program /home/program/mips/lib/libcrypto.so.1.1)

It compiles fine without warnings, but checking the resulting binary tells me that it's still shared library.

readelf -d program:

Dynamic section at offset 0x1bc contains 35 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libssl.so.1.1]
 0x00000001 (NEEDED)                     Shared library: [libcrypto.so.1.1]
 0x0000000f (RPATH)                      Library rpath: [/home/program/mips/lib]

I don't understand what I'm doing wrong.

EDIT: Already looked at Linking statically OpenSSL crypto library in CMake but it didn't tell me anything new.

EDIT 2: Updated the CMakeLists.txt file according to the reply: CMakeLists.txt:

compileAsC99()

if(NOT ${use_http})
    message(FATAL_ERROR "program being generated without HTTP support")
endif()

set(program_c_files
    ...
)

set(program_h_files
    ...
)

include_directories(...)

add_executable(program ${program_c_files} ${program_h_files})

find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
set(OPENSSL_USE_STATIC_LIBS TRUE)
message("OPENSSL FOUND!")
endif()
target_link_libraries(program OpenSSL::Crypto)

Output:

-- IoT Client SDK Version = 1.2.11
-- Provisioning client OFF
-- target architecture: GENERIC
-- Cross compiling not using pkg-config
-- Found CURL: /home/program/mips/lib/libcurl.a (found version "7.63.0")
-- Found CURL: /home/program/mips/lib/libcurl.a
-- target architecture: GENERIC
-- target architecture: GENERIC
-- target architecture: GENERIC
-- target architecture: GENERIC
-- iothub architecture: GENERIC
OPENSSL FOUND!
-- Configuring done
-- Generating done

EDIT PROSPERITY: If you, future people, run into the undefined reference to dlopen, I added the following to my CMakeLists.txt file

target_link_libraries(program ${CMAKE_DL_LIBS})
Giess answered 14/3, 2019 at 14:32 Comment(0)
A
9

Setting to TRUE, variable OPENSSL_USE_STATIC_LIBS forces find_package(OpenSSL) to search the static library. So this variable works only with that call, and if you use its results:

set(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)
target_link_libraries(program OpenSSL::Crypto)

If you have already executed cmake without setting of OPENSSL_USE_STATIC_LIBS, then you need to remove CMake cache (CMakeCache.txt under build directory) before new attempt. Otherwise, already found (shared!) libraries will be used and no re-search will be performed.

Arvillaarvin answered 14/3, 2019 at 14:41 Comment(8)
Still doesn't work. It seems to find the correct ssl and crypto library files according to the build log, but readelfstill reports that those are shared. Tried deleting the ´cmake` folder entirely and rebuilding everything without any change. Is there another flag somewhere that needs to be set somewhere perhaps?Giess
"It seems to find the correct ssl and crypto library files according to the build log" - please, show that part of log, where one can find whether libraries are static or shared. Also, as you have in your code target_link_libraries(program OpenSSL::Crypto), you don't use target_link_libraries(program /home/program/mips/lib/libssl.so.1.1), do you?Arvillaarvin
Updated my post with output and revised CMakeLists.txt.Giess
The output contains static library for libcurl, but your problem is with libssl and libcrypto. Note, that in your updated code you use that answer on related question, not mine. I have added comments for that answer why it is suspicious.Arvillaarvin
Oh, I didn't know that .a were static libraries. That makes more sense then. Updated my toolchain file to use the SET (OPENSSL_USE_STATIC_LIBS TRUE) and now the output says Found OpenSSL: /home/program/mips/lib/libcrypto.a (found version "1.1.1a"). Fails with a lot of undefined references now, but at least it seems to be using the static library instead.Giess
Shared library contain list of all libraries it depends from. When link with a shared library, the linker automatically link with all these dependent libraries. But static libraries doesn't contain such list. When link with a static libcrypto.a you need to explicitely link with all libraries it depends from.Arvillaarvin
How do I link the libraries it requies? find_library?Giess
Linking is always performed with target_link_libraries. But for searching the libraries (instead of hardcoding paths to them) you may use any available way. If the library supports find_package(XXX), then use that command. If the library can be found with pkg-config command-line utility, then use pkg_check_modules. If the library supports none mechanism for search it, then resort to find_library.Arvillaarvin

© 2022 - 2024 — McMap. All rights reserved.