Open Knitschi opened 5 days ago
Hi @Knitschi
This is a known limitation of the current CMakeDeps
generator.
creates amongst others the import-target CONAN_LIB::qt_Qt6Cored_DEBUG of type SHARED_LIBRARY from which I can read the location of the Qt6Core.dll.
Please note that this is an internal implementation detail, that shouldn't be used as it can break in future releases.
The recommended way by CMake to deploy shared library dependencies would be via the install(RUNTIME_DEPENDENCY_SET
, which conan allows by providing the CONAN_RUNTIME_LIB_DIRS variable see https://docs.conan.io/2/reference/tools/cmake/cmaketoolchain.html#conan-runtime-lib-dirs
A different story is that plugins are really not linked libraries. They might not exist at all in CMake, because they might not be part of the build at all, just a pure runtime thing.
What happens if there are components that are only .dll
and the consumer tries to link them? It will most likely fail the build as it will not find the import library. Conan components are designed to be at "build-time", so not sure this will not be a problematic approach.
We are trying to improve this in the new CMakeDeps
generator, the one that is activated with -c tools.cmake.cmakedeps:new=will_break_next
(only dev-testing). This generator do not create CONAN_LIB or any artificial targets, it creates the targets, with the correct SHARED/STATIC/INTERFACE time, doing the detection of the location if necessary (not explicitly defined in recipes, because recipes also learned the self.cpp_info.location
and self.cpp_info.link_location
and self.cpp_info.type
info).
Following the CPS new specification, that we are also trying to contribute (see our CppCon23 and CppCon24 talks about it), this would require a new component type "MODULE" iirc, that would be able to model this. But this will still require some time to stabilize, the best to move it forward is to try it and give feedback. The current CMakeDeps
generator will not be modified, the risk of breaking existing users is too high.
First off all thank you for your fast and detailed answer. I am glad to hear that you guys are working on a solution for plugins. Thank you for that as well.
I will check out your work when it is ready. Until then I will probably use my workaround that accesses the implementation targets.
Describe the bug
OS: Windows conan: 2.9.1
I am trying to consume the qt package with a project that uses the CMakeToolchain and CMakeDeps generators. I observer that
find_package(Qt6 ... )
creates amongst others the import-targetCONAN_LIB::qt_Qt6Cored_DEBUG
of typeSHARED_LIBRARY
from which I can read the location of theQt6Core.dll
. BTW I need the location to deploy the dll to the build directory so I do not have to rely on PATH.The problem is that the
SHARED_LIBRARY
target is not created for the Qt plugins likeQt6::QWindowsIntegrationPlugin
. So the only way to findqwindows.dll
would be to look in the path for it and guess its name. Our existing dll deployment code however takes import targets and then reads theIMPORTED_LOCATION_<config>
property to get the .dll location.After digging into the qt recipe and into
cmakedeps_macros.cmake
, it looks like there is no whay forcmakedeps_macros.cmake
to create shared library import targets for libraries that have no.lib
file. The functionconan_package_library_targets()
always looks for the.lib
first and only when that is found it will look for the.dll
. This fails if a library has no.lib
which is the case for plugins.My research also revealed that cmake 3.17 changed the default behavior of
find_library()
to no longer consider.dll
files. Now users have to manuall activate.dll
finding by addingset(CMAKE_FIND_LIBRARY_SUFFIXES .dll ${CMAKE_FIND_LIBRARY_SUFFIXES})
to their code.With this we can change the recipe to fabricate a workaround:
With this the
test_package
gets an import target with the nameCONAN_LIB::qt_Qt6_QWindowsIntegrationPlugin_qwindowsd_DEBUG
from which one could read the qwindows.dll location.How to reproduce it
Can be reproduced with the qt package.
Add the following lines to
test_package\CMakeLists.txt
The output will contain
SHARED_LIBRARY
targets forQt6::Core
and other normal libraries but not for the plugin targets likeQt6::QWindowsIntegrationPlugin
and others.