conan
conan copied to clipboard
[bug] check_c_source_compiles for openssl is not working with CMakeToolChain and Visual Studio generator
Environment Details (include every applicable attribute)
- Operating System+version: Windows 11
- Compiler+version: Visual Studio 2019
- Conan version: 1.51.3
- Python version: 3.10.3
Steps to reproduce (Include if Applicable)
- in the conanfile:
- use CMakeToolChain to build the package
- require openssl
self.requires("openssl/1.1.1q")
- in the cmakefile of the project:
- link with openssl like
LINK_LIBRARIES(OpenSSL::SSL OpenSSL::Crypto) - use check_c_source_compiles like
- link with openssl like
CHECK_C_SOURCE_COMPILES("#include <openssl/opensslv.h>
#ifndef OPENSSL_VERSION_NUMBER
#error No OPENSSL_VERSION_NUMBER defined
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#error This is not OpenSSL 1.1 or higher
#endif
int main(void) { return 0; }" PODOFO_HAVE_OPENSSL_1_1)
=> you get the following error:
C:/J/w/prod/BuildSingleReference/.conan/data/podofo/0.9.7/_/_/build/f8220457d46bfa1f3246ae8e28788767027bcd82/build/CMakeFiles/CMakeTmp/CMakeLists.txt:20 (add_executable):
Target "cmTC_491e9" links to target
"CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASE" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
Note: the error does not appear if you use another generator like Ninja.
This error was found when working on this pull request: https://github.com/conan-io/conan-center-index/pull/12615
Quick question: if not using check_c_source_compiles(), but just building a normal library or executable that target_link_libraries() the openssl targets, does it work?
Quick question: if not using
check_c_source_compiles(), but just building a normal library or executable thattarget_link_libraries()the openssl targets, does it work?
Yes
From what I see in https://cmake.org/cmake/help/latest/module/CheckCSourceCompiles.html, check_c_source_compiles() executes as try_compile(), which is not the same context as the main project, and it requires to pass CMAKE_REQUIRED_INCLUDES, CMAKE_REQUIRED_LIBRARIES etc, but not the targets, so it could be related. No idea why it would work with some generators like Ninja and not the others. Ninja with the VS compiler (cl.exe) works fine? I assume that the above failure is with standard CMake "Visual Studio" generator?
The failure is only with the standard CMake "Visual Studio" generator, running manually the cmake project configured by conan with -G "Ninja" fix the issue.
related issue: https://github.com/conan-io/conan/issues/12180
More or less all CMake macros in https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html#utility-modules like check_c_source_compiles, check_cxx_source_compiles, check_symbols_exists, check_cxx_symbols_exists, check_function_exists, check_include_file etc are broken with <name>_LIBRARIES variables created by CMakeDeps.
I've experienced the same in the following context:
- I've tried to make the recipe of libssh2 conan-2 compatible, it depends on OpenSSL
- There is a
check_function_existscall in the CMake code of libssh2, where we command cmake to link toopenssl::openssl. openssl::openssldepends onOpenSSL::SSL,OpenSSL::SSLdepends on "micro target"CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASEin turn- The targets
openssl::openssl,OpenSSL::SSLareINTERFACE IMPORTED - The target
CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASEisUNKNOWN IMPORTED - The
check_function_existscallstry_compile, what supportsINTERFACE IMPORTEDtargets to link against, but it does not suportUNKNOWN IMPORTEDtargets. (cmake command line option--debug-trycompileis useful here)
The CONAN_LIB:XXX micro targets are defined in the function conan_package_library_targets in the generated file cmakedeps_macros.cmake somewhat like this:
function(conan_package_library_targets libraries package_libdir deps_target out_libraries_target config_suffix package_name)
set(_out_libraries_target "")
foreach(_LIBRARY_NAME ${libraries})
find_library(CONAN_FOUND_LIBRARY NAMES ${_LIBRARY_NAME} PATHS ${package_libdir}
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
if(CONAN_FOUND_LIBRARY)
message(VERBOSE "Conan: Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")
# Create a micro-target for each lib/a found
# Allow only some characters for the target name
string(REGEX REPLACE "[^A-Za-z0-9.+_-]" "_" _LIBRARY_NAME ${_LIBRARY_NAME})
set(_LIB_NAME CONAN_LIB::${package_name}_${_LIBRARY_NAME}${config_suffix})
if(NOT TARGET ${_LIB_NAME})
# Create a micro-target for each lib/a found
add_library(${_LIB_NAME} UNKNOWN IMPORTED)
endif()
# .....
endfunction()
If I change the library type to INTERFACE IMPORTED like this:
add_library(${_LIB_NAME} INTERFACE IMPORTED)
then try_compile properly "memoizes" this micro target, as well as OpenSSL::SSL, OpenSSL::Crypto and openssl::openssl, and it succeeds, so check_function_exists succeeds as well.
try_compile creates a temporary CMake project (again, --debug-trycompile helps), what contains a cmTC-<XXX>Targets.cmake file. In this file cmake memoizes all INTERFACE IMPORTED dependencies from the calling context, transitively.
Is it possible to define these micro-targets as INTERFACE IMPORTED libraries or it wrecks something else?
I see this being pushed along the 1.x track of releases, but I wanted to report that this is happening with 2.0.14 as well. It's basically blocking us from being able to use OpenSSL as a dependency via conan unfortunately, which also blocks a number of other libraries (such as libcurl):
CMake Error at C:/<>/build/CMakeFiles/CMakeScratch/TryCompile-ncuco8/cmTC_33fd1Targets.cmake:42 (set_target_properties):
The link interface of target "OpenSSL::SSL" contains:
CONAN_LIB::openssl_OpenSSL_SSL_libssld_DEBUG
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
Call Stack (most recent call first):
C:/<>/build/CMakeFiles/CMakeScratch/TryCompile-ncuco8/CMakeLists.txt:18 (include)
Should also mention: I ran into this issue while working on a Git recipe, due to this I am unable to use the provided CMake file.