Search code examples
cmakeopensslshared-librariesldundefined-reference

How to solve `ld: undefined reference to SSL_get_peer_certificate` in a CMake project


I have a CMake project in Linux in which I successfully build a shared library. I will then use the library in an executable.

###########################
# manager SHARED LIBRARY
###########################
add_library(manager SHARED)
set_property(TARGET manager PROPERTY CXX_STANDARD 17)
target_sources(manager PRIVATE "src/manager.cpp" "src/manager.h")
target_include_directories(manager PUBLIC src)
target_include_directories(manager PUBLIC ${M_INCLUDE_DIR})
target_link_directories(manager PUBLIC ${M_LIB_DIR})
target_link_libraries(manager PUBLIC ${M_LIB_FILES})
set_target_properties(manager PROPERTIES ENABLE_EXPORTS ON)
target_link_libraries(manager PUBLIC
        ZLIB::ZLIB
        OpenSSL::SSL OpenSSL::Crypto
)
add_library(manager::manager ALIAS manager)
# manager::manager is built successfully in both Windows and Linux

###########################
# MYAPP
########################### 
add_executable(myapp)
target_sources(myapp PRIVATE "src/main-manager.cpp")
target_link_libraries(myapp PRIVATE manager::manager)
# myapp is built successfully ONLY in Windows, it fails in Linux

In both Windows and Linux, I can build the shared library manager. However, myapp, which uses manager, is only built successfully in Windows and I get the following link errors in Linux:

/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: lib/libmanager.so: undefined reference to `SSL_get_peer_certificate'
/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: lib/libmanager.so: undefined reference to `EVP_CIPHER_iv_length'
/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: lib/libmanager.so: undefined reference to `EM_put_error'
/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: lib/libmanager.so: undefined reference to `EVP_PKEY_size'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/myapp.dir/build.make:120: bin/myapp] Error 1
make[2]: *** [CMakeFiles/Makefile2:552: CMakeFiles/myapp.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:559: CMakeFiles/myapp.dir/rule] Error 2
make: *** [Makefile:296: myapp] Error 2

All the undefined references, SSL_get_peer_certificate, EVP_CIPHER_iv_length, EM_put_error, EVP_PKEY_size belong to the OpenSSL library which is PUBLICly included in manager and Windows recognized this and creates myapp.exe, but Linux fails to do so.

Could someone kindly help me out? Thank you very much in advance.


Solution

  • By the looks of it, you are using old versions of ssl.h and evp.h etc.

    In OpenSSL 3, SSL_get_peer_certificate is just a macro for SSL_get1_peer_certificate and EVP_CIPHER_iv_length is a macro for EVP_CIPHER_get_iv_length.

    The functions it should try finding when linking is therefore SSL_get1_peer_certificate and EVP_CIPHER_get_iv_length - but since the old headers do not contain this mapping, it tries to find the functions by their old names inside the OpenSSL 3 library, which doesn't contain those functions.

    Make sure that you use the correct header files from your vcpkg installation and you should be able to pass this hurdle.