cpprestsdk icon indicating copy to clipboard operation
cpprestsdk copied to clipboard

CMake config doesn't add needed libcrypto link dependency

Open tonyelewis opened this issue 5 years ago • 11 comments

Not sure about this one…

Summary: if I update websocketpp to develop to get cpprestsdk working with Boost 1.72, the CMake-based build doesn't handle the resulting dependency on libcrypto.

I have a single source file main.cpp:

#include <cpprest/http_client.h>

int main() {
}

…and CMakeLists.txt:

cmake_minimum_required( VERSION 3.7 )

project( main )

find_package( Boost 1.72 REQUIRED system )
find_package( cpprestsdk REQUIRED        )

add_executable       ( main main.cpp                                  )
target_link_libraries( main PRIVATE cpprestsdk::cpprest Boost::system )

(I include the Boost::system because of the issue described in #991)

Since I'm using Boost 1.72, I've checked-out the zaphoyd/websocketpp repo in Release/libs/websocketpp to develop (bc0dc57) as advised on this comment on #1378.

Now the build fails with:

/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: undefined reference to symbol 'CONF_modules_unload@@OPENSSL_1_1_0'
//usr/lib/x86_64-linux-gnu/libcrypto.so.1.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
ninja: build stopped: cannot make progress due to previous errors.

…but succeeds if I add -lcrypto.

Since these files are only using cpprestsdk, I think cpprestsdk's CMake config (and/or the CMake config of its dependencies) should be dealing with this in CMake targets.

Thank you for all work on this library.

tonyelewis avatar Apr 15 '20 06:04 tonyelewis

What happens if you add OpenSSL::Crypto to this line:

https://github.com/microsoft/cpprestsdk/blob/f4124a9ee10042582c795578d69022368877282e/Release/cmake/cpprest_find_openssl.cmake#L68

garethsb avatar Apr 16 '20 22:04 garethsb

Thanks for the response.

If I'm sorry to report that if I add OpenSSL::Crypto as one of the targets in that line, it doesn't change anything.

I tried added message( WARNING ...) in both parts of the surrounding if/else and it seems that the line in question is not being executed, because the if condition fails. Indeed, if I try to explicitly target_link_libraries(cpprestsdk_openssl_internal INTERFACE OpenSSL::Crypto ) before the if, I get an error message about the target OpenSSL::Crypto not being found.

(But adding OpenSSL::Crypto as a dependency of my final executable works.)

tonyelewis avatar Apr 17 '20 13:04 tonyelewis

Perhaps the find script has used the PkgConfig search mechanism a few lines above? Maybe that needs updating to include pkg_search_module(CRYPTO libcrypto REQUIRED) etc. etc.

garethsb avatar Apr 20 '20 10:04 garethsb

@tonyelewis Just a few questions.

  • What is the output to the console, when you run cmake on your example from above with main.cpp and CMakeLists.txt I am getting the following here with boost 1.69:
cmake -G Ninja ..
...
-- Detecting CXX compile features - done
-- Found Boost: /usr/include (found suitable version "1.69.0", minimum required is "1.69") found components: system 
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11") 
-- Found OpenSSL: /usr/lib64/libcrypto.so (found version "1.1.1d")  
-- Configuring done
...
ninja
[2/2] Linking CXX executable main

Tested with cpprestsdk 2.10.14 under Fedora 31 x86_64

~~- Is the following file from cpprestsdk installed on your system (locate cpprestsdk-config.cmake) and if yes, what is its contents? cpprestsdk-config.cmake~~

c72578 avatar Apr 26 '20 14:04 c72578

OK, I could reproduce it now using cpprestsdk 2.10.16 under Fedora 31 and boost 1.69:

ninja
[2/2] Linking CXX executable main
FAILED: main 
: && /usr/lib64/ccache/c++     CMakeFiles/main.dir/main.cpp.o  -o main  /usr/lib64/libcpprest.so.2.10  /usr/lib64/libboost_system.so  -lpthread && :
/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: undefined reference to symbol 'CONF_modules_unload@@OPENSSL_1_1_0'
/usr/bin/ld: /usr/lib64/libcrypto.so.1.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

c72578 avatar Apr 26 '20 14:04 c72578

If you edit the installed cpprestsdk-targets.cmake file, and add the following line again, which is missing in cpprestsdk-targets.cmake from cpprestsdk 2.10.16, it works again: INTERFACE_LINK_LIBRARIES "OpenSSL::SSL" Add it here:

set_target_properties(cpprestsdk::cpprestsdk_openssl_internal PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "CPPREST_NO_SSL_LEAK_SUPPRESS"
  INTERFACE_LINK_LIBRARIES "OpenSSL::SSL"
)

c72578 avatar Apr 26 '20 15:04 c72578

Thanks both for your responses.

Yes - adding INTERFACE_LINK_LIBRARIES "OpenSSL::SSL" into the installed cpprestsdk-targets.cmake fixes the problem for me.

So how can the source repo be modified to make this change?

tonyelewis avatar Apr 26 '20 16:04 tonyelewis

@tonyelewis could you please test the following patch:

diff --git a/Release/cmake/cpprest_find_openssl.cmake b/Release/cmake/cpprest_find_openssl.cmake
index 93336636..db10c829 100644
--- a/Release/cmake/cpprest_find_openssl.cmake
+++ b/Release/cmake/cpprest_find_openssl.cmake
@@ -48,7 +48,7 @@ function(cpprest_find_openssl)
       pkg_search_module(OPENSSL openssl)
     endif()
     if(OPENSSL_FOUND)
-      target_link_libraries(cpprest PRIVATE ${OPENSSL_LDFLAGS})
+      target_link_libraries(cpprest INTERFACE ${OPENSSL_LDFLAGS})
     else()
       find_package(OpenSSL 1.0.0 REQUIRED)
     endif()

It adds -lssl;-lcrypto; to INTERFACE_LINK_LIBRARIES in cpprestsdk-targets.cmake

c72578 avatar Apr 26 '20 17:04 c72578

@c72578 - :+1: - that works for me.

tonyelewis avatar Apr 26 '20 20:04 tonyelewis

I just tested with target_link_libraries(cpprest INTERFACE ${OPENSSL_LDFLAGS}) for cross compile but it isn't working #1378

letrthong avatar Apr 27 '20 17:04 letrthong

When shall this be fixed?

raikrahul avatar Jul 05 '23 08:07 raikrahul