Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.2.4
-
82601c120 (dev)
Description
For full description, please see the forum post at:
https://discourse.cmake.org/t/strange-problem-when-using-qt-add-qml-module-in-module-being-brought-in-via-fetchcontent/6781
Slightly shorter version:
In Qt 6 when using CMake build system, QML modules use qt_add_qml_module(). In following situation:
project(BCControls) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Svg Qml LinguistTools REQUIRED) set(QML_FILES BCInfoScreen.qml # omitting many files here ) set(RESOURCE_FILES # omitting ) qt_add_library(BCControls STATIC) file(GLOB TS_FILES translations/*.ts) qt_add_translations(BCControls TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE qmfiles ) qt_add_qml_module(BCControls URI "BCControls" VERSION 1.0 QML_FILES ${QML_FILES} RESOURCES ${RESOURCE_FILES} ) qt_add_resources(BCControls "BCControlsTranslations" PREFIX "/translations" FILES ${qmfiles}) # Images in SVG format exist in bccontrols.qrc. Need to # load Qt${QT_VERSION_MAJOR}::Svg shared library at runtime. target_link_libraries(BCControls PRIVATE Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Qml )
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Qml REQUIRED)
set(RESOURCE_FILES
# omitting
)
set(QML_FILES
# omitting many files here
)
set(CPP_FILES
# omitting
)
qt_add_executable(BatchExecutor ${CPP_FILES})
qt_add_qml_module(BatchExecutor
VERSION 1.0
URI "BatchExecutor"
QML_FILES ${QML_FILES}
RESOURCES ${RESOURCE_FILES}
)
FetchContent_Declare(BCControls SOURCE_DIR ${BCControls_LOC})
FetchContent_MakeAvailable(BCControls)
target_include_directories(BatchExecutor PRIVATE .)
target_link_libraries(BatchExecutor
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Qml
BCControls
)
In the case above following CMake configuration warning is output:
CMake Warning at C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:698 (message): The BCControls target is a QML module with target path BCControls. It uses an OUTPUT_DIRECTORY of C:/Projects/build-AEPP-Desktop_Qt_6_2_4_MSVC2019_32bit-Release/_deps/bccontrols-build, which should end in the same target path, but doesn't. Tooling such as qmllint may not work correctly. Call Stack (most recent call first): C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:1458 (_qt_internal_target_enable_qmllint) C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:564 (qt6_target_qml_sources) C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:615 (qt6_add_qml_module) eSW/Qt/QtCommon/BCControls/CMakeLists.txt:282 (qt_add_qml_module)
In addition, the application that is Fetching dependencies with this warning exhibits a CMake configuration error. In this example BatchExecutor, the executable wanting to link against BCControls, is complaining about a non-existent Qt6::Svg, but BatchExecutor is not itself dependent on that component.
BatchExecutor error:
CMake Error at C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Core/Qt6CoreMacros.cmake:592 (get_target_property): get_target_property() called with non-existent target "Qt6::Svg". Call Stack (most recent call first): C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Core/Qt6CoreMacros.cmake:681 (_qt_internal_finalize_executable) C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Core/Qt6CoreMacros.cmake:661:EVAL:1 (qt6_finalize_target) eSW/Qt/Apps/BatchExecutor/CMakeLists.txt:DEFERRED This error goes away if I add Qt6::Svg on the list of REQUIRED COMPONENTS in the find_package() call.
According to Alexandru's answer in the forum this happens:
...because the qml cmake api expects BCControls to be placed in a nested BCControls/CMakeLists.txt folder, so that the build folder where the .dll file is placed looks like
/_deps/bccontrols-build/BCControls/BCControls.dll.
This is due to some specifics how the QML engine expects dlls to be placed, so that they can be loaded at runtime (as well as for tooling like qmllint).Regarding the error.
BCControls is a static library, that links to Svg, as can be seen in target_link_libraries.
BatchExecutor then links against that static library.
Qt has some code in the executable finalizer that walks over all transitive dependencies of the executable to detect if it needs to do certain things.
It naturally encounters BatchExecutor → Svg and tries to get a property from the Svg target, but the target is not globally visible (because the find_package is done in a nested subdirectory, not where the executable is added, and the Svg target is local to that subdirectory scope) and that leads to an error.
The workaround is indeed to move the find_package(Svg) to the root CMakeLists.txtI do think it’s a bug in Qt, which should guard against a non-visible Svg target and probably show a warning....
Attachments
Issue Links
- is duplicated by
-
QTBUG-113626 Using qt_add_library and qt_add_executable causes failure to link Qt6::QuickControls2 (and probably other imported targets)
-
- Closed
-
For Gerrit Dashboard: QTBUG-108286 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
448050,2 | CMake: Handle non-existent targets when collecting dependencies | dev | qt/qtbase | Status: MERGED | +2 | 0 |