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_exists
call in the CMake code of libssh2, where we command cmake to link toopenssl::openssl
. -
openssl::openssl
depends onOpenSSL::SSL
,OpenSSL::SSL
depends on "micro target"CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASE
in turn - The targets
openssl::openssl
,OpenSSL::SSL
areINTERFACE IMPORTED
- The target
CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASE
isUNKNOWN IMPORTED
- The
check_function_exists
callstry_compile
, what supportsINTERFACE IMPORTED
targets to link against, but it does not suportUNKNOWN IMPORTED
targets. (cmake command line option--debug-trycompile
is 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.