CMake config doesn't add needed libcrypto link dependency
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.
What happens if you add OpenSSL::Crypto to this line:
https://github.com/microsoft/cpprestsdk/blob/f4124a9ee10042582c795578d69022368877282e/Release/cmake/cpprest_find_openssl.cmake#L68
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.)
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.
@tonyelewis Just a few questions.
- What is the output to the console, when you run
cmakeon your example from above withmain.cppandCMakeLists.txtI 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~~
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.
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"
)
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 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 - :+1: - that works for me.
I just tested with target_link_libraries(cpprest INTERFACE ${OPENSSL_LDFLAGS}) for cross compile but it isn't working #1378
When shall this be fixed?