Building CMake with static OpenSSL libraries fails to link properly
I'm building cmake itself, and I want to link in static OpenSSL libraries. To do this when I configure CMake source code I add OPENSSL_INCLUDE_DIR
, OPENSSL_CRYPTO_LIBRARY
, and OPENSSL_SSL_LIBRARY
. However when the build attempts to link the curl test it fails trying to locate some pthread functions. Examining the link line I see that the libraries linked in look like this:
.../libssl.a -lpthread -ldl .../libcrypto.a ...
Since -lpthread
comes before libcrypto.a
, we get link errors.
Digging through what happens, the issue is here in Modules/FindOpenSSL.cmake
:
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} )
list(REMOVE_DUPLICATES OPENSSL_LIBRARIES)
The problem is that OPENSSL_SSL_LIBRARIES
has computed its prerequisites and equals libssl.a;pthread;dl
and OPENSSL_CRYPTO_LIBRARIES
has computed its prerequisites and equals libcrypto.a;pthread;dl
, so OPENSSL_LIBRARIES
ends up being libssl.a;pthread;dl;libcrypto.a;pthread;dl
.
Then the REMOVE_DUPLICATES
runs and keeps the first instance removing the others, so OPENSSL_LIBRARIES
ends up being libssl.a;pthread;dl;libcrypto.a
and the link fails.
I hacked around this in my local copy by simply doing a double-reverse trick and changing the above code to:
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} )
list(REVERSE OPENSSL_LIBRARIES)
list(REMOVE_DUPLICATES OPENSSL_LIBRARIES)
list(REVERSE OPENSSL_LIBRARIES)
This works fine but probably the FindOpenSSL.cmake
module should be enhanced to combine the search for dependencies of both of these libraries together, rather than one at a time (e.g., this section needs some love:
if(_OpenSSL_has_dependencies)
_OpenSSL_add_dependencies( OPENSSL_SSL_LIBRARIES "${OPENSSL_SSL_LIBRARY}" )
_OpenSSL_add_dependencies( OPENSSL_CRYPTO_LIBRARIES "${OPENSSL_CRYPTO_LIBRARY}" )
endif()
)